MATIC Price: $0.750113 (+9.68%)
Gas: 49 GWei
 

Overview

Max Total Supply

1,075,708.53700000000426 PORT3

Holders

185

Total Transfers

-

Market

Price

$0.00 @ 0.000000 MATIC

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information

Contract Source Code Verified (Exact Match)

Contract Name:
CATERC20

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 10000 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at polygonscan.com on 2023-11-28
*/

// File: contracts/contracts/cat/ERC20/Structs.sol

// contracts/Structs.sol

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;


contract CATERC20Structs {
    struct CrossChainPayload {
        // Amount being transferred (big-endian uint256)
        uint256 amount;
        // Address of the token. Left-zero-padded if shorter than 32 bytes
        bytes32 tokenAddress;
        // Chain ID of the token
        uint16 tokenChain;
        // Address of the recipient. Left-zero-padded if shorter than 32 bytes
        bytes32 toAddress;
        // Chain ID of the recipient
        uint16 toChain;
        // Token Decimals of sender chain
        uint8 tokenDecimals;
    }

    struct SignatureVerification {
        // Address of custodian the user has delegated to sign transaction on behalf of
        address custodian;
        // Timestamp the transaction will be valid till
        uint256 validTill;
        // Signed Signature
        bytes signature;
    }
}

// File: contracts/contracts/cat/ERC20/State.sol

// contracts/State.sol




contract CATERC20Events {
    event bridgeInEvent(
        uint256 tokenAmount,
        uint256 fromChain,
        uint256 toChain,
        bytes32 indexed toAddress
    );

    event bridgeOutEvent(
        uint256 tokenAmount,
        uint256 fromChain,
        uint256 toChain,
        bytes32 indexed fromAddress,
        bytes32 indexed toAddress
    );
}

contract CATERC20Storage {
    struct Provider {
        uint16 chainId;
        // Required number of block confirmations to assume finality
        uint8 finality;
    }

    struct State {
        Provider provider;
        address payable wormhole;
        // Mapping of consumed token transfers
        mapping(bytes32 => bool) completedTransfers;
        // Mapping of token contracts on other chains
        mapping(uint16 => bytes32) tokenImplementations;
        // EIP-155 Chain ID
        uint256 evmChainId;
        address nativeAsset;
        bool isInitialized;
        uint8 decimals;
        uint256 maxSupply;
        uint256 mintedSupply;
        // Mapping for storing used signatures
        mapping(bytes => bool) signaturesUsed;
    }
}

contract CATERC20State {
    CATERC20Storage.State _state;
}

// File: contracts/contracts/cat/ERC20/Setters.sol

// contracts/Setters.sol





contract CATERC20Setters is CATERC20State {
    function setTransferCompleted(bytes32 hash) internal {
        _state.completedTransfers[hash] = true;
    }

    function setTokenImplementation(uint16 chainId, bytes32 tokenContract) internal {
        _state.tokenImplementations[chainId] = tokenContract;
    }

    function setWormhole(address wh) internal {
        _state.wormhole = payable(wh);
    }

    function setFinality(uint8 finality) internal {
        _state.provider.finality = finality;
    }

    function setChainId(uint16 chainId) internal {
        _state.provider.chainId = chainId;
    }

    function setEvmChainId(uint256 evmChainId) internal {
        require(evmChainId == block.chainid, "invalid evmChainId");
        _state.evmChainId = evmChainId;
    }

    function setDecimals(uint8 decimals) internal {
        _state.decimals = decimals;
    }

    function setMaxSupply(uint256 maxSupply) internal {
        _state.maxSupply = maxSupply;
    }

    function setMintedSupply(uint256 mintedSupply) internal {
        _state.mintedSupply = mintedSupply;
    }

    function setNativeAsset(address nativeAsset) internal {
        _state.nativeAsset = nativeAsset;
    }

    function setIsInitialized() internal {
        _state.isInitialized = true;
    }

    function setSignatureUsed(bytes memory signature) internal {
        _state.signaturesUsed[signature] = true;
    }
}

// File: contracts/contracts/libraries/external/BytesLib.sol


/*
 * @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,
        uint256 _start,
        uint256 _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, uint256 _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, uint256 _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, uint256 _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, uint256 _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, uint256 _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, uint256 _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, uint256 _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, uint256 _start) internal pure returns (uint256) {
        require(_bytes.length >= _start + 32, "toUint256_outOfBounds");
        uint256 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x20), _start))
        }

        return tempUint;
    }

    function toBytes32(bytes memory _bytes, uint256 _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;
    }
}

// File: contracts/contracts/cat/interfaces/ICATERC20.sol




interface ICATERC20 {
    function initialize(
        uint16 chainId,
        address wormhole,
        uint8 finality,
        uint256 maxSupply
    ) external;

    /**
     * @dev To bridge tokens to other chains.
     */
    function bridgeOut(
        uint256 amount,
        uint16 recipientChain,
        bytes32 recipient,
        uint32 nonce
    ) external payable returns (uint64 sequence);

    function bridgeIn(bytes memory encodedVm) external returns (bytes memory);

    function mint(address recipient, uint256 amount) external;
}

// File: contracts/contracts/interfaces/IWormhole.sol

// contracts/Messages.sol




interface IWormhole {
    struct GuardianSet {
        address[] keys;
        uint32 expirationTime;
    }

    struct Signature {
        bytes32 r;
        bytes32 s;
        uint8 v;
        uint8 guardianIndex;
    }

    struct VM {
        uint8 version;
        uint32 timestamp;
        uint32 nonce;
        uint16 emitterChainId;
        bytes32 emitterAddress;
        uint64 sequence;
        uint8 consistencyLevel;
        bytes payload;

        uint32 guardianSetIndex;
        Signature[] signatures;

        bytes32 hash;
    }

    struct TransferFees {
        bytes32 module;
        uint8 action;
        uint16 chain;

        uint256 amount;
        bytes32 recipient;
    }

    event LogMessagePublished(address indexed sender, uint64 sequence, uint32 nonce, bytes payload, uint8 consistencyLevel);
    function publishMessage(
        uint32 nonce,
        bytes memory payload,
        uint8 consistencyLevel
    ) external payable returns (uint64 sequence);

    function parseAndVerifyVM(bytes calldata encodedVM) external view returns (VM memory vm, bool valid, string memory reason);

    function verifyVM(VM memory vm) external view returns (bool valid, string memory reason);

    function verifySignatures(bytes32 hash, Signature[] memory signatures, GuardianSet memory guardianSet) external pure returns (bool valid, string memory reason);

    function parseVM(bytes memory encodedVM) external pure returns (VM memory vm);

    function isInitialized(address impl) external view returns (bool);

    function chainId() external view returns (uint16);

    function governanceChainId() external view returns (uint16);

    function governanceContract() external view returns (bytes32);

    function messageFee() external view returns (uint256);

    function evmChainId() external view returns (uint256);

}

// File: contracts/contracts/cat/shared/WormholeStructs.sol

// contracts/shared/WormholeStructs.sol




interface WormholeStructs {
    struct Provider {
        uint16 chainId;
        uint16 governanceChainId;
        bytes32 governanceContract;
    }

    struct GuardianSet {
        address[] keys;
        uint32 expirationTime;
    }

    struct Signature {
        bytes32 r;
        bytes32 s;
        uint8 v;
        uint8 guardianIndex;
    }

    struct VM {
        uint8 version;
        uint32 timestamp;
        uint32 nonce;
        uint16 emitterChainId;
        bytes32 emitterAddress;
        uint64 sequence;
        uint8 consistencyLevel;
        bytes payload;
        uint32 guardianSetIndex;
        Signature[] signatures;
        bytes32 hash;
    }
}

// File: @openzeppelin/contracts/utils/introspection/IERC165.sol


// 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);
}

// File: @openzeppelin/contracts/utils/introspection/ERC165.sol


// 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;
    }
}

// File: @openzeppelin/contracts/utils/Context.sol


// 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;
    }
}

// File: @openzeppelin/contracts/access/Ownable.sol


// OpenZeppelin Contracts (last updated v4.7.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 anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public 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);
    }
}

// File: @openzeppelin/contracts/utils/Address.sol


// OpenZeppelin Contracts (last updated v4.8.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
     * ====
     *
     * [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://diligence.consensys.net/posts/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.5.11/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);
        }
    }
}

// File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Permit.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/draft-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);
}

// File: @openzeppelin/contracts/token/ERC20/extensions/draft-IERC20Permit.sol


// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC20/extensions/draft-IERC20Permit.sol)



// EIP-2612 is Final as of 2022-11-01. This file is deprecated.


// File: @openzeppelin/contracts/token/ERC20/IERC20.sol


// OpenZeppelin Contracts (last updated v4.6.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);
}

// File: contracts/contracts/cat/interfaces/IERC20Extended.sol





interface IERC20Extended is IERC20 {
    function decimals() external view returns (uint8);
}

// File: contracts/contracts/cat/ERC20/Getters.sol

// contracts/Getters.sol








contract CATERC20Getters is CATERC20State {
    using BytesLib for bytes;

    function isTransferCompleted(bytes32 hash) public view returns (bool) {
        return _state.completedTransfers[hash];
    }

    function wormhole() public view returns (IWormhole) {
        return IWormhole(_state.wormhole);
    }

    function chainId() public view returns (uint16) {
        return _state.provider.chainId;
    }

    function evmChainId() public view returns (uint256) {
        return _state.evmChainId;
    }

    function tokenContracts(uint16 chainId_) public view returns (bytes32) {
        return _state.tokenImplementations[chainId_];
    }

    function finality() public view returns (uint8) {
        return _state.provider.finality;
    }

    function getDecimals() public view returns (uint8) {
        return _state.decimals;
    }

    function maxSupply() public view returns (uint256) {
        return _state.maxSupply;
    }

    function mintedSupply() public view returns (uint256) {
        return _state.mintedSupply;
    }

    function nativeAsset() public view returns (IERC20Extended) {
        return IERC20Extended(_state.nativeAsset);
    }

    function isInitialized() public view returns (bool) {
        return _state.isInitialized;
    }

    function isSignatureUsed(bytes memory signature) public view returns (bool) {
        return _state.signaturesUsed[signature];
    }

    function normalizeAmount(
        uint256 amount,
        uint8 foreignDecimals,
        uint8 localDecimals
    ) internal pure returns (uint256) {
        if (foreignDecimals > localDecimals) {
            amount /= 10 ** (foreignDecimals - localDecimals);
        }
        if (localDecimals > foreignDecimals) {
            amount *= 10 ** (localDecimals - foreignDecimals);
        }
        return amount;
    }

    /*
     * @dev Truncate a 32 byte array to a 20 byte address.
     *      Reverts if the array contains non-0 bytes in the first 12 bytes.
     *
     * @param bytes32 bytes The 32 byte array to be converted.
     */
    function bytesToAddress(bytes32 b) public pure returns (address) {
        require(bytes12(b) == 0, "invalid EVM address");
        return address(uint160(uint256(b)));
    }

    function addressToBytes(address a) public pure returns (bytes32) {
        return bytes32(uint256(uint160(a)));
    }

    function encodeTransfer(
        CATERC20Structs.CrossChainPayload memory transfer
    ) public pure returns (bytes memory encoded) {
        encoded = abi.encodePacked(
            transfer.amount,
            transfer.tokenAddress,
            transfer.tokenChain,
            transfer.toAddress,
            transfer.toChain,
            transfer.tokenDecimals
        );
    }

    function decodeTransfer(
        bytes memory encoded
    ) public pure returns (CATERC20Structs.CrossChainPayload memory transfer) {
        uint index = 0;

        transfer.amount = encoded.toUint256(index);
        index += 32;

        transfer.tokenAddress = encoded.toBytes32(index);
        index += 32;

        transfer.tokenChain = encoded.toUint16(index);
        index += 2;

        transfer.toAddress = encoded.toBytes32(index);
        index += 32;

        transfer.toChain = encoded.toUint16(index);
        index += 2;

        transfer.tokenDecimals = encoded.toUint8(index);
        index += 1;

        require(encoded.length == index, "invalid Transfer");
    }
}

// File: contracts/contracts/cat/ERC20/Governance.sol

// contracts/Bridge.sol










contract CATERC20Governance is CATERC20Getters, CATERC20Setters, Ownable {
    /// builds a prefixed hash to mimic the behavior of eth_sign.
    function prefixed(bytes32 _hash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", _hash));
    }

    /// signature methods.
    function splitSignature(
        bytes memory sig
    ) internal pure returns (uint8 v, bytes32 r, bytes32 s) {
        require(sig.length == 65);

        assembly {
            // first 32 bytes, after the length prefix.
            r := mload(add(sig, 32))
            // second 32 bytes.
            s := mload(add(sig, 64))
            // final byte (first byte of the next 32 bytes).
            v := byte(0, mload(add(sig, 96)))
        }

        return (v, r, s);
    }

    function verifySignature(
        bytes32 message,
        bytes memory signature,
        address authority
    ) internal pure returns (bool) {
        (uint8 v, bytes32 r, bytes32 s) = splitSignature(signature);
        address recovered = ecrecover(message, v, r, s);
        if (recovered == authority) {
            return true;
        } else {
            return false;
        }
    }

    /// @dev verify owner is caller or the caller has valid owner signature
    modifier onlyOwnerOrOwnerSignature(
        CATERC20Structs.SignatureVerification memory signatureArguments
    ) {
        if (_msgSender() == owner()) {
            _;
        } else {
            bytes32 encodedHashData = prefixed(
                keccak256(
                    abi.encodePacked(signatureArguments.custodian, signatureArguments.validTill)
                )
            );
            require(signatureArguments.custodian == _msgSender(), "custodian can call only");
            require(signatureArguments.validTill > block.timestamp, "signed transaction expired");
            require(
                isSignatureUsed(signatureArguments.signature) == false,
                "cannot re-use signatures"
            );
            setSignatureUsed(signatureArguments.signature);
            require(
                verifySignature(encodedHashData, signatureArguments.signature, owner()),
                "unauthorized signature"
            );
            _;
        }
    }

    // Execute a RegisterChain governance message
    function registerChain(
        uint16 chainId,
        bytes32 tokenContract,
        CATERC20Structs.SignatureVerification memory signatureArguments
    ) public onlyOwnerOrOwnerSignature(signatureArguments) {
        setTokenImplementation(chainId, tokenContract);
    }

    function registerChains(
        uint16[] memory chainId,
        bytes32[] memory tokenContract,
        CATERC20Structs.SignatureVerification memory signatureArguments
    ) public onlyOwnerOrOwnerSignature(signatureArguments) {
        require(chainId.length == tokenContract.length, "Invalid Input");
        for (uint256 i = 0; i < tokenContract.length; i++) {
            setTokenImplementation(chainId[i], tokenContract[i]);
        }
    }

    // Execute a RegisterChain governance message
    function updateFinality(
        uint8 finality,
        CATERC20Structs.SignatureVerification memory signatureArguments
    ) public onlyOwnerOrOwnerSignature(signatureArguments) {
        setFinality(finality);
    }
}

// File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)




/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

    /**
     * @dev Returns the symbol of the token.
     */
    function symbol() external view returns (string memory);

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

// File: @openzeppelin/contracts/token/ERC20/ERC20.sol


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC20/ERC20.sol)






/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

    /**
     * @dev See {IERC20-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address to, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, amount);
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, allowance(owner, spender) + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        address owner = _msgSender();
        uint256 currentAllowance = allowance(owner, spender);
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `from` to `to`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
            // Overflow not possible: the sum of all balances is capped by totalSupply, and the sum is preserved by
            // decrementing then incrementing.
            _balances[to] += amount;
        }

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        unchecked {
            // Overflow not possible: balance + amount is at most totalSupply + amount, which is checked above.
            _balances[account] += amount;
        }
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
            // Overflow not possible: amount <= accountBalance <= totalSupply.
            _totalSupply -= amount;
        }

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Updates `owner` s allowance for `spender` based on spent `amount`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}

// File: @openzeppelin/contracts/token/ERC20/utils/SafeERC20.sol


// OpenZeppelin Contracts (last updated v4.8.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;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(token, abi.encodeWithSelector(token.transfer.selector, to, value));
    }

    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));
    }

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
    }

    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");
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(token, abi.encodeWithSelector(token.approve.selector, spender, newAllowance));
        }
    }

    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");
        if (returndata.length > 0) {
            // Return data is optional
            require(abi.decode(returndata, (bool)), "SafeERC20: ERC20 operation did not succeed");
        }
    }
}

// File: contracts/contracts/cat/ERC20/CATERC20.sol













contract CATERC20 is Context, ERC20, CATERC20Governance, CATERC20Events, ERC165 {
	using SafeERC20 for IERC20;
	
	constructor(string memory name, string memory symbol, uint8 decimal) ERC20(name, symbol) {
		setEvmChainId(block.chainid);
		setDecimals(decimal);
	}
	
	function initialize(
		uint16 chainId,
		address wormhole,
		uint8 finality,
		uint256 maxSupply
	) public onlyOwner {
		require(isInitialized() == false, "Already Initialized");
		
		setChainId(chainId);
		setWormhole(wormhole);
		setFinality(finality);
		setMaxSupply(maxSupply);
		setMintedSupply(0);
		setIsInitialized();
	}
	
	function decimals() public view virtual override returns (uint8) {
		return getDecimals();
	}
	
	function supportsInterface(
		bytes4 interfaceId
	) public view virtual override(ERC165) returns (bool) {
		return interfaceId == type(ICATERC20).interfaceId || super.supportsInterface(interfaceId);
	}
	
	/**
	 * @dev To bridge tokens to other chains.
     */
	function bridgeOut(
		uint256 amount,
		uint16 recipientChain,
		bytes32 recipient,
		uint32 nonce
	) external payable returns (uint64 sequence) {
		require(isInitialized() == true, "Not Initialized");
		require(evmChainId() == block.chainid, "unsupported fork");
		
		uint256 fee = wormhole().messageFee();
		require(msg.value >= fee, "Not enough fee provided to publish message");
		uint16 tokenChain = wormhole().chainId();
		bytes32 tokenAddress = bytes32(uint256(uint160(address(this))));
		
		_burn(_msgSender(), amount);
		
		CATERC20Structs.CrossChainPayload memory transfer = CATERC20Structs.CrossChainPayload({
			amount: amount,
			tokenAddress: tokenAddress,
			tokenChain: tokenChain,
			toAddress: recipient,
			toChain: recipientChain,
			tokenDecimals: getDecimals()
		});
		
		sequence = wormhole().publishMessage{value: msg.value}(
			nonce,
			encodeTransfer(transfer),
			finality()
		);
		
		emit bridgeOutEvent(
			amount,
			tokenChain,
			recipientChain,
			addressToBytes(_msgSender()),
			recipient
		);
	} // end of function
	
	function bridgeIn(bytes memory encodedVm) external returns (bytes memory) {
		require(isInitialized() == true, "Not Initialized");
		require(evmChainId() == block.chainid, "unsupported fork");
		
		(IWormhole.VM memory vm, bool valid, string memory reason) = wormhole().parseAndVerifyVM(
			encodedVm
		);
		require(valid, reason);
		require(
			bytesToAddress(vm.emitterAddress) == address(this) ||
			tokenContracts(vm.emitterChainId) == vm.emitterAddress,
			"Invalid Emitter"
		);
		
		CATERC20Structs.CrossChainPayload memory transfer = decodeTransfer(vm.payload);
		address transferRecipient = bytesToAddress(transfer.toAddress);
		
		require(!isTransferCompleted(vm.hash), "transfer already completed");
		setTransferCompleted(vm.hash);
		
		require(transfer.toChain == wormhole().chainId(), "invalid target chain");
		
		uint256 nativeAmount = normalizeAmount(
			transfer.amount,
			transfer.tokenDecimals,
			getDecimals()
		);
		
		_mint(transferRecipient, nativeAmount);
		
		emit bridgeInEvent(nativeAmount, transfer.tokenChain, transfer.toChain, transfer.toAddress);
		
		return vm.payload;
	}
	
	function mint(address recipient, uint256 amount) public onlyOwner {
		require(mintedSupply() + amount <= maxSupply(), "MAX SUPPLY REACHED");
		setMintedSupply(mintedSupply() + amount);
		_mint(recipient, amount);
	}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"uint8","name":"decimal","type":"uint8"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","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":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fromChain","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toChain","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"toAddress","type":"bytes32"}],"name":"bridgeInEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenAmount","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"fromChain","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toChain","type":"uint256"},{"indexed":true,"internalType":"bytes32","name":"fromAddress","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"toAddress","type":"bytes32"}],"name":"bridgeOutEvent","type":"event"},{"inputs":[{"internalType":"address","name":"a","type":"address"}],"name":"addressToBytes","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"encodedVm","type":"bytes"}],"name":"bridgeIn","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"uint16","name":"recipientChain","type":"uint16"},{"internalType":"bytes32","name":"recipient","type":"bytes32"},{"internalType":"uint32","name":"nonce","type":"uint32"}],"name":"bridgeOut","outputs":[{"internalType":"uint64","name":"sequence","type":"uint64"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"b","type":"bytes32"}],"name":"bytesToAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"chainId","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"encoded","type":"bytes"}],"name":"decodeTransfer","outputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"tokenAddress","type":"bytes32"},{"internalType":"uint16","name":"tokenChain","type":"uint16"},{"internalType":"bytes32","name":"toAddress","type":"bytes32"},{"internalType":"uint16","name":"toChain","type":"uint16"},{"internalType":"uint8","name":"tokenDecimals","type":"uint8"}],"internalType":"struct CATERC20Structs.CrossChainPayload","name":"transfer","type":"tuple"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes32","name":"tokenAddress","type":"bytes32"},{"internalType":"uint16","name":"tokenChain","type":"uint16"},{"internalType":"bytes32","name":"toAddress","type":"bytes32"},{"internalType":"uint16","name":"toChain","type":"uint16"},{"internalType":"uint8","name":"tokenDecimals","type":"uint8"}],"internalType":"struct CATERC20Structs.CrossChainPayload","name":"transfer","type":"tuple"}],"name":"encodeTransfer","outputs":[{"internalType":"bytes","name":"encoded","type":"bytes"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"evmChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"finality","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDecimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"chainId","type":"uint16"},{"internalType":"address","name":"wormhole","type":"address"},{"internalType":"uint8","name":"finality","type":"uint8"},{"internalType":"uint256","name":"maxSupply","type":"uint256"}],"name":"initialize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"isInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"isSignatureUsed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"hash","type":"bytes32"}],"name":"isTransferCompleted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"mintedSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nativeAsset","outputs":[{"internalType":"contract IERC20Extended","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"chainId","type":"uint16"},{"internalType":"bytes32","name":"tokenContract","type":"bytes32"},{"components":[{"internalType":"address","name":"custodian","type":"address"},{"internalType":"uint256","name":"validTill","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct CATERC20Structs.SignatureVerification","name":"signatureArguments","type":"tuple"}],"name":"registerChain","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16[]","name":"chainId","type":"uint16[]"},{"internalType":"bytes32[]","name":"tokenContract","type":"bytes32[]"},{"components":[{"internalType":"address","name":"custodian","type":"address"},{"internalType":"uint256","name":"validTill","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct CATERC20Structs.SignatureVerification","name":"signatureArguments","type":"tuple"}],"name":"registerChains","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"chainId_","type":"uint16"}],"name":"tokenContracts","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"finality","type":"uint8"},{"components":[{"internalType":"address","name":"custodian","type":"address"},{"internalType":"uint256","name":"validTill","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"internalType":"struct CATERC20Structs.SignatureVerification","name":"signatureArguments","type":"tuple"}],"name":"updateFinality","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wormhole","outputs":[{"internalType":"contract IWormhole","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

60806040523480156200001157600080fd5b5060405162003b7338038062003b738339810160408190526200003491620002c3565b8251839083906200004d90600c90602085019062000150565b5080516200006390600d90602084019062000150565b505050620000806200007a620000ac60201b60201c565b620000b0565b6200008b4662000102565b6005805460ff60a81b1916600160a81b60ff84160217905550505062000385565b3390565b600e80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b4681146200014b5760405162461bcd60e51b81526020600482015260126024820152711a5b9d985b1a5908195d9b50da185a5b925960721b604482015260640160405180910390fd5b600455565b8280546200015e9062000348565b90600052602060002090601f016020900481019282620001825760008555620001cd565b82601f106200019d57805160ff1916838001178555620001cd565b82800160010185558215620001cd579182015b82811115620001cd578251825591602001919060010190620001b0565b50620001db929150620001df565b5090565b5b80821115620001db5760008155600101620001e0565b634e487b7160e01b600052604160045260246000fd5b600082601f8301126200021e57600080fd5b81516001600160401b03808211156200023b576200023b620001f6565b604051601f8301601f19908116603f01168101908282118183101715620002665762000266620001f6565b816040528381526020925086838588010111156200028357600080fd5b600091505b83821015620002a7578582018301518183018401529082019062000288565b83821115620002b95760008385830101525b9695505050505050565b600080600060608486031215620002d957600080fd5b83516001600160401b0380821115620002f157600080fd5b620002ff878388016200020c565b945060208601519150808211156200031657600080fd5b5062000325868287016200020c565b925050604084015160ff811681146200033d57600080fd5b809150509250925092565b600181811c908216806200035d57607f821691505b602082108114156200037f57634e487b7160e01b600052602260045260246000fd5b50919050565b6137de80620003956000396000f3fe6080604052600436106102855760003560e01c80637d557a3f11610153578063c1bd8cf9116100cb578063ded8454a1161007f578063f2fde38b11610064578063f2fde38b146107c6578063f7ee9998146107e6578063ff99c39f1461081757600080fd5b8063ded8454a1461076e578063f0141d841461079557600080fd5b8063d5abeb01116100b0578063d5abeb011461069a578063dc02f456146106af578063dd62ed3e1461072857600080fd5b8063c1bd8cf914610665578063c599efdd1461067a57600080fd5b806395d89b4111610122578063a457c2d711610107578063a457c2d7146105f5578063a9059cbb14610615578063aa4efa5b1461063557600080fd5b806395d89b41146105bd5780639a8a0592146105d257600080fd5b80637d557a3f1461054157806384acd1bb14610561578063860369cc1461057f5780638da5cb5b1461059f57600080fd5b8063313ce5671161020157806364d42b17116101b5578063715018a61161019a578063715018a6146104dc578063739fc8d1146104f157806374d32ad41461050f57600080fd5b806364d42b171461049157806370a08231146104a657600080fd5b806339509351116101e657806339509351146104315780633fb7778b1461045157806340c10f191461047157600080fd5b8063313ce567146103c2578063392e53cd1461040157600080fd5b806318160ddd116102585780632af6d4a81161023d5780632af6d4a8146103605780632c5485f4146103825780632d1fdb46146103a257600080fd5b806318160ddd1461032157806323b872dd1461034057600080fd5b806301ffc9a71461028a57806306fdde03146102bf578063095ea7b3146102e15780631150f0f314610301575b600080fd5b34801561029657600080fd5b506102aa6102a5366004612a61565b610843565b60405190151581526020015b60405180910390f35b3480156102cb57600080fd5b506102d46108dc565b6040516102b69190612b19565b3480156102ed57600080fd5b506102aa6102fc366004612b48565b61096e565b34801561030d57600080fd5b506102aa61031c366004612cd9565b610986565b34801561032d57600080fd5b50600b545b6040519081526020016102b6565b34801561034c57600080fd5b506102aa61035b366004612d16565b6109b3565b34801561036c57600080fd5b5061038061037b366004612de1565b6109d9565b005b34801561038e57600080fd5b5061038061039d366004612e41565b610cca565b3480156103ae57600080fd5b506102d46103bd366004612cd9565b610ef9565b3480156103ce57600080fd5b506005547501000000000000000000000000000000000000000000900460ff165b60405160ff90911681526020016102b6565b34801561040d57600080fd5b5060055474010000000000000000000000000000000000000000900460ff166102aa565b34801561043d57600080fd5b506102aa61044c366004612b48565b61136a565b34801561045d57600080fd5b5061038061046c366004612e9a565b6113a9565b34801561047d57600080fd5b5061038061048c366004612b48565b6114dc565b34801561049d57600080fd5b50600454610332565b3480156104b257600080fd5b506103326104c1366004612ee9565b6001600160a01b031660009081526009602052604090205490565b3480156104e857600080fd5b50610380611573565b3480156104fd57600080fd5b5060005462010000900460ff166103ef565b34801561051b57600080fd5b506005546001600160a01b03165b6040516001600160a01b0390911681526020016102b6565b34801561054d57600080fd5b5061038061055c366004612f8e565b611587565b34801561056d57600080fd5b506001546001600160a01b0316610529565b34801561058b57600080fd5b506102d461059a36600461306a565b6118e9565b3480156105ab57600080fd5b50600e546001600160a01b0316610529565b3480156105c957600080fd5b506102d46119a9565b3480156105de57600080fd5b5060005460405161ffff90911681526020016102b6565b34801561060157600080fd5b506102aa610610366004612b48565b6119b8565b34801561062157600080fd5b506102aa610630366004612b48565b611a6d565b34801561064157600080fd5b506102aa6106503660046130fc565b60009081526002602052604090205460ff1690565b34801561067157600080fd5b50600754610332565b34801561068657600080fd5b506105296106953660046130fc565b611a7b565b3480156106a657600080fd5b50600654610332565b3480156106bb57600080fd5b506106cf6106ca366004612cd9565b611af1565b6040516102b69190600060c0820190508251825260208301516020830152604083015161ffff808216604085015260608501516060850152806080860151166080850152505060ff60a08401511660a083015292915050565b34801561073457600080fd5b50610332610743366004613115565b6001600160a01b039182166000908152600a6020908152604080832093909416825291909152205490565b34801561077a57600080fd5b50610332610789366004612ee9565b6001600160a01b031690565b3480156107a157600080fd5b506005547501000000000000000000000000000000000000000000900460ff166103ef565b3480156107d257600080fd5b506103806107e1366004612ee9565b611c2c565b3480156107f257600080fd5b50610332610801366004613148565b61ffff1660009081526003602052604090205490565b61082a610825366004613177565b611cbc565b60405167ffffffffffffffff90911681526020016102b6565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fadf0604b0000000000000000000000000000000000000000000000000000000014806108d657507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6060600c80546108eb906131c1565b80601f0160208091040260200160405190810160405280929190818152602001828054610917906131c1565b80156109645780601f1061093957610100808354040283529160200191610964565b820191906000526020600020905b81548152906001019060200180831161094757829003601f168201915b5050505050905090565b60003361097c818585612048565b5060019392505050565b6000806008018260405161099a919061320f565b9081526040519081900360200190205460ff1692915050565b6000336109c18582856121a0565b6109cc85858561224a565b60019150505b9392505050565b806109ec600e546001600160a01b031690565b6001600160a01b0316336001600160a01b03161415610a3c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff166201000060ff861602179055505050565b6000610b0a82600001518360200151604051602001610a8c92919060609290921b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000168252601482015260340190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000084830152603c8085019190915282518085039091018152605c909301909152815191012090565b82519091506001600160a01b03163314610b6b5760405162461bcd60e51b815260206004820152601760248201527f637573746f6469616e2063616e2063616c6c206f6e6c7900000000000000000060448201526064015b60405180910390fd5b42826020015111610bbe5760405162461bcd60e51b815260206004820152601a60248201527f7369676e6564207472616e73616374696f6e20657870697265640000000000006044820152606401610b62565b610bcb8260400151610986565b15610c185760405162461bcd60e51b815260206004820152601860248201527f63616e6e6f742072652d757365207369676e61747572657300000000000000006044820152606401610b62565b610c25826040015161243e565b610c45818360400151610c40600e546001600160a01b031690565b612494565b610c915760405162461bcd60e51b815260206004820152601660248201527f756e617574686f72697a6564207369676e6174757265000000000000000000006044820152606401610b62565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff166201000060ff8716021790555b50505050565b80610cdd600e546001600160a01b031690565b6001600160a01b0316336001600160a01b03161415610d115761ffff84166000908152600360205260409020839055610cc4565b6000610d6182600001518360200151604051602001610a8c92919060609290921b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000168252601482015260340190565b82519091506001600160a01b03163314610dbd5760405162461bcd60e51b815260206004820152601760248201527f637573746f6469616e2063616e2063616c6c206f6e6c790000000000000000006044820152606401610b62565b42826020015111610e105760405162461bcd60e51b815260206004820152601a60248201527f7369676e6564207472616e73616374696f6e20657870697265640000000000006044820152606401610b62565b610e1d8260400151610986565b15610e6a5760405162461bcd60e51b815260206004820152601860248201527f63616e6e6f742072652d757365207369676e61747572657300000000000000006044820152606401610b62565b610e77826040015161243e565b610e92818360400151610c40600e546001600160a01b031690565b610ede5760405162461bcd60e51b815260206004820152601660248201527f756e617574686f72697a6564207369676e6174757265000000000000000000006044820152606401610b62565b50505061ffff91909116600090815260036020526040902055565b60055460609074010000000000000000000000000000000000000000900460ff161515600114610f6b5760405162461bcd60e51b815260206004820152600f60248201527f4e6f7420496e697469616c697a656400000000000000000000000000000000006044820152606401610b62565b46610f7560045490565b14610fc25760405162461bcd60e51b815260206004820152601060248201527f756e737570706f7274656420666f726b000000000000000000000000000000006044820152606401610b62565b6000806000610fd96001546001600160a01b031690565b6001600160a01b031663c0fd8bde866040518263ffffffff1660e01b81526004016110049190612b19565b600060405180830381865afa158015611021573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611067919081019061335e565b92509250925081819061108d5760405162461bcd60e51b8152600401610b629190612b19565b50306001600160a01b03166110a58460800151611a7b565b6001600160a01b031614806110d457506080830151606084015161ffff16600090815260036020526040902054145b6111205760405162461bcd60e51b815260206004820152600f60248201527f496e76616c696420456d697474657200000000000000000000000000000000006044820152606401610b62565b600061112f8460e00151611af1565b905060006111408260600151611a7b565b905061116085610140015160009081526002602052604090205460ff1690565b156111ad5760405162461bcd60e51b815260206004820152601a60248201527f7472616e7366657220616c726561647920636f6d706c657465640000000000006044820152606401610b62565b6111ef856101400151600090815260026020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6001546001600160a01b03166001600160a01b0316639a8a05926040518163ffffffff1660e01b8152600401602060405180830381865afa158015611238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061125c91906134ac565b61ffff16826080015161ffff16146112b65760405162461bcd60e51b815260206004820152601460248201527f696e76616c69642074617267657420636861696e0000000000000000000000006044820152606401610b62565b60006112f083600001518460a001516112eb60055460ff75010000000000000000000000000000000000000000009091041690565b612549565b90506112fc82826125b3565b82606001517fdf5e04c9235e5b4ddaec2baee15dc9c74de339075fa433a8dd25ebbc0719857b82856040015186608001516040516113519392919092835261ffff918216602084015216604082015260600190565b60405180910390a250505060e090920151949350505050565b336000818152600a602090815260408083206001600160a01b038716845290915281205490919061097c90829086906113a49087906134f8565b612048565b6113b1612674565b60055474010000000000000000000000000000000000000000900460ff161561141c5760405162461bcd60e51b815260206004820152601360248201527f416c726561647920496e697469616c697a6564000000000000000000000000006044820152606401610b62565b60008054600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03871617905561ffff86167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116176201000060ff85160217905560068190556114986000600755565b610cc4600580547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000179055565b6114e4612674565b600654816114f160075490565b6114fb91906134f8565b11156115495760405162461bcd60e51b815260206004820152601260248201527f4d415820535550504c59205245414348454400000000000000000000000000006044820152606401610b62565b6115658161155660075490565b61156091906134f8565b600755565b61156f82826125b3565b5050565b61157b612674565b61158560006126ce565b565b8061159a600e546001600160a01b031690565b6001600160a01b0316336001600160a01b031614156116765782518451146116045760405162461bcd60e51b815260206004820152600d60248201527f496e76616c696420496e707574000000000000000000000000000000000000006044820152606401610b62565b60005b83518110156116705761165e85828151811061162557611625613510565b602002602001015185838151811061163f5761163f613510565b602002602001015161ffff909116600090815260036020526040902055565b806116688161353f565b915050611607565b50610cc4565b60006116c682600001518360200151604051602001610a8c92919060609290921b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000168252601482015260340190565b82519091506001600160a01b031633146117225760405162461bcd60e51b815260206004820152601760248201527f637573746f6469616e2063616e2063616c6c206f6e6c790000000000000000006044820152606401610b62565b428260200151116117755760405162461bcd60e51b815260206004820152601a60248201527f7369676e6564207472616e73616374696f6e20657870697265640000000000006044820152606401610b62565b6117828260400151610986565b156117cf5760405162461bcd60e51b815260206004820152601860248201527f63616e6e6f742072652d757365207369676e61747572657300000000000000006044820152606401610b62565b6117dc826040015161243e565b6117f7818360400151610c40600e546001600160a01b031690565b6118435760405162461bcd60e51b815260206004820152601660248201527f756e617574686f72697a6564207369676e6174757265000000000000000000006044820152606401610b62565b83518551146118945760405162461bcd60e51b815260206004820152600d60248201527f496e76616c696420496e707574000000000000000000000000000000000000006044820152606401610b62565b60005b84518110156118e1576118cf8682815181106118b5576118b5613510565b602002602001015186838151811061163f5761163f613510565b806118d98161353f565b915050611897565b505050505050565b6060816000015182602001518360400151846060015185608001518660a0015160405160200161199396959493929190958652602086019490945260f092831b7fffff0000000000000000000000000000000000000000000000000000000000009081166040870152604286019290925290911b16606283015260f81b7fff0000000000000000000000000000000000000000000000000000000000000016606482015260650190565b6040516020818303038152906040529050919050565b6060600d80546108eb906131c1565b336000818152600a602090815260408083206001600160a01b038716845290915281205490919083811015611a555760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610b62565b611a628286868403612048565b506001949350505050565b60003361097c81858561224a565b60007fffffffffffffffffffffffff0000000000000000000000000000000000000000821615611aed5760405162461bcd60e51b815260206004820152601360248201527f696e76616c69642045564d2061646472657373000000000000000000000000006044820152606401610b62565b5090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905290611b2d8382612738565b8252611b3a6020826134f8565b9050611b46838261279e565b602080840191909152611b5990826134f8565b9050611b6583826127fb565b61ffff166040830152611b796002826134f8565b9050611b85838261279e565b6060830152611b956020826134f8565b9050611ba183826127fb565b61ffff166080830152611bb56002826134f8565b9050611bc18382612861565b60ff1660a0830152611bd46001826134f8565b905080835114611c265760405162461bcd60e51b815260206004820152601060248201527f696e76616c6964205472616e73666572000000000000000000000000000000006044820152606401610b62565b50919050565b611c34612674565b6001600160a01b038116611cb05760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610b62565b611cb9816126ce565b50565b60055460009074010000000000000000000000000000000000000000900460ff161515600114611d2e5760405162461bcd60e51b815260206004820152600f60248201527f4e6f7420496e697469616c697a656400000000000000000000000000000000006044820152606401610b62565b46611d3860045490565b14611d855760405162461bcd60e51b815260206004820152601060248201527f756e737570706f7274656420666f726b000000000000000000000000000000006044820152606401610b62565b6000611d996001546001600160a01b031690565b6001600160a01b0316631a90a2196040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dfa9190613578565b905080341015611e725760405162461bcd60e51b815260206004820152602a60248201527f4e6f7420656e6f756768206665652070726f766964656420746f207075626c6960448201527f7368206d657373616765000000000000000000000000000000000000000000006064820152608401610b62565b6000611e866001546001600160a01b031690565b6001600160a01b0316639a8a05926040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ec3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee791906134ac565b905030611ef433896128c7565b60006040518060c001604052808a81526020018381526020018461ffff1681526020018881526020018961ffff168152602001611f4d60055460ff75010000000000000000000000000000000000000000009091041690565b60ff1690529050611f666001546001600160a01b031690565b6001600160a01b031663b19a437e3488611f7f856118e9565b60005462010000900460ff166040518563ffffffff1660e01b8152600401611fa993929190613591565b60206040518083038185885af1158015611fc7573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611fec91906135c3565b945086611ff833610789565b604080518c815261ffff87811660208301528c168183015290517fce2636d514abb08349f7cf4369885a4ac22355555ff0e1c6f99afc895a77f3669181900360600190a350505050949350505050565b6001600160a01b0383166120c35760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610b62565b6001600160a01b03821661213f5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610b62565b6001600160a01b038381166000818152600a602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b038381166000908152600a60209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610cc4578181101561223d5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610b62565b610cc48484848403612048565b6001600160a01b0383166122c65760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610b62565b6001600160a01b0382166123425760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610b62565b6001600160a01b038316600090815260096020526040902054818110156123d15760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610b62565b6001600160a01b0380851660008181526009602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906124319086815260200190565b60405180910390a3610cc4565b6001600060080182604051612453919061320f565b90815260405190819003602001902080549115157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090921691909117905550565b6000806000806124a386612a32565b9250925092506000600188858585604051600081526020016040526040516124e7949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612509573d6000803e3d6000fd5b505050602060405103519050856001600160a01b0316816001600160a01b0316141561253c5760019450505050506109d2565b60009450505050506109d2565b60008160ff168360ff16111561257b5761256382846135de565b61256e90600a613721565b6125789085613730565b93505b8260ff168260ff1611156125ab5761259383836135de565b61259e90600a613721565b6125a8908561376b565b93505b509192915050565b6001600160a01b0382166126095760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610b62565b80600b600082825461261b91906134f8565b90915550506001600160a01b0382166000818152600960209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b600e546001600160a01b031633146115855760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b62565b600e80546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006127458260206134f8565b835110156127955760405162461bcd60e51b815260206004820152601560248201527f746f55696e743235365f6f75744f66426f756e647300000000000000000000006044820152606401610b62565b50016020015190565b60006127ab8260206134f8565b835110156127955760405162461bcd60e51b815260206004820152601560248201527f746f427974657333325f6f75744f66426f756e647300000000000000000000006044820152606401610b62565b60006128088260026134f8565b835110156128585760405162461bcd60e51b815260206004820152601460248201527f746f55696e7431365f6f75744f66426f756e64730000000000000000000000006044820152606401610b62565b50016002015190565b600061286e8260016134f8565b835110156128be5760405162461bcd60e51b815260206004820152601360248201527f746f55696e74385f6f75744f66426f756e6473000000000000000000000000006044820152606401610b62565b50016001015190565b6001600160a01b0382166129435760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610b62565b6001600160a01b038216600090815260096020526040902054818110156129d25760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610b62565b6001600160a01b03831660008181526009602090815260408083208686039055600b80548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b60008060008351604114612a4557600080fd5b5050506020810151604082015160609092015160001a92909190565b600060208284031215612a7357600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146109d257600080fd5b60005b83811015612abe578181015183820152602001612aa6565b83811115610cc45750506000910152565b60008151808452612ae7816020860160208601612aa3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006109d26020830184612acf565b80356001600160a01b0381168114612b4357600080fd5b919050565b60008060408385031215612b5b57600080fd5b612b6483612b2c565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715612bc457612bc4612b72565b60405290565b604051610160810167ffffffffffffffff81118282101715612bc457612bc4612b72565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612c3557612c35612b72565b604052919050565b600067ffffffffffffffff821115612c5757612c57612b72565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112612c9457600080fd5b8135612ca7612ca282612c3d565b612bee565b818152846020838601011115612cbc57600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215612ceb57600080fd5b813567ffffffffffffffff811115612d0257600080fd5b612d0e84828501612c83565b949350505050565b600080600060608486031215612d2b57600080fd5b612d3484612b2c565b9250612d4260208501612b2c565b9150604084013590509250925092565b60ff81168114611cb957600080fd5b600060608284031215612d7357600080fd5b6040516060810167ffffffffffffffff8282108183111715612d9757612d97612b72565b81604052829350612da785612b2c565b8352602085013560208401526040850135915080821115612dc757600080fd5b50612dd485828601612c83565b6040830152505092915050565b60008060408385031215612df457600080fd5b8235612dff81612d52565b9150602083013567ffffffffffffffff811115612e1b57600080fd5b612e2785828601612d61565b9150509250929050565b61ffff81168114611cb957600080fd5b600080600060608486031215612e5657600080fd5b8335612e6181612e31565b925060208401359150604084013567ffffffffffffffff811115612e8457600080fd5b612e9086828701612d61565b9150509250925092565b60008060008060808587031215612eb057600080fd5b8435612ebb81612e31565b9350612ec960208601612b2c565b92506040850135612ed981612d52565b9396929550929360600135925050565b600060208284031215612efb57600080fd5b6109d282612b2c565b600067ffffffffffffffff821115612f1e57612f1e612b72565b5060051b60200190565b600082601f830112612f3957600080fd5b81356020612f49612ca283612f04565b82815260059290921b84018101918181019086841115612f6857600080fd5b8286015b84811015612f835780358352918301918301612f6c565b509695505050505050565b600080600060608486031215612fa357600080fd5b833567ffffffffffffffff80821115612fbb57600080fd5b818601915086601f830112612fcf57600080fd5b81356020612fdf612ca283612f04565b82815260059290921b8401810191818101908a841115612ffe57600080fd5b948201945b8386101561302557853561301681612e31565b82529482019490820190613003565b9750508701359250508082111561303b57600080fd5b61304787838801612f28565b9350604086013591508082111561305d57600080fd5b50612e9086828701612d61565b600060c0828403121561307c57600080fd5b60405160c0810181811067ffffffffffffffff8211171561309f5761309f612b72565b8060405250823581526020830135602082015260408301356130c081612e31565b60408201526060838101359082015260808301356130dd81612e31565b608082015260a08301356130f081612d52565b60a08201529392505050565b60006020828403121561310e57600080fd5b5035919050565b6000806040838503121561312857600080fd5b61313183612b2c565b915061313f60208401612b2c565b90509250929050565b60006020828403121561315a57600080fd5b81356109d281612e31565b63ffffffff81168114611cb957600080fd5b6000806000806080858703121561318d57600080fd5b84359350602085013561319f81612e31565b92506040850135915060608501356131b681613165565b939692955090935050565b600181811c908216806131d557607f821691505b60208210811415611c26577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60008251613221818460208701612aa3565b9190910192915050565b8051612b4381612d52565b8051612b4381613165565b8051612b4381612e31565b805167ffffffffffffffff81168114612b4357600080fd5b600082601f83011261327557600080fd5b8151613283612ca282612c3d565b81815284602083860101111561329857600080fd5b612d0e826020830160208701612aa3565b600082601f8301126132ba57600080fd5b815160206132ca612ca283612f04565b82815260079290921b840181019181810190868411156132e957600080fd5b8286015b84811015612f8357608081890312156133065760008081fd5b61330e612ba1565b81518152848201518582015260408083015161332981612d52565b9082015260608281015161333c81612d52565b908201528352918301916080016132ed565b80518015158114612b4357600080fd5b60008060006060848603121561337357600080fd5b835167ffffffffffffffff8082111561338b57600080fd5b9085019061016082880312156133a057600080fd5b6133a8612bca565b6133b18361322b565b81526133bf60208401613236565b60208201526133d060408401613236565b60408201526133e160608401613241565b6060820152608083015160808201526133fc60a0840161324c565b60a082015261340d60c0840161322b565b60c082015260e08301518281111561342457600080fd5b61343089828601613264565b60e083015250610100613444818501613236565b90820152610120838101518381111561345c57600080fd5b6134688a8287016132a9565b9183019190915250610140838101519082015294506134896020870161334e565b9350604086015191508082111561349f57600080fd5b50612e9086828701613264565b6000602082840312156134be57600080fd5b81516109d281612e31565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561350b5761350b6134c9565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613571576135716134c9565b5060010190565b60006020828403121561358a57600080fd5b5051919050565b63ffffffff841681526060602082015260006135b06060830185612acf565b905060ff83166040830152949350505050565b6000602082840312156135d557600080fd5b6109d28261324c565b600060ff821660ff8416808210156135f8576135f86134c9565b90039392505050565b600181815b8085111561365a57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613640576136406134c9565b8085161561364d57918102915b93841c9390800290613606565b509250929050565b600082613671575060016108d6565b8161367e575060006108d6565b8160018114613694576002811461369e576136ba565b60019150506108d6565b60ff8411156136af576136af6134c9565b50506001821b6108d6565b5060208310610133831016604e8410600b84101617156136dd575081810a6108d6565b6136e78383613601565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613719576137196134c9565b029392505050565b60006109d260ff841683613662565b600082613766577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156137a3576137a36134c9565b50029056fea2646970667358221220271164ad7854cff628789c8e146bdea5141c1f0afd8465b07e4edc084694ac5764736f6c634300080a0033000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000d506f727433204e6574776f726b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005504f525433000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106102855760003560e01c80637d557a3f11610153578063c1bd8cf9116100cb578063ded8454a1161007f578063f2fde38b11610064578063f2fde38b146107c6578063f7ee9998146107e6578063ff99c39f1461081757600080fd5b8063ded8454a1461076e578063f0141d841461079557600080fd5b8063d5abeb01116100b0578063d5abeb011461069a578063dc02f456146106af578063dd62ed3e1461072857600080fd5b8063c1bd8cf914610665578063c599efdd1461067a57600080fd5b806395d89b4111610122578063a457c2d711610107578063a457c2d7146105f5578063a9059cbb14610615578063aa4efa5b1461063557600080fd5b806395d89b41146105bd5780639a8a0592146105d257600080fd5b80637d557a3f1461054157806384acd1bb14610561578063860369cc1461057f5780638da5cb5b1461059f57600080fd5b8063313ce5671161020157806364d42b17116101b5578063715018a61161019a578063715018a6146104dc578063739fc8d1146104f157806374d32ad41461050f57600080fd5b806364d42b171461049157806370a08231146104a657600080fd5b806339509351116101e657806339509351146104315780633fb7778b1461045157806340c10f191461047157600080fd5b8063313ce567146103c2578063392e53cd1461040157600080fd5b806318160ddd116102585780632af6d4a81161023d5780632af6d4a8146103605780632c5485f4146103825780632d1fdb46146103a257600080fd5b806318160ddd1461032157806323b872dd1461034057600080fd5b806301ffc9a71461028a57806306fdde03146102bf578063095ea7b3146102e15780631150f0f314610301575b600080fd5b34801561029657600080fd5b506102aa6102a5366004612a61565b610843565b60405190151581526020015b60405180910390f35b3480156102cb57600080fd5b506102d46108dc565b6040516102b69190612b19565b3480156102ed57600080fd5b506102aa6102fc366004612b48565b61096e565b34801561030d57600080fd5b506102aa61031c366004612cd9565b610986565b34801561032d57600080fd5b50600b545b6040519081526020016102b6565b34801561034c57600080fd5b506102aa61035b366004612d16565b6109b3565b34801561036c57600080fd5b5061038061037b366004612de1565b6109d9565b005b34801561038e57600080fd5b5061038061039d366004612e41565b610cca565b3480156103ae57600080fd5b506102d46103bd366004612cd9565b610ef9565b3480156103ce57600080fd5b506005547501000000000000000000000000000000000000000000900460ff165b60405160ff90911681526020016102b6565b34801561040d57600080fd5b5060055474010000000000000000000000000000000000000000900460ff166102aa565b34801561043d57600080fd5b506102aa61044c366004612b48565b61136a565b34801561045d57600080fd5b5061038061046c366004612e9a565b6113a9565b34801561047d57600080fd5b5061038061048c366004612b48565b6114dc565b34801561049d57600080fd5b50600454610332565b3480156104b257600080fd5b506103326104c1366004612ee9565b6001600160a01b031660009081526009602052604090205490565b3480156104e857600080fd5b50610380611573565b3480156104fd57600080fd5b5060005462010000900460ff166103ef565b34801561051b57600080fd5b506005546001600160a01b03165b6040516001600160a01b0390911681526020016102b6565b34801561054d57600080fd5b5061038061055c366004612f8e565b611587565b34801561056d57600080fd5b506001546001600160a01b0316610529565b34801561058b57600080fd5b506102d461059a36600461306a565b6118e9565b3480156105ab57600080fd5b50600e546001600160a01b0316610529565b3480156105c957600080fd5b506102d46119a9565b3480156105de57600080fd5b5060005460405161ffff90911681526020016102b6565b34801561060157600080fd5b506102aa610610366004612b48565b6119b8565b34801561062157600080fd5b506102aa610630366004612b48565b611a6d565b34801561064157600080fd5b506102aa6106503660046130fc565b60009081526002602052604090205460ff1690565b34801561067157600080fd5b50600754610332565b34801561068657600080fd5b506105296106953660046130fc565b611a7b565b3480156106a657600080fd5b50600654610332565b3480156106bb57600080fd5b506106cf6106ca366004612cd9565b611af1565b6040516102b69190600060c0820190508251825260208301516020830152604083015161ffff808216604085015260608501516060850152806080860151166080850152505060ff60a08401511660a083015292915050565b34801561073457600080fd5b50610332610743366004613115565b6001600160a01b039182166000908152600a6020908152604080832093909416825291909152205490565b34801561077a57600080fd5b50610332610789366004612ee9565b6001600160a01b031690565b3480156107a157600080fd5b506005547501000000000000000000000000000000000000000000900460ff166103ef565b3480156107d257600080fd5b506103806107e1366004612ee9565b611c2c565b3480156107f257600080fd5b50610332610801366004613148565b61ffff1660009081526003602052604090205490565b61082a610825366004613177565b611cbc565b60405167ffffffffffffffff90911681526020016102b6565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167fadf0604b0000000000000000000000000000000000000000000000000000000014806108d657507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316145b92915050565b6060600c80546108eb906131c1565b80601f0160208091040260200160405190810160405280929190818152602001828054610917906131c1565b80156109645780601f1061093957610100808354040283529160200191610964565b820191906000526020600020905b81548152906001019060200180831161094757829003601f168201915b5050505050905090565b60003361097c818585612048565b5060019392505050565b6000806008018260405161099a919061320f565b9081526040519081900360200190205460ff1692915050565b6000336109c18582856121a0565b6109cc85858561224a565b60019150505b9392505050565b806109ec600e546001600160a01b031690565b6001600160a01b0316336001600160a01b03161415610a3c57600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff166201000060ff861602179055505050565b6000610b0a82600001518360200151604051602001610a8c92919060609290921b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000168252601482015260340190565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815282825280516020918201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000084830152603c8085019190915282518085039091018152605c909301909152815191012090565b82519091506001600160a01b03163314610b6b5760405162461bcd60e51b815260206004820152601760248201527f637573746f6469616e2063616e2063616c6c206f6e6c7900000000000000000060448201526064015b60405180910390fd5b42826020015111610bbe5760405162461bcd60e51b815260206004820152601a60248201527f7369676e6564207472616e73616374696f6e20657870697265640000000000006044820152606401610b62565b610bcb8260400151610986565b15610c185760405162461bcd60e51b815260206004820152601860248201527f63616e6e6f742072652d757365207369676e61747572657300000000000000006044820152606401610b62565b610c25826040015161243e565b610c45818360400151610c40600e546001600160a01b031690565b612494565b610c915760405162461bcd60e51b815260206004820152601660248201527f756e617574686f72697a6564207369676e6174757265000000000000000000006044820152606401610b62565b600080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ffff166201000060ff8716021790555b50505050565b80610cdd600e546001600160a01b031690565b6001600160a01b0316336001600160a01b03161415610d115761ffff84166000908152600360205260409020839055610cc4565b6000610d6182600001518360200151604051602001610a8c92919060609290921b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000168252601482015260340190565b82519091506001600160a01b03163314610dbd5760405162461bcd60e51b815260206004820152601760248201527f637573746f6469616e2063616e2063616c6c206f6e6c790000000000000000006044820152606401610b62565b42826020015111610e105760405162461bcd60e51b815260206004820152601a60248201527f7369676e6564207472616e73616374696f6e20657870697265640000000000006044820152606401610b62565b610e1d8260400151610986565b15610e6a5760405162461bcd60e51b815260206004820152601860248201527f63616e6e6f742072652d757365207369676e61747572657300000000000000006044820152606401610b62565b610e77826040015161243e565b610e92818360400151610c40600e546001600160a01b031690565b610ede5760405162461bcd60e51b815260206004820152601660248201527f756e617574686f72697a6564207369676e6174757265000000000000000000006044820152606401610b62565b50505061ffff91909116600090815260036020526040902055565b60055460609074010000000000000000000000000000000000000000900460ff161515600114610f6b5760405162461bcd60e51b815260206004820152600f60248201527f4e6f7420496e697469616c697a656400000000000000000000000000000000006044820152606401610b62565b46610f7560045490565b14610fc25760405162461bcd60e51b815260206004820152601060248201527f756e737570706f7274656420666f726b000000000000000000000000000000006044820152606401610b62565b6000806000610fd96001546001600160a01b031690565b6001600160a01b031663c0fd8bde866040518263ffffffff1660e01b81526004016110049190612b19565b600060405180830381865afa158015611021573d6000803e3d6000fd5b505050506040513d6000823e601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201604052611067919081019061335e565b92509250925081819061108d5760405162461bcd60e51b8152600401610b629190612b19565b50306001600160a01b03166110a58460800151611a7b565b6001600160a01b031614806110d457506080830151606084015161ffff16600090815260036020526040902054145b6111205760405162461bcd60e51b815260206004820152600f60248201527f496e76616c696420456d697474657200000000000000000000000000000000006044820152606401610b62565b600061112f8460e00151611af1565b905060006111408260600151611a7b565b905061116085610140015160009081526002602052604090205460ff1690565b156111ad5760405162461bcd60e51b815260206004820152601a60248201527f7472616e7366657220616c726561647920636f6d706c657465640000000000006044820152606401610b62565b6111ef856101400151600090815260026020526040902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055565b6001546001600160a01b03166001600160a01b0316639a8a05926040518163ffffffff1660e01b8152600401602060405180830381865afa158015611238573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061125c91906134ac565b61ffff16826080015161ffff16146112b65760405162461bcd60e51b815260206004820152601460248201527f696e76616c69642074617267657420636861696e0000000000000000000000006044820152606401610b62565b60006112f083600001518460a001516112eb60055460ff75010000000000000000000000000000000000000000009091041690565b612549565b90506112fc82826125b3565b82606001517fdf5e04c9235e5b4ddaec2baee15dc9c74de339075fa433a8dd25ebbc0719857b82856040015186608001516040516113519392919092835261ffff918216602084015216604082015260600190565b60405180910390a250505060e090920151949350505050565b336000818152600a602090815260408083206001600160a01b038716845290915281205490919061097c90829086906113a49087906134f8565b612048565b6113b1612674565b60055474010000000000000000000000000000000000000000900460ff161561141c5760405162461bcd60e51b815260206004820152601360248201527f416c726561647920496e697469616c697a6564000000000000000000000000006044820152606401610b62565b60008054600180547fffffffffffffffffffffffff0000000000000000000000000000000000000000166001600160a01b03871617905561ffff86167fffffffffffffffffffffffffffffffffffffffffffffffffffffffffff000000909116176201000060ff85160217905560068190556114986000600755565b610cc4600580547fffffffffffffffffffffff00ffffffffffffffffffffffffffffffffffffffff1674010000000000000000000000000000000000000000179055565b6114e4612674565b600654816114f160075490565b6114fb91906134f8565b11156115495760405162461bcd60e51b815260206004820152601260248201527f4d415820535550504c59205245414348454400000000000000000000000000006044820152606401610b62565b6115658161155660075490565b61156091906134f8565b600755565b61156f82826125b3565b5050565b61157b612674565b61158560006126ce565b565b8061159a600e546001600160a01b031690565b6001600160a01b0316336001600160a01b031614156116765782518451146116045760405162461bcd60e51b815260206004820152600d60248201527f496e76616c696420496e707574000000000000000000000000000000000000006044820152606401610b62565b60005b83518110156116705761165e85828151811061162557611625613510565b602002602001015185838151811061163f5761163f613510565b602002602001015161ffff909116600090815260036020526040902055565b806116688161353f565b915050611607565b50610cc4565b60006116c682600001518360200151604051602001610a8c92919060609290921b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000168252601482015260340190565b82519091506001600160a01b031633146117225760405162461bcd60e51b815260206004820152601760248201527f637573746f6469616e2063616e2063616c6c206f6e6c790000000000000000006044820152606401610b62565b428260200151116117755760405162461bcd60e51b815260206004820152601a60248201527f7369676e6564207472616e73616374696f6e20657870697265640000000000006044820152606401610b62565b6117828260400151610986565b156117cf5760405162461bcd60e51b815260206004820152601860248201527f63616e6e6f742072652d757365207369676e61747572657300000000000000006044820152606401610b62565b6117dc826040015161243e565b6117f7818360400151610c40600e546001600160a01b031690565b6118435760405162461bcd60e51b815260206004820152601660248201527f756e617574686f72697a6564207369676e6174757265000000000000000000006044820152606401610b62565b83518551146118945760405162461bcd60e51b815260206004820152600d60248201527f496e76616c696420496e707574000000000000000000000000000000000000006044820152606401610b62565b60005b84518110156118e1576118cf8682815181106118b5576118b5613510565b602002602001015186838151811061163f5761163f613510565b806118d98161353f565b915050611897565b505050505050565b6060816000015182602001518360400151846060015185608001518660a0015160405160200161199396959493929190958652602086019490945260f092831b7fffff0000000000000000000000000000000000000000000000000000000000009081166040870152604286019290925290911b16606283015260f81b7fff0000000000000000000000000000000000000000000000000000000000000016606482015260650190565b6040516020818303038152906040529050919050565b6060600d80546108eb906131c1565b336000818152600a602090815260408083206001600160a01b038716845290915281205490919083811015611a555760405162461bcd60e51b815260206004820152602560248201527f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760448201527f207a65726f0000000000000000000000000000000000000000000000000000006064820152608401610b62565b611a628286868403612048565b506001949350505050565b60003361097c81858561224a565b60007fffffffffffffffffffffffff0000000000000000000000000000000000000000821615611aed5760405162461bcd60e51b815260206004820152601360248201527f696e76616c69642045564d2061646472657373000000000000000000000000006044820152606401610b62565b5090565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a0810182905290611b2d8382612738565b8252611b3a6020826134f8565b9050611b46838261279e565b602080840191909152611b5990826134f8565b9050611b6583826127fb565b61ffff166040830152611b796002826134f8565b9050611b85838261279e565b6060830152611b956020826134f8565b9050611ba183826127fb565b61ffff166080830152611bb56002826134f8565b9050611bc18382612861565b60ff1660a0830152611bd46001826134f8565b905080835114611c265760405162461bcd60e51b815260206004820152601060248201527f696e76616c6964205472616e73666572000000000000000000000000000000006044820152606401610b62565b50919050565b611c34612674565b6001600160a01b038116611cb05760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610b62565b611cb9816126ce565b50565b60055460009074010000000000000000000000000000000000000000900460ff161515600114611d2e5760405162461bcd60e51b815260206004820152600f60248201527f4e6f7420496e697469616c697a656400000000000000000000000000000000006044820152606401610b62565b46611d3860045490565b14611d855760405162461bcd60e51b815260206004820152601060248201527f756e737570706f7274656420666f726b000000000000000000000000000000006044820152606401610b62565b6000611d996001546001600160a01b031690565b6001600160a01b0316631a90a2196040518163ffffffff1660e01b8152600401602060405180830381865afa158015611dd6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dfa9190613578565b905080341015611e725760405162461bcd60e51b815260206004820152602a60248201527f4e6f7420656e6f756768206665652070726f766964656420746f207075626c6960448201527f7368206d657373616765000000000000000000000000000000000000000000006064820152608401610b62565b6000611e866001546001600160a01b031690565b6001600160a01b0316639a8a05926040518163ffffffff1660e01b8152600401602060405180830381865afa158015611ec3573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611ee791906134ac565b905030611ef433896128c7565b60006040518060c001604052808a81526020018381526020018461ffff1681526020018881526020018961ffff168152602001611f4d60055460ff75010000000000000000000000000000000000000000009091041690565b60ff1690529050611f666001546001600160a01b031690565b6001600160a01b031663b19a437e3488611f7f856118e9565b60005462010000900460ff166040518563ffffffff1660e01b8152600401611fa993929190613591565b60206040518083038185885af1158015611fc7573d6000803e3d6000fd5b50505050506040513d601f19601f82011682018060405250810190611fec91906135c3565b945086611ff833610789565b604080518c815261ffff87811660208301528c168183015290517fce2636d514abb08349f7cf4369885a4ac22355555ff0e1c6f99afc895a77f3669181900360600190a350505050949350505050565b6001600160a01b0383166120c35760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610b62565b6001600160a01b03821661213f5760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f20616464726560448201527f73730000000000000000000000000000000000000000000000000000000000006064820152608401610b62565b6001600160a01b038381166000818152600a602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925910160405180910390a3505050565b6001600160a01b038381166000908152600a60209081526040808320938616835292905220547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8114610cc4578181101561223d5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e63650000006044820152606401610b62565b610cc48484848403612048565b6001600160a01b0383166122c65760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f20616460448201527f64726573730000000000000000000000000000000000000000000000000000006064820152608401610b62565b6001600160a01b0382166123425760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201527f65737300000000000000000000000000000000000000000000000000000000006064820152608401610b62565b6001600160a01b038316600090815260096020526040902054818110156123d15760405162461bcd60e51b815260206004820152602660248201527f45524332303a207472616e7366657220616d6f756e742065786365656473206260448201527f616c616e636500000000000000000000000000000000000000000000000000006064820152608401610b62565b6001600160a01b0380851660008181526009602052604080822086860390559286168082529083902080548601905591517fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef906124319086815260200190565b60405180910390a3610cc4565b6001600060080182604051612453919061320f565b90815260405190819003602001902080549115157fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0090921691909117905550565b6000806000806124a386612a32565b9250925092506000600188858585604051600081526020016040526040516124e7949392919093845260ff9290921660208401526040830152606082015260800190565b6020604051602081039080840390855afa158015612509573d6000803e3d6000fd5b505050602060405103519050856001600160a01b0316816001600160a01b0316141561253c5760019450505050506109d2565b60009450505050506109d2565b60008160ff168360ff16111561257b5761256382846135de565b61256e90600a613721565b6125789085613730565b93505b8260ff168260ff1611156125ab5761259383836135de565b61259e90600a613721565b6125a8908561376b565b93505b509192915050565b6001600160a01b0382166126095760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f2061646472657373006044820152606401610b62565b80600b600082825461261b91906134f8565b90915550506001600160a01b0382166000818152600960209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a35050565b600e546001600160a01b031633146115855760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b62565b600e80546001600160a01b038381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60006127458260206134f8565b835110156127955760405162461bcd60e51b815260206004820152601560248201527f746f55696e743235365f6f75744f66426f756e647300000000000000000000006044820152606401610b62565b50016020015190565b60006127ab8260206134f8565b835110156127955760405162461bcd60e51b815260206004820152601560248201527f746f427974657333325f6f75744f66426f756e647300000000000000000000006044820152606401610b62565b60006128088260026134f8565b835110156128585760405162461bcd60e51b815260206004820152601460248201527f746f55696e7431365f6f75744f66426f756e64730000000000000000000000006044820152606401610b62565b50016002015190565b600061286e8260016134f8565b835110156128be5760405162461bcd60e51b815260206004820152601360248201527f746f55696e74385f6f75744f66426f756e6473000000000000000000000000006044820152606401610b62565b50016001015190565b6001600160a01b0382166129435760405162461bcd60e51b815260206004820152602160248201527f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360448201527f73000000000000000000000000000000000000000000000000000000000000006064820152608401610b62565b6001600160a01b038216600090815260096020526040902054818110156129d25760405162461bcd60e51b815260206004820152602260248201527f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60448201527f63650000000000000000000000000000000000000000000000000000000000006064820152608401610b62565b6001600160a01b03831660008181526009602090815260408083208686039055600b80548790039055518581529192917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3505050565b60008060008351604114612a4557600080fd5b5050506020810151604082015160609092015160001a92909190565b600060208284031215612a7357600080fd5b81357fffffffff00000000000000000000000000000000000000000000000000000000811681146109d257600080fd5b60005b83811015612abe578181015183820152602001612aa6565b83811115610cc45750506000910152565b60008151808452612ae7816020860160208601612aa3565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006109d26020830184612acf565b80356001600160a01b0381168114612b4357600080fd5b919050565b60008060408385031215612b5b57600080fd5b612b6483612b2c565b946020939093013593505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040516080810167ffffffffffffffff81118282101715612bc457612bc4612b72565b60405290565b604051610160810167ffffffffffffffff81118282101715612bc457612bc4612b72565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715612c3557612c35612b72565b604052919050565b600067ffffffffffffffff821115612c5757612c57612b72565b50601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01660200190565b600082601f830112612c9457600080fd5b8135612ca7612ca282612c3d565b612bee565b818152846020838601011115612cbc57600080fd5b816020850160208301376000918101602001919091529392505050565b600060208284031215612ceb57600080fd5b813567ffffffffffffffff811115612d0257600080fd5b612d0e84828501612c83565b949350505050565b600080600060608486031215612d2b57600080fd5b612d3484612b2c565b9250612d4260208501612b2c565b9150604084013590509250925092565b60ff81168114611cb957600080fd5b600060608284031215612d7357600080fd5b6040516060810167ffffffffffffffff8282108183111715612d9757612d97612b72565b81604052829350612da785612b2c565b8352602085013560208401526040850135915080821115612dc757600080fd5b50612dd485828601612c83565b6040830152505092915050565b60008060408385031215612df457600080fd5b8235612dff81612d52565b9150602083013567ffffffffffffffff811115612e1b57600080fd5b612e2785828601612d61565b9150509250929050565b61ffff81168114611cb957600080fd5b600080600060608486031215612e5657600080fd5b8335612e6181612e31565b925060208401359150604084013567ffffffffffffffff811115612e8457600080fd5b612e9086828701612d61565b9150509250925092565b60008060008060808587031215612eb057600080fd5b8435612ebb81612e31565b9350612ec960208601612b2c565b92506040850135612ed981612d52565b9396929550929360600135925050565b600060208284031215612efb57600080fd5b6109d282612b2c565b600067ffffffffffffffff821115612f1e57612f1e612b72565b5060051b60200190565b600082601f830112612f3957600080fd5b81356020612f49612ca283612f04565b82815260059290921b84018101918181019086841115612f6857600080fd5b8286015b84811015612f835780358352918301918301612f6c565b509695505050505050565b600080600060608486031215612fa357600080fd5b833567ffffffffffffffff80821115612fbb57600080fd5b818601915086601f830112612fcf57600080fd5b81356020612fdf612ca283612f04565b82815260059290921b8401810191818101908a841115612ffe57600080fd5b948201945b8386101561302557853561301681612e31565b82529482019490820190613003565b9750508701359250508082111561303b57600080fd5b61304787838801612f28565b9350604086013591508082111561305d57600080fd5b50612e9086828701612d61565b600060c0828403121561307c57600080fd5b60405160c0810181811067ffffffffffffffff8211171561309f5761309f612b72565b8060405250823581526020830135602082015260408301356130c081612e31565b60408201526060838101359082015260808301356130dd81612e31565b608082015260a08301356130f081612d52565b60a08201529392505050565b60006020828403121561310e57600080fd5b5035919050565b6000806040838503121561312857600080fd5b61313183612b2c565b915061313f60208401612b2c565b90509250929050565b60006020828403121561315a57600080fd5b81356109d281612e31565b63ffffffff81168114611cb957600080fd5b6000806000806080858703121561318d57600080fd5b84359350602085013561319f81612e31565b92506040850135915060608501356131b681613165565b939692955090935050565b600181811c908216806131d557607f821691505b60208210811415611c26577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60008251613221818460208701612aa3565b9190910192915050565b8051612b4381612d52565b8051612b4381613165565b8051612b4381612e31565b805167ffffffffffffffff81168114612b4357600080fd5b600082601f83011261327557600080fd5b8151613283612ca282612c3d565b81815284602083860101111561329857600080fd5b612d0e826020830160208701612aa3565b600082601f8301126132ba57600080fd5b815160206132ca612ca283612f04565b82815260079290921b840181019181810190868411156132e957600080fd5b8286015b84811015612f8357608081890312156133065760008081fd5b61330e612ba1565b81518152848201518582015260408083015161332981612d52565b9082015260608281015161333c81612d52565b908201528352918301916080016132ed565b80518015158114612b4357600080fd5b60008060006060848603121561337357600080fd5b835167ffffffffffffffff8082111561338b57600080fd5b9085019061016082880312156133a057600080fd5b6133a8612bca565b6133b18361322b565b81526133bf60208401613236565b60208201526133d060408401613236565b60408201526133e160608401613241565b6060820152608083015160808201526133fc60a0840161324c565b60a082015261340d60c0840161322b565b60c082015260e08301518281111561342457600080fd5b61343089828601613264565b60e083015250610100613444818501613236565b90820152610120838101518381111561345c57600080fd5b6134688a8287016132a9565b9183019190915250610140838101519082015294506134896020870161334e565b9350604086015191508082111561349f57600080fd5b50612e9086828701613264565b6000602082840312156134be57600080fd5b81516109d281612e31565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000821982111561350b5761350b6134c9565b500190565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415613571576135716134c9565b5060010190565b60006020828403121561358a57600080fd5b5051919050565b63ffffffff841681526060602082015260006135b06060830185612acf565b905060ff83166040830152949350505050565b6000602082840312156135d557600080fd5b6109d28261324c565b600060ff821660ff8416808210156135f8576135f86134c9565b90039392505050565b600181815b8085111561365a57817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613640576136406134c9565b8085161561364d57918102915b93841c9390800290613606565b509250929050565b600082613671575060016108d6565b8161367e575060006108d6565b8160018114613694576002811461369e576136ba565b60019150506108d6565b60ff8411156136af576136af6134c9565b50506001821b6108d6565b5060208310610133831016604e8410600b84101617156136dd575081810a6108d6565b6136e78383613601565b807fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04821115613719576137196134c9565b029392505050565b60006109d260ff841683613662565b600082613766577f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff04831182151516156137a3576137a36134c9565b50029056fea2646970667358221220271164ad7854cff628789c8e146bdea5141c1f0afd8465b07e4edc084694ac5764736f6c634300080a0033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000a00000000000000000000000000000000000000000000000000000000000000012000000000000000000000000000000000000000000000000000000000000000d506f727433204e6574776f726b000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000005504f525433000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : name (string): Port3 Network
Arg [1] : symbol (string): PORT3
Arg [2] : decimal (uint8): 18

-----Encoded View---------------
7 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [1] : 00000000000000000000000000000000000000000000000000000000000000a0
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000012
Arg [3] : 000000000000000000000000000000000000000000000000000000000000000d
Arg [4] : 506f727433204e6574776f726b00000000000000000000000000000000000000
Arg [5] : 0000000000000000000000000000000000000000000000000000000000000005
Arg [6] : 504f525433000000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

73391:3457:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74115:205;;;;;;;;;;-1:-1:-1;74115:205:0;;;;;:::i;:::-;;:::i;:::-;;;516:14:1;;509:22;491:41;;479:2;464:18;74115:205:0;;;;;;;;57643:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;59994:201::-;;;;;;;;;;-1:-1:-1;59994:201:0;;;;;:::i;:::-;;:::i;49034:134::-;;;;;;;;;;-1:-1:-1;49034:134:0;;;;;:::i;:::-;;:::i;58763:108::-;;;;;;;;;;-1:-1:-1;58851:12:0;;58763:108;;;4047:25:1;;;4035:2;4020:18;58763:108:0;3901:177:1;60775:295:0;;;;;;;;;;-1:-1:-1;60775:295:0;;;;;:::i;:::-;;:::i;54580:223::-;;;;;;;;;;-1:-1:-1;54580:223:0;;;;;:::i;:::-;;:::i;:::-;;53778:279;;;;;;;;;;-1:-1:-1;53778:279:0;;;;;:::i;:::-;;:::i;75480:1140::-;;;;;;;;;;-1:-1:-1;75480:1140:0;;;;;:::i;:::-;;:::i;74014:95::-;;;;;;;;;;-1:-1:-1;48561:15:0;;;;;;;74014:95;;;6831:4:1;6819:17;;;6801:36;;6789:2;6774:18;74014:95:0;6659:184:1;48928:98:0;;;;;;;;;;-1:-1:-1;48998:20:0;;;;;;;48928:98;;61479:238;;;;;;;;;;-1:-1:-1;61479:238:0;;;;;:::i;:::-;;:::i;73666:342::-;;;;;;;;;;-1:-1:-1;73666:342:0;;;;;:::i;:::-;;:::i;76626:219::-;;;;;;;;;;-1:-1:-1;76626:219:0;;;;;:::i;:::-;;:::i;48141:95::-;;;;;;;;;;-1:-1:-1;48211:17:0;;48141:95;;58934:127;;;;;;;;;;-1:-1:-1;58934:127:0;;;;;:::i;:::-;-1:-1:-1;;;;;59035:18:0;59008:7;59035:18;;;:9;:18;;;;;;;58934:127;31768:103;;;;;;;;;;;;;:::i;48386:98::-;;;;;;;;;;-1:-1:-1;48427:5:0;48452:24;;;;;;48386:98;;48800:120;;;;;;;;;;-1:-1:-1;48893:18:0;;-1:-1:-1;;;;;48893:18:0;48800:120;;;-1:-1:-1;;;;;7756:55:1;;;7738:74;;7726:2;7711:18;48800:120:0;7569:249:1;54065:456:0;;;;;;;;;;-1:-1:-1;54065:456:0;;;;;:::i;:::-;;:::i;47924:104::-;;;;;;;;;;-1:-1:-1;48004:15:0;;-1:-1:-1;;;;;48004:15:0;47924:104;;50152:391;;;;;;;;;;-1:-1:-1;50152:391:0;;;;;:::i;:::-;;:::i;31120:87::-;;;;;;;;;;-1:-1:-1;31193:6:0;;-1:-1:-1;;;;;31193:6:0;31120:87;;57862:104;;;;;;;;;;;;;:::i;48036:97::-;;;;;;;;;;-1:-1:-1;48076:6:0;48102:23;48036:97;;48102:23;;;;11761:38:1;;11749:2;11734:18;48036:97:0;11617:188:1;62220:436:0;;;;;;;;;;-1:-1:-1;62220:436:0;;;;;:::i;:::-;;:::i;59267:193::-;;;;;;;;;;-1:-1:-1;59267:193:0;;;;;:::i;:::-;;:::i;47789:127::-;;;;;;;;;;-1:-1:-1;47789:127:0;;;;;:::i;:::-;47853:4;47877:31;;;:25;:31;;;;;;;;;47789:127;48693:99;;;;;;;;;;-1:-1:-1;48765:19:0;;48693:99;;49840:177;;;;;;;;;;-1:-1:-1;49840:177:0;;;;;:::i;:::-;;:::i;48592:93::-;;;;;;;;;;-1:-1:-1;48661:16:0;;48592:93;;50551:708;;;;;;;;;;-1:-1:-1;50551:708:0;;;;;:::i;:::-;;:::i;:::-;;;;;;12153:4:1;12195:3;12184:9;12180:19;12172:27;;12232:6;12226:13;12215:9;12208:32;12296:4;12288:6;12284:17;12278:24;12271:4;12260:9;12256:20;12249:54;12350:4;12342:6;12338:17;12332:24;12375:6;12437:2;12423:12;12419:21;12412:4;12401:9;12397:20;12390:51;12497:4;12489:6;12485:17;12479:24;12472:4;12461:9;12457:20;12450:54;12572:2;12564:4;12556:6;12552:17;12546:24;12542:33;12535:4;12524:9;12520:20;12513:63;;;12644:4;12636;12628:6;12624:17;12618:24;12614:35;12607:4;12596:9;12592:20;12585:65;11995:661;;;;;59523:151:0;;;;;;;;;;-1:-1:-1;59523:151:0;;;;;:::i;:::-;-1:-1:-1;;;;;59639:18:0;;;59612:7;59639:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;59523:151;50025:119;;;;;;;;;;-1:-1:-1;50025:119:0;;;;;:::i;:::-;-1:-1:-1;;;;;50116:19:0;;50025:119;48492:92;;;;;;;;;;-1:-1:-1;48561:15:0;;;;;;;48492:92;;32026:201;;;;;;;;;;-1:-1:-1;32026:201:0;;;;;:::i;:::-;;:::i;48244:134::-;;;;;;;;;;-1:-1:-1;48244:134:0;;;;;:::i;:::-;48333:37;;48306:7;48333:37;;;:27;:37;;;;;;;48244:134;74385:1070;;;;;;:::i;:::-;;:::i;:::-;;;14184:18:1;14172:31;;;14154:50;;14142:2;14127:18;74385:1070:0;14010:200:1;74115:205:0;74215:4;74233:42;;;74248:27;74233:42;;:82;;-1:-1:-1;28998:25:0;28983:40;;;;74279:36;74226:89;74115:205;-1:-1:-1;;74115:205:0:o;57643:100::-;57697:13;57730:5;57723:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57643:100;:::o;59994:201::-;60077:4;29774:10;60133:32;29774:10;60149:7;60158:6;60133:8;:32::i;:::-;-1:-1:-1;60183:4:0;;59994:201;-1:-1:-1;;;59994:201:0:o;49034:134::-;49104:4;49128:6;:21;;49150:9;49128:32;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;49034:134;-1:-1:-1;;49034:134:0:o;60775:295::-;60906:4;29774:10;60964:38;60980:4;29774:10;60995:6;60964:15;:38::i;:::-;61013:27;61023:4;61029:2;61033:6;61013:9;:27::i;:::-;61058:4;61051:11;;;60775:295;;;;;;:::o;54580:223::-;54743:18;52850:7;31193:6;;-1:-1:-1;;;;;31193:6:0;;31120:87;52850:7;-1:-1:-1;;;;;52834:23:0;29774:10;-1:-1:-1;;;;;52834:23:0;;52830:882;;;2902:6;:35;;;;;;;;;;;;54580:223;;;:::o;52830:882::-;52908:23;52934:169;53010:18;:28;;;53040:18;:28;;;52993:76;;;;;;;;15113:2:1;15109:15;;;;15126:66;15105:88;15093:101;;15219:2;15210:12;;15203:28;15256:2;15247:12;;14936:329;52993:76:0;;;;;;;;;;;;;;52961:127;;52993:76;52961:127;;;;31075:66:1;51608:59:0;;;31063:79:1;31158:12;;;;31151:28;;;;51608:59:0;;;;;;;;;;31195:12:1;;;;51608:59:0;;;51598:70;;;;;;51515:161;52934:169;53126:28;;52908:195;;-1:-1:-1;;;;;;53126:44:0;29774:10;53126:44;53118:80;;;;-1:-1:-1;;;53118:80:0;;15472:2:1;53118:80:0;;;15454:21:1;15511:2;15491:18;;;15484:30;15550:25;15530:18;;;15523:53;15593:18;;53118:80:0;;;;;;;;;53252:15;53221:18;:28;;;:46;53213:85;;;;-1:-1:-1;;;53213:85:0;;15824:2:1;53213:85:0;;;15806:21:1;15863:2;15843:18;;;15836:30;15902:28;15882:18;;;15875:56;15948:18;;53213:85:0;15622:350:1;53213:85:0;53339:45;53355:18;:28;;;53339:15;:45::i;:::-;:54;53313:140;;;;-1:-1:-1;;;53313:140:0;;16179:2:1;53313:140:0;;;16161:21:1;16218:2;16198:18;;;16191:30;16257:26;16237:18;;;16230:54;16301:18;;53313:140:0;15977:348:1;53313:140:0;53468:46;53485:18;:28;;;53468:16;:46::i;:::-;53555:71;53571:15;53588:18;:28;;;53618:7;31193:6;;-1:-1:-1;;;;;31193:6:0;;31120:87;53618:7;53555:15;:71::i;:::-;53529:155;;;;-1:-1:-1;;;53529:155:0;;16532:2:1;53529:155:0;;;16514:21:1;16571:2;16551:18;;;16544:30;16610:24;16590:18;;;16583:52;16652:18;;53529:155:0;16330:346:1;53529:155:0;2902:6;:35;;;;;;;;;;;;54774:21:::1;52893:819:::0;54580:223;;;:::o;53778:279::-;53972:18;52850:7;31193:6;;-1:-1:-1;;;;;31193:6:0;;31120:87;52850:7;-1:-1:-1;;;;;52834:23:0;29774:10;-1:-1:-1;;;;;52834:23:0;;52830:882;;;2679:36;;;:6;:36;;;:27;:36;;;;;:52;;;52830:882;;;52908:23;52934:169;53010:18;:28;;;53040:18;:28;;;52993:76;;;;;;;;15113:2:1;15109:15;;;;15126:66;15105:88;15093:101;;15219:2;15210:12;;15203:28;15256:2;15247:12;;14936:329;52934:169:0;53126:28;;52908:195;;-1:-1:-1;;;;;;53126:44:0;29774:10;53126:44;53118:80;;;;-1:-1:-1;;;53118:80:0;;15472:2:1;53118:80:0;;;15454:21:1;15511:2;15491:18;;;15484:30;15550:25;15530:18;;;15523:53;15593:18;;53118:80:0;15270:347:1;53118:80:0;53252:15;53221:18;:28;;;:46;53213:85;;;;-1:-1:-1;;;53213:85:0;;15824:2:1;53213:85:0;;;15806:21:1;15863:2;15843:18;;;15836:30;15902:28;15882:18;;;15875:56;15948:18;;53213:85:0;15622:350:1;53213:85:0;53339:45;53355:18;:28;;;53339:15;:45::i;:::-;:54;53313:140;;;;-1:-1:-1;;;53313:140:0;;16179:2:1;53313:140:0;;;16161:21:1;16218:2;16198:18;;;16191:30;16257:26;16237:18;;;16230:54;16301:18;;53313:140:0;15977:348:1;53313:140:0;53468:46;53485:18;:28;;;53468:16;:46::i;:::-;53555:71;53571:15;53588:18;:28;;;53618:7;31193:6;;-1:-1:-1;;;;;31193:6:0;;31120:87;53555:71;53529:155;;;;-1:-1:-1;;;53529:155:0;;16532:2:1;53529:155:0;;;16514:21:1;16571:2;16551:18;;;16544:30;16610:24;16590:18;;;16583:52;16652:18;;53529:155:0;16330:346:1;53529:155:0;-1:-1:-1;;;2679:36:0;;;;;:6;:36;;;:27;:36;;;;;:52;53778:279::o;75480:1140::-;48998:20;;75540:12;;48998:20;;;;;75567:23;;75586:4;75567:23;75559:51;;;;-1:-1:-1;;;75559:51:0;;16883:2:1;75559:51:0;;;16865:21:1;16922:2;16902:18;;;16895:30;16961:17;16941:18;;;16934:45;16996:18;;75559:51:0;16681:339:1;75559:51:0;75639:13;75623:12;48211:17;;;48141:95;75623:12;:29;75615:58;;;;-1:-1:-1;;;75615:58:0;;17227:2:1;75615:58:0;;;17209:21:1;17266:2;17246:18;;;17239:30;17305:18;17285;;;17278:46;17341:18;;75615:58:0;17025:340:1;75615:58:0;75683:22;75707:10;75719:20;75743:10;48004:15;;-1:-1:-1;;;;;48004:15:0;;47924:104;75743:10;-1:-1:-1;;;;;75743:27:0;;75776:9;75743:47;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75682:108;;;;;;75803:5;75810:6;75795:22;;;;;-1:-1:-1;;;75795:22:0;;;;;;;;:::i;:::-;;75880:4;-1:-1:-1;;;;;75835:50:0;:33;75850:2;:17;;;75835:14;:33::i;:::-;-1:-1:-1;;;;;75835:50:0;;:112;;;-1:-1:-1;75930:17:0;;;;75908;;;;48333:37;;48306:7;48333:37;;;:27;:37;;;;;;75893:54;75835:112;75822:153;;;;-1:-1:-1;;;75822:153:0;;21821:2:1;75822:153:0;;;21803:21:1;21860:2;21840:18;;;21833:30;21899:17;21879:18;;;21872:45;21934:18;;75822:153:0;21619:339:1;75822:153:0;75984:49;76036:26;76051:2;:10;;;76036:14;:26::i;:::-;75984:78;;76067:25;76095:34;76110:8;:18;;;76095:14;:34::i;:::-;76067:62;;76147:28;76167:2;:7;;;47853:4;47877:31;;;:25;:31;;;;;;;;;47789:127;76147:28;76146:29;76138:68;;;;-1:-1:-1;;;76138:68:0;;22165:2:1;76138:68:0;;;22147:21:1;22204:2;22184:18;;;22177:30;22243:28;22223:18;;;22216:56;22289:18;;76138:68:0;21963:350:1;76138:68:0;76211:29;76232:2;:7;;;2534:6;:31;;;:25;:31;;;;;:38;;;;2568:4;2534:38;;;2470:110;76211:29;48004:15;;-1:-1:-1;;;;;48004:15:0;-1:-1:-1;;;;;76277:18:0;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;76257:40;;:8;:16;;;:40;;;76249:73;;;;-1:-1:-1;;;76249:73:0;;22774:2:1;76249:73:0;;;22756:21:1;22813:2;22793:18;;;22786:30;22852:22;22832:18;;;22825:50;22892:18;;76249:73:0;22572:344:1;76249:73:0;76331:20;76354:88;76375:8;:15;;;76396:8;:22;;;76424:13;48561:15;;;;;;;;;48492:92;76424:13;76354:15;:88::i;:::-;76331:111;;76451:38;76457:17;76476:12;76451:5;:38::i;:::-;76570:8;:18;;;76503:86;76517:12;76531:8;:19;;;76552:8;:16;;;76503:86;;;;;;;23121:25:1;;;23165:6;23207:15;;;23202:2;23187:18;;23180:43;23259:15;23254:2;23239:18;;23232:43;23109:2;23094:18;;22921:360;76503:86:0;;;;;;;;-1:-1:-1;;;76605:10:0;;;;;;75480:1140;-1:-1:-1;;;;75480:1140:0:o;61479:238::-;29774:10;61567:4;59639:18;;;:11;:18;;;;;;;;-1:-1:-1;;;;;59639:27:0;;;;;;;;;;61567:4;;29774:10;61623:64;;29774:10;;59639:27;;61648:38;;61676:10;;61648:38;:::i;:::-;61623:8;:64::i;73666:342::-;31006:13;:11;:13::i;:::-;48998:20;;;;;;;73801:24:::1;73793:56;;;::::0;-1:-1:-1;;;73793:56:0;;23810:2:1;73793:56:0::1;::::0;::::1;23792:21:1::0;23849:2;23829:18;;;23822:30;23888:21;23868:18;;;23861:49;23927:18;;73793:56:0::1;23608:343:1::0;73793:56:0::1;3009:6:::0;:33;;-1:-1:-1;2800:29:0;;;;-1:-1:-1;;;;;2800:29:0;;;;;3009:33;;;2902:35;;;;;;;;;;;;;3396:16;:28;;;73962:18:::1;73978:1;3507:19:::0;:34;3440:109;73962:18:::1;73985;3718:20:::0;:27;;;;;;;;3670:83;76626:219;31006:13;:11;:13::i;:::-;48661:16;;76722:6:::1;76705:14;48765:19:::0;;;48693:99;76705:14:::1;:23;;;;:::i;:::-;:38;;76697:69;;;::::0;-1:-1:-1;;;76697:69:0;;24158:2:1;76697:69:0::1;::::0;::::1;24140:21:1::0;24197:2;24177:18;;;24170:30;24236:20;24216:18;;;24209:48;24274:18;;76697:69:0::1;23956:342:1::0;76697:69:0::1;76771:40;76804:6;76787:14;48765:19:::0;;;48693:99;76787:14:::1;:23;;;;:::i;:::-;3507:19:::0;:34;3440:109;76771:40:::1;76816:24;76822:9;76833:6;76816:5;:24::i;:::-;76626:219:::0;;:::o;31768:103::-;31006:13;:11;:13::i;:::-;31833:30:::1;31860:1;31833:18;:30::i;:::-;31768:103::o:0;54065:456::-;54278:18;52850:7;31193:6;;-1:-1:-1;;;;;31193:6:0;;31120:87;52850:7;-1:-1:-1;;;;;52834:23:0;29774:10;-1:-1:-1;;;;;52834:23:0;;52830:882;;;54335:13:::1;:20;54317:7;:14;:38;54309:64;;;::::0;-1:-1:-1;;;54309:64:0;;24505:2:1;54309:64:0::1;::::0;::::1;24487:21:1::0;24544:2;24524:18;;;24517:30;24583:15;24563:18;;;24556:43;24616:18;;54309:64:0::1;24303:337:1::0;54309:64:0::1;54389:9;54384:130;54408:13;:20;54404:1;:24;54384:130;;;54450:52;54473:7;54481:1;54473:10;;;;;;;;:::i;:::-;;;;;;;54485:13;54499:1;54485:16;;;;;;;;:::i;:::-;;;;;;;2679:36:::0;;;;:6;:36;;;:27;:36;;;;;:52;2588:151;54450:52:::1;54430:3:::0;::::1;::::0;::::1;:::i;:::-;;;;54384:130;;;;52830:882:::0;;;52908:23;52934:169;53010:18;:28;;;53040:18;:28;;;52993:76;;;;;;;;15113:2:1;15109:15;;;;15126:66;15105:88;15093:101;;15219:2;15210:12;;15203:28;15256:2;15247:12;;14936:329;52934:169:0;53126:28;;52908:195;;-1:-1:-1;;;;;;53126:44:0;29774:10;53126:44;53118:80;;;;-1:-1:-1;;;53118:80:0;;15472:2:1;53118:80:0;;;15454:21:1;15511:2;15491:18;;;15484:30;15550:25;15530:18;;;15523:53;15593:18;;53118:80:0;15270:347:1;53118:80:0;53252:15;53221:18;:28;;;:46;53213:85;;;;-1:-1:-1;;;53213:85:0;;15824:2:1;53213:85:0;;;15806:21:1;15863:2;15843:18;;;15836:30;15902:28;15882:18;;;15875:56;15948:18;;53213:85:0;15622:350:1;53213:85:0;53339:45;53355:18;:28;;;53339:15;:45::i;:::-;:54;53313:140;;;;-1:-1:-1;;;53313:140:0;;16179:2:1;53313:140:0;;;16161:21:1;16218:2;16198:18;;;16191:30;16257:26;16237:18;;;16230:54;16301:18;;53313:140:0;15977:348:1;53313:140:0;53468:46;53485:18;:28;;;53468:16;:46::i;:::-;53555:71;53571:15;53588:18;:28;;;53618:7;31193:6;;-1:-1:-1;;;;;31193:6:0;;31120:87;53555:71;53529:155;;;;-1:-1:-1;;;53529:155:0;;16532:2:1;53529:155:0;;;16514:21:1;16571:2;16551:18;;;16544:30;16610:24;16590:18;;;16583:52;16652:18;;53529:155:0;16330:346:1;53529:155:0;54335:13:::1;:20;54317:7;:14;:38;54309:64;;;::::0;-1:-1:-1;;;54309:64:0;;24505:2:1;54309:64:0::1;::::0;::::1;24487:21:1::0;24544:2;24524:18;;;24517:30;24583:15;24563:18;;;24556:43;24616:18;;54309:64:0::1;24303:337:1::0;54309:64:0::1;54389:9;54384:130;54408:13;:20;54404:1;:24;54384:130;;;54450:52;54473:7;54481:1;54473:10;;;;;;;;:::i;:::-;;;;;;;54485:13;54499:1;54485:16;;;;;;;;:::i;54450:52::-;54430:3:::0;::::1;::::0;::::1;:::i;:::-;;;;54384:130;;;;52893:819:::0;54065:456;;;;:::o;50152:391::-;50264:20;50338:8;:15;;;50368:8;:21;;;50404:8;:19;;;50438:8;:18;;;50471:8;:16;;;50502:8;:22;;;50307:228;;;;;;;;;;;;25295:19:1;;;25339:2;25330:12;;25323:28;;;;25474:3;25470:16;;;25370:66;25466:25;;;25461:2;25452:12;;25445:47;25517:2;25508:12;;25501:28;;;;25563:16;;;25559:25;25554:2;25545:12;;25538:47;25624:3;25620:16;25638:66;25616:89;25610:3;25601:13;;25594:112;25731:3;25722:13;;25034:707;50307:228:0;;;;;;;;;;;;;50297:238;;50152:391;;;:::o;57862:104::-;57918:13;57951:7;57944:14;;;;;:::i;62220:436::-;29774:10;62313:4;59639:18;;;:11;:18;;;;;;;;-1:-1:-1;;;;;59639:27:0;;;;;;;;;;62313:4;;29774:10;62460:15;62440:16;:35;;62432:85;;;;-1:-1:-1;;;62432:85:0;;25948:2:1;62432:85:0;;;25930:21:1;25987:2;25967:18;;;25960:30;26026:34;26006:18;;;25999:62;26097:7;26077:18;;;26070:35;26122:19;;62432:85:0;25746:401:1;62432:85:0;62553:60;62562:5;62569:7;62597:15;62578:16;:34;62553:8;:60::i;:::-;-1:-1:-1;62644:4:0;;62220:436;-1:-1:-1;;;;62220:436:0:o;59267:193::-;59346:4;29774:10;59402:28;29774:10;59419:2;59423:6;59402:9;:28::i;49840:177::-;49896:7;49924:15;;;;49916:47;;;;-1:-1:-1;;;49916:47:0;;26354:2:1;49916:47:0;;;26336:21:1;26393:2;26373:18;;;26366:30;26432:21;26412:18;;;26405:49;26471:18;;49916:47:0;26152:343:1;49916:47:0;-1:-1:-1;50005:1:0;49840:177::o;50551:708::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50741:24:0;:7;-1:-1:-1;50741:17:0;:24::i;:::-;50723:42;;50776:11;50785:2;50776:11;;:::i;:::-;;-1:-1:-1;50824:24:0;:7;50776:11;50824:17;:24::i;:::-;50800:21;;;;:48;;;;50859:11;;;;:::i;:::-;;-1:-1:-1;50905:23:0;:7;50859:11;50905:16;:23::i;:::-;50883:45;;:19;;;:45;50939:10;50948:1;50939:10;;:::i;:::-;;-1:-1:-1;50983:24:0;:7;50939:10;50983:17;:24::i;:::-;50962:18;;;:45;51018:11;51027:2;51018:11;;:::i;:::-;;-1:-1:-1;51061:23:0;:7;51018:11;51061:16;:23::i;:::-;51042:42;;:16;;;:42;51095:10;51104:1;51095:10;;:::i;:::-;;-1:-1:-1;51143:22:0;:7;51095:10;51143:15;:22::i;:::-;51118:47;;:22;;;:47;51176:10;51185:1;51176:10;;:::i;:::-;;;51225:5;51207:7;:14;:23;51199:52;;;;-1:-1:-1;;;51199:52:0;;26702:2:1;51199:52:0;;;26684:21:1;26741:2;26721:18;;;26714:30;26780:18;26760;;;26753:46;26816:18;;51199:52:0;26500:340:1;51199:52:0;50685:574;50551:708;;;:::o;32026:201::-;31006:13;:11;:13::i;:::-;-1:-1:-1;;;;;32115:22:0;::::1;32107:73;;;::::0;-1:-1:-1;;;32107:73:0;;27047:2:1;32107:73:0::1;::::0;::::1;27029:21:1::0;27086:2;27066:18;;;27059:30;27125:34;27105:18;;;27098:62;27196:8;27176:18;;;27169:36;27222:19;;32107:73:0::1;26845:402:1::0;32107:73:0::1;32191:28;32210:8;32191:18;:28::i;:::-;32026:201:::0;:::o;74385:1070::-;48998:20;;74518:15;;48998:20;;;;;74548:23;;74567:4;74548:23;74540:51;;;;-1:-1:-1;;;74540:51:0;;16883:2:1;74540:51:0;;;16865:21:1;16922:2;16902:18;;;16895:30;16961:17;16941:18;;;16934:45;16996:18;;74540:51:0;16681:339:1;74540:51:0;74620:13;74604:12;48211:17;;;48141:95;74604:12;:29;74596:58;;;;-1:-1:-1;;;74596:58:0;;17227:2:1;74596:58:0;;;17209:21:1;17266:2;17246:18;;;17239:30;17305:18;17285;;;17278:46;17341:18;;74596:58:0;17025:340:1;74596:58:0;74663:11;74677:10;48004:15;;-1:-1:-1;;;;;48004:15:0;;47924:104;74677:10;-1:-1:-1;;;;;74677:21:0;;:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;74663:37;;74726:3;74713:9;:16;;74705:71;;;;-1:-1:-1;;;74705:71:0;;27643:2:1;74705:71:0;;;27625:21:1;27682:2;27662:18;;;27655:30;27721:34;27701:18;;;27694:62;27792:12;27772:18;;;27765:40;27822:19;;74705:71:0;27441:406:1;74705:71:0;74781:17;74801:10;48004:15;;-1:-1:-1;;;;;48004:15:0;;47924:104;74801:10;-1:-1:-1;;;;;74801:18:0;;:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;74781:40;-1:-1:-1;74881:4:0;74898:27;29774:10;74918:6;74898:5;:27::i;:::-;74934:49;74986:209;;;;;;;;75034:6;74986:209;;;;75060:12;74986:209;;;;75090:10;74986:209;;;;;;75117:9;74986:209;;;;75141:14;74986:209;;;;;;75176:13;48561:15;;;;;;;;;48492:92;75176:13;74986:209;;;;74934:261;-1:-1:-1;75215:10:0;48004:15;;-1:-1:-1;;;;;48004:15:0;;47924:104;75215:10;-1:-1:-1;;;;;75215:25:0;;75248:9;75264:5;75275:24;75290:8;75275:14;:24::i;:::-;48427:5;48452:24;;;;;;75215:105;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;75204:116;-1:-1:-1;75436:9:0;75402:28;29774:10;75417:12;29694:98;75402:28;75334:116;;;23121:25:1;;;23165:6;23207:15;;;23202:2;23187:18;;23180:43;23259:15;;23239:18;;;23232:43;75334:116:0;;;;;;;23109:2:1;75334:116:0;;;74535:920;;;;74385:1070;;;;;;:::o;66247:380::-;-1:-1:-1;;;;;66383:19:0;;66375:68;;;;-1:-1:-1;;;66375:68:0;;28652:2:1;66375:68:0;;;28634:21:1;28691:2;28671:18;;;28664:30;28730:34;28710:18;;;28703:62;28801:6;28781:18;;;28774:34;28825:19;;66375:68:0;28450:400:1;66375:68:0;-1:-1:-1;;;;;66462:21:0;;66454:68;;;;-1:-1:-1;;;66454:68:0;;29057:2:1;66454:68:0;;;29039:21:1;29096:2;29076:18;;;29069:30;29135:34;29115:18;;;29108:62;29206:4;29186:18;;;29179:32;29228:19;;66454:68:0;28855:398:1;66454:68:0;-1:-1:-1;;;;;66535:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;66587:32;;4047:25:1;;;66587:32:0;;4020:18:1;66587:32:0;;;;;;;66247:380;;;:::o;66918:453::-;-1:-1:-1;;;;;59639:18:0;;;67053:24;59639:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;67140:17;67120:37;;67116:248;;67202:6;67182:16;:26;;67174:68;;;;-1:-1:-1;;;67174:68:0;;29460:2:1;67174:68:0;;;29442:21:1;29499:2;29479:18;;;29472:30;29538:31;29518:18;;;29511:59;29587:18;;67174:68:0;29258:353:1;67174:68:0;67286:51;67295:5;67302:7;67330:6;67311:16;:25;67286:8;:51::i;63126:840::-;-1:-1:-1;;;;;63257:18:0;;63249:68;;;;-1:-1:-1;;;63249:68:0;;29818:2:1;63249:68:0;;;29800:21:1;29857:2;29837:18;;;29830:30;29896:34;29876:18;;;29869:62;29967:7;29947:18;;;29940:35;29992:19;;63249:68:0;29616:401:1;63249:68:0;-1:-1:-1;;;;;63336:16:0;;63328:64;;;;-1:-1:-1;;;63328:64:0;;30224:2:1;63328:64:0;;;30206:21:1;30263:2;30243:18;;;30236:30;30302:34;30282:18;;;30275:62;30373:5;30353:18;;;30346:33;30396:19;;63328:64:0;30022:399:1;63328:64:0;-1:-1:-1;;;;;63478:15:0;;63456:19;63478:15;;;:9;:15;;;;;;63512:21;;;;63504:72;;;;-1:-1:-1;;;63504:72:0;;30628:2:1;63504:72:0;;;30610:21:1;30667:2;30647:18;;;30640:30;30706:34;30686:18;;;30679:62;30777:8;30757:18;;;30750:36;30803:19;;63504:72:0;30426:402:1;63504:72:0;-1:-1:-1;;;;;63612:15:0;;;;;;;:9;:15;;;;;;63630:20;;;63612:38;;63830:13;;;;;;;;;;:23;;;;;;63882:26;;;;;;63644:6;4047:25:1;;4035:2;4020:18;;3901:177;63882:26:0;;;;;;;;63921:37;54580:223;3761:117;3866:4;3831:6;:21;;3853:9;3831:32;;;;;;:::i;:::-;;;;;;;;;;;;;;:39;;;;;;;;;;;;;;;-1:-1:-1;3761:117:0:o;52213:405::-;52355:4;52373:7;52382:9;52393;52406:25;52421:9;52406:14;:25::i;:::-;52372:59;;;;;;52442:17;52462:27;52472:7;52481:1;52484;52487;52462:27;;;;;;;;;;;;;;;;;31445:25:1;;;31518:4;31506:17;;;;31501:2;31486:18;;31479:45;31555:2;31540:18;;31533:34;31598:2;31583:18;;31576:34;31432:3;31417:19;;31218:398;52462:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52442:47;;52517:9;-1:-1:-1;;;;;52504:22:0;:9;-1:-1:-1;;;;;52504:22:0;;52500:111;;;52550:4;52543:11;;;;;;;;52500:111;52594:5;52587:12;;;;;;;;49176:429;49318:7;49360:13;49342:31;;:15;:31;;;49338:113;;;49407:31;49425:13;49407:15;:31;:::i;:::-;49400:39;;:2;:39;:::i;:::-;49390:49;;;;:::i;:::-;;;49338:113;49481:15;49465:31;;:13;:31;;;49461:113;;;49530:31;49546:15;49530:13;:31;:::i;:::-;49523:39;;:2;:39;:::i;:::-;49513:49;;;;:::i;:::-;;;49461:113;-1:-1:-1;49591:6:0;;49176:429;-1:-1:-1;;49176:429:0:o;64253:548::-;-1:-1:-1;;;;;64337:21:0;;64329:65;;;;-1:-1:-1;;;64329:65:0;;34038:2:1;64329:65:0;;;34020:21:1;34077:2;34057:18;;;34050:30;34116:33;34096:18;;;34089:61;34167:18;;64329:65:0;33836:355:1;64329:65:0;64485:6;64469:12;;:22;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;64640:18:0;;;;;;:9;:18;;;;;;;;:28;;;;;;64695:37;4047:25:1;;;64695:37:0;;4020:18:1;64695:37:0;;;;;;;76626:219;;:::o;31285:132::-;31193:6;;-1:-1:-1;;;;;31193:6:0;29774:10;31349:23;31341:68;;;;-1:-1:-1;;;31341:68:0;;34398:2:1;31341:68:0;;;34380:21:1;;;34417:18;;;34410:30;34476:34;34456:18;;;34449:62;34528:18;;31341:68:0;34196:356:1;32387:191:0;32480:6;;;-1:-1:-1;;;;;32497:17:0;;;;;;;;;;;32530:40;;32480:6;;;32497:17;32480:6;;32530:40;;32461:16;;32530:40;32450:128;32387:191;:::o;18749:320::-;18828:7;18873:11;:6;18882:2;18873:11;:::i;:::-;18856:6;:13;:28;;18848:62;;;;-1:-1:-1;;;18848:62:0;;34759:2:1;18848:62:0;;;34741:21:1;34798:2;34778:18;;;34771:30;34837:23;34817:18;;;34810:51;34878:18;;18848:62:0;34557:345:1;18848:62:0;-1:-1:-1;18992:30:0;19008:4;18992:30;18986:37;;18749:320::o;19077:329::-;19156:7;19201:11;:6;19210:2;19201:11;:::i;:::-;19184:6;:13;:28;;19176:62;;;;-1:-1:-1;;;19176:62:0;;35109:2:1;19176:62:0;;;35091:21:1;35148:2;35128:18;;;35121:30;35187:23;35167:18;;;35160:51;35228:18;;19176:62:0;34907:345:1;17132:314:0;17210:6;17254:10;:6;17263:1;17254:10;:::i;:::-;17237:6;:13;:27;;17229:60;;;;-1:-1:-1;;;17229:60:0;;35459:2:1;17229:60:0;;;35441:21:1;35498:2;35478:18;;;35471:30;35537:22;35517:18;;;35510:50;35577:18;;17229:60:0;35257:344:1;17229:60:0;-1:-1:-1;17370:29:0;17386:3;17370:29;17364:36;;17132:314::o;16813:311::-;16890:5;16933:10;:6;16942:1;16933:10;:::i;:::-;16916:6;:13;:27;;16908:60;;;;-1:-1:-1;;;16908:60:0;;35808:2:1;16908:60:0;;;35790:21:1;35847:2;35827:18;;;35820:30;35886:21;35866:18;;;35859:49;35925:18;;16908:60:0;35606:343:1;16908:60:0;-1:-1:-1;17048:29:0;17064:3;17048:29;17042:36;;16813:311::o;65134:675::-;-1:-1:-1;;;;;65218:21:0;;65210:67;;;;-1:-1:-1;;;65210:67:0;;36156:2:1;65210:67:0;;;36138:21:1;36195:2;36175:18;;;36168:30;36234:34;36214:18;;;36207:62;36305:3;36285:18;;;36278:31;36326:19;;65210:67:0;35954:397:1;65210:67:0;-1:-1:-1;;;;;65377:18:0;;65352:22;65377:18;;;:9;:18;;;;;;65414:24;;;;65406:71;;;;-1:-1:-1;;;65406:71:0;;36558:2:1;65406:71:0;;;36540:21:1;36597:2;36577:18;;;36570:30;36636:34;36616:18;;;36609:62;36707:4;36687:18;;;36680:32;36729:19;;65406:71:0;36356:398:1;65406:71:0;-1:-1:-1;;;;;65513:18:0;;;;;;:9;:18;;;;;;;;65534:23;;;65513:44;;65652:12;:22;;;;;;;65703:37;4047:25:1;;;65513:18:0;;;65703:37;;4020:18:1;65703:37:0;;;;;;;54580:223;;;:::o;51712:493::-;51793:7;51802:9;51813;51843:3;:10;51857:2;51843:16;51835:25;;;;;;-1:-1:-1;;;51974:2:0;51965:12;;51959:19;52045:2;52036:12;;52030:19;52153:2;52144:12;;;52138:19;52135:1;52130:28;;51959:19;;52030;51712:493::o;14:332:1:-;72:6;125:2;113:9;104:7;100:23;96:32;93:52;;;141:1;138;131:12;93:52;180:9;167:23;230:66;223:5;219:78;212:5;209:89;199:117;;312:1;309;302:12;543:258;615:1;625:113;639:6;636:1;633:13;625:113;;;715:11;;;709:18;696:11;;;689:39;661:2;654:10;625:113;;;756:6;753:1;750:13;747:48;;;-1:-1:-1;;791:1:1;773:16;;766:27;543:258::o;806:317::-;848:3;886:5;880:12;913:6;908:3;901:19;929:63;985:6;978:4;973:3;969:14;962:4;955:5;951:16;929:63;:::i;:::-;1037:2;1025:15;1042:66;1021:88;1012:98;;;;1112:4;1008:109;;806:317;-1:-1:-1;;806:317:1:o;1128:220::-;1277:2;1266:9;1259:21;1240:4;1297:45;1338:2;1327:9;1323:18;1315:6;1297:45;:::i;1353:196::-;1421:20;;-1:-1:-1;;;;;1470:54:1;;1460:65;;1450:93;;1539:1;1536;1529:12;1450:93;1353:196;;;:::o;1554:254::-;1622:6;1630;1683:2;1671:9;1662:7;1658:23;1654:32;1651:52;;;1699:1;1696;1689:12;1651:52;1722:29;1741:9;1722:29;:::i;:::-;1712:39;1798:2;1783:18;;;;1770:32;;-1:-1:-1;;;1554:254:1:o;1813:184::-;1865:77;1862:1;1855:88;1962:4;1959:1;1952:15;1986:4;1983:1;1976:15;2002:253;2074:2;2068:9;2116:4;2104:17;;2151:18;2136:34;;2172:22;;;2133:62;2130:88;;;2198:18;;:::i;:::-;2234:2;2227:22;2002:253;:::o;2260:255::-;2332:2;2326:9;2374:6;2362:19;;2411:18;2396:34;;2432:22;;;2393:62;2390:88;;;2458:18;;:::i;2520:334::-;2591:2;2585:9;2647:2;2637:13;;2652:66;2633:86;2621:99;;2750:18;2735:34;;2771:22;;;2732:62;2729:88;;;2797:18;;:::i;:::-;2833:2;2826:22;2520:334;;-1:-1:-1;2520:334:1:o;2859:245::-;2907:4;2940:18;2932:6;2929:30;2926:56;;;2962:18;;:::i;:::-;-1:-1:-1;3019:2:1;3007:15;3024:66;3003:88;3093:4;2999:99;;2859:245::o;3109:462::-;3151:5;3204:3;3197:4;3189:6;3185:17;3181:27;3171:55;;3222:1;3219;3212:12;3171:55;3258:6;3245:20;3289:48;3305:31;3333:2;3305:31;:::i;:::-;3289:48;:::i;:::-;3362:2;3353:7;3346:19;3408:3;3401:4;3396:2;3388:6;3384:15;3380:26;3377:35;3374:55;;;3425:1;3422;3415:12;3374:55;3490:2;3483:4;3475:6;3471:17;3464:4;3455:7;3451:18;3438:55;3538:1;3513:16;;;3531:4;3509:27;3502:38;;;;3517:7;3109:462;-1:-1:-1;;;3109:462:1:o;3576:320::-;3644:6;3697:2;3685:9;3676:7;3672:23;3668:32;3665:52;;;3713:1;3710;3703:12;3665:52;3753:9;3740:23;3786:18;3778:6;3775:30;3772:50;;;3818:1;3815;3808:12;3772:50;3841:49;3882:7;3873:6;3862:9;3858:22;3841:49;:::i;:::-;3831:59;3576:320;-1:-1:-1;;;;3576:320:1:o;4083:328::-;4160:6;4168;4176;4229:2;4217:9;4208:7;4204:23;4200:32;4197:52;;;4245:1;4242;4235:12;4197:52;4268:29;4287:9;4268:29;:::i;:::-;4258:39;;4316:38;4350:2;4339:9;4335:18;4316:38;:::i;:::-;4306:48;;4401:2;4390:9;4386:18;4373:32;4363:42;;4083:328;;;;;:::o;4416:114::-;4500:4;4493:5;4489:16;4482:5;4479:27;4469:55;;4520:1;4517;4510:12;4535:690;4603:5;4651:4;4639:9;4634:3;4630:19;4626:30;4623:50;;;4669:1;4666;4659:12;4623:50;4702:2;4696:9;4744:4;4736:6;4732:17;4768:18;4836:6;4824:10;4821:22;4816:2;4804:10;4801:18;4798:46;4795:72;;;4847:18;;:::i;:::-;4887:10;4883:2;4876:22;4916:6;4907:15;;4946:29;4965:9;4946:29;:::i;:::-;4938:6;4931:45;5037:2;5026:9;5022:18;5009:32;5004:2;4996:6;4992:15;4985:57;5093:2;5082:9;5078:18;5065:32;5051:46;;5120:2;5112:6;5109:14;5106:34;;;5136:1;5133;5126:12;5106:34;;5173:45;5214:3;5205:6;5194:9;5190:22;5173:45;:::i;:::-;5168:2;5160:6;5156:15;5149:70;;;4535:690;;;;:::o;5230:502::-;5333:6;5341;5394:2;5382:9;5373:7;5369:23;5365:32;5362:52;;;5410:1;5407;5400:12;5362:52;5449:9;5436:23;5468:29;5491:5;5468:29;:::i;:::-;5516:5;-1:-1:-1;5572:2:1;5557:18;;5544:32;5599:18;5588:30;;5585:50;;;5631:1;5628;5621:12;5585:50;5654:72;5718:7;5709:6;5698:9;5694:22;5654:72;:::i;:::-;5644:82;;;5230:502;;;;;:::o;5737:117::-;5822:6;5815:5;5811:18;5804:5;5801:29;5791:57;;5844:1;5841;5834:12;5859:572;5972:6;5980;5988;6041:2;6029:9;6020:7;6016:23;6012:32;6009:52;;;6057:1;6054;6047:12;6009:52;6096:9;6083:23;6115:30;6139:5;6115:30;:::i;:::-;6164:5;-1:-1:-1;6216:2:1;6201:18;;6188:32;;-1:-1:-1;6271:2:1;6256:18;;6243:32;6298:18;6287:30;;6284:50;;;6330:1;6327;6320:12;6284:50;6353:72;6417:7;6408:6;6397:9;6393:22;6353:72;:::i;:::-;6343:82;;;5859:572;;;;;:::o;6848:525::-;6931:6;6939;6947;6955;7008:3;6996:9;6987:7;6983:23;6979:33;6976:53;;;7025:1;7022;7015:12;6976:53;7064:9;7051:23;7083:30;7107:5;7083:30;:::i;:::-;7132:5;-1:-1:-1;7156:38:1;7190:2;7175:18;;7156:38;:::i;:::-;7146:48;;7246:2;7235:9;7231:18;7218:32;7259:31;7282:7;7259:31;:::i;:::-;6848:525;;;;-1:-1:-1;7309:7:1;;7363:2;7348:18;7335:32;;-1:-1:-1;;6848:525:1:o;7378:186::-;7437:6;7490:2;7478:9;7469:7;7465:23;7461:32;7458:52;;;7506:1;7503;7496:12;7458:52;7529:29;7548:9;7529:29;:::i;7823:182::-;7882:4;7915:18;7907:6;7904:30;7901:56;;;7937:18;;:::i;:::-;-1:-1:-1;7982:1:1;7978:14;7994:4;7974:25;;7823:182::o;8010:661::-;8064:5;8117:3;8110:4;8102:6;8098:17;8094:27;8084:55;;8135:1;8132;8125:12;8084:55;8171:6;8158:20;8197:4;8221:59;8237:42;8276:2;8237:42;:::i;8221:59::-;8314:15;;;8400:1;8396:10;;;;8384:23;;8380:32;;;8345:12;;;;8424:15;;;8421:35;;;8452:1;8449;8442:12;8421:35;8488:2;8480:6;8476:15;8500:142;8516:6;8511:3;8508:15;8500:142;;;8582:17;;8570:30;;8620:12;;;;8533;;8500:142;;;-1:-1:-1;8660:5:1;8010:661;-1:-1:-1;;;;;;8010:661:1:o;8676:1461::-;8839:6;8847;8855;8908:2;8896:9;8887:7;8883:23;8879:32;8876:52;;;8924:1;8921;8914:12;8876:52;8964:9;8951:23;8993:18;9034:2;9026:6;9023:14;9020:34;;;9050:1;9047;9040:12;9020:34;9088:6;9077:9;9073:22;9063:32;;9133:7;9126:4;9122:2;9118:13;9114:27;9104:55;;9155:1;9152;9145:12;9104:55;9191:2;9178:16;9213:4;9237:59;9253:42;9292:2;9253:42;:::i;9237:59::-;9330:15;;;9412:1;9408:10;;;;9400:19;;9396:28;;;9361:12;;;;9436:19;;;9433:39;;;9468:1;9465;9458:12;9433:39;9492:11;;;;9512:216;9528:6;9523:3;9520:15;9512:216;;;9608:3;9595:17;9625:30;9649:5;9625:30;:::i;:::-;9668:18;;9545:12;;;;9706;;;;9512:216;;;9747:5;-1:-1:-1;;9790:18:1;;9777:32;;-1:-1:-1;;9821:16:1;;;9818:36;;;9850:1;9847;9840:12;9818:36;9873:63;9928:7;9917:8;9906:9;9902:24;9873:63;:::i;:::-;9863:73;;9989:2;9978:9;9974:18;9961:32;9945:48;;10018:2;10008:8;10005:16;10002:36;;;10034:1;10031;10024:12;10002:36;;10057:74;10123:7;10112:8;10101:9;10097:24;10057:74;:::i;10390:991::-;10482:6;10535:3;10523:9;10514:7;10510:23;10506:33;10503:53;;;10552:1;10549;10542:12;10503:53;10585:2;10579:9;10627:3;10619:6;10615:16;10697:6;10685:10;10682:22;10661:18;10649:10;10646:34;10643:62;10640:88;;;10708:18;;:::i;:::-;10748:10;10744:2;10737:22;;10796:9;10783:23;10775:6;10768:39;10868:2;10857:9;10853:18;10840:32;10835:2;10827:6;10823:15;10816:57;10923:2;10912:9;10908:18;10895:32;10936:30;10960:5;10936:30;:::i;:::-;10994:2;10982:15;;10975:30;11066:2;11051:18;;;11038:32;11021:15;;;11014:57;11123:3;11108:19;;11095:33;11137:32;11095:33;11137:32;:::i;:::-;11197:3;11185:16;;11178:33;11263:3;11248:19;;11235:33;11277:31;11235:33;11277:31;:::i;:::-;11336:3;11324:16;;11317:33;11328:6;10390:991;-1:-1:-1;;;10390:991:1:o;11810:180::-;11869:6;11922:2;11910:9;11901:7;11897:23;11893:32;11890:52;;;11938:1;11935;11928:12;11890:52;-1:-1:-1;11961:23:1;;11810:180;-1:-1:-1;11810:180:1:o;12661:260::-;12729:6;12737;12790:2;12778:9;12769:7;12765:23;12761:32;12758:52;;;12806:1;12803;12796:12;12758:52;12829:29;12848:9;12829:29;:::i;:::-;12819:39;;12877:38;12911:2;12900:9;12896:18;12877:38;:::i;:::-;12867:48;;12661:260;;;;;:::o;13108:245::-;13166:6;13219:2;13207:9;13198:7;13194:23;13190:32;13187:52;;;13235:1;13232;13225:12;13187:52;13274:9;13261:23;13293:30;13317:5;13293:30;:::i;13358:121::-;13443:10;13436:5;13432:22;13425:5;13422:33;13412:61;;13469:1;13466;13459:12;13484:521;13568:6;13576;13584;13592;13645:3;13633:9;13624:7;13620:23;13616:33;13613:53;;;13662:1;13659;13652:12;13613:53;13698:9;13685:23;13675:33;;13758:2;13747:9;13743:18;13730:32;13771:30;13795:5;13771:30;:::i;:::-;13820:5;-1:-1:-1;13872:2:1;13857:18;;13844:32;;-1:-1:-1;13928:2:1;13913:18;;13900:32;13941;13900;13941;:::i;:::-;13484:521;;;;-1:-1:-1;13484:521:1;;-1:-1:-1;;13484:521:1:o;14215:437::-;14294:1;14290:12;;;;14337;;;14358:61;;14412:4;14404:6;14400:17;14390:27;;14358:61;14465:2;14457:6;14454:14;14434:18;14431:38;14428:218;;;14502:77;14499:1;14492:88;14603:4;14600:1;14593:15;14631:4;14628:1;14621:15;14657:274;14786:3;14824:6;14818:13;14840:53;14886:6;14881:3;14874:4;14866:6;14862:17;14840:53;:::i;:::-;14909:16;;;;;14657:274;-1:-1:-1;;14657:274:1:o;17370:134::-;17447:13;;17469:29;17447:13;17469:29;:::i;17509:136::-;17587:13;;17609:30;17587:13;17609:30;:::i;17650:136::-;17728:13;;17750:30;17728:13;17750:30;:::i;17791:175::-;17869:13;;17922:18;17911:30;;17901:41;;17891:69;;17956:1;17953;17946:12;17971:428;18024:5;18077:3;18070:4;18062:6;18058:17;18054:27;18044:55;;18095:1;18092;18085:12;18044:55;18124:6;18118:13;18155:48;18171:31;18199:2;18171:31;:::i;18155:48::-;18228:2;18219:7;18212:19;18274:3;18267:4;18262:2;18254:6;18250:15;18246:26;18243:35;18240:55;;;18291:1;18288;18281:12;18240:55;18304:64;18365:2;18358:4;18349:7;18345:18;18338:4;18330:6;18326:17;18304:64;:::i;18404:1253::-;18478:5;18531:3;18524:4;18516:6;18512:17;18508:27;18498:55;;18549:1;18546;18539:12;18498:55;18578:6;18572:13;18604:4;18628:59;18644:42;18683:2;18644:42;:::i;18628:59::-;18721:15;;;18807:1;18803:10;;;;18791:23;;18787:32;;;18752:12;;;;18831:15;;;18828:35;;;18859:1;18856;18849:12;18828:35;18895:2;18887:6;18883:15;18907:721;18923:6;18918:3;18915:15;18907:721;;;19001:4;18995:3;18990;18986:13;18982:24;18979:114;;;19047:1;19076:2;19072;19065:14;18979:114;19119:22;;:::i;:::-;19174:3;19168:10;19161:5;19154:25;19230:2;19225:3;19221:12;19215:19;19210:2;19203:5;19199:14;19192:43;19258:2;19303;19298:3;19294:12;19288:19;19320:31;19343:7;19320:31;:::i;:::-;19371:14;;;19364:31;19418:2;19454:12;;;19448:19;19480:31;19448:19;19480:31;:::i;:::-;19531:14;;;19524:31;19568:18;;19606:12;;;;18949:4;18940:14;18907:721;;19662:164;19738:13;;19787;;19780:21;19770:32;;19760:60;;19816:1;19813;19806:12;19831:1783;19945:6;19953;19961;20014:2;20002:9;19993:7;19989:23;19985:32;19982:52;;;20030:1;20027;20020:12;19982:52;20063:9;20057:16;20092:18;20133:2;20125:6;20122:14;20119:34;;;20149:1;20146;20139:12;20119:34;20172:22;;;;20228:6;20210:16;;;20206:29;20203:49;;;20248:1;20245;20238:12;20203:49;20274:22;;:::i;:::-;20319:31;20347:2;20319:31;:::i;:::-;20312:5;20305:46;20383:41;20420:2;20416;20412:11;20383:41;:::i;:::-;20378:2;20371:5;20367:14;20360:65;20457:41;20494:2;20490;20486:11;20457:41;:::i;:::-;20452:2;20445:5;20441:14;20434:65;20531:41;20568:2;20564;20560:11;20531:41;:::i;:::-;20526:2;20519:5;20515:14;20508:65;20620:3;20616:2;20612:12;20606:19;20600:3;20593:5;20589:15;20582:44;20659:42;20696:3;20692:2;20688:12;20659:42;:::i;:::-;20653:3;20646:5;20642:15;20635:67;20735:41;20771:3;20767:2;20763:12;20735:41;:::i;:::-;20729:3;20722:5;20718:15;20711:66;20816:3;20812:2;20808:12;20802:19;20846:2;20836:8;20833:16;20830:36;;;20862:1;20859;20852:12;20830:36;20899:55;20946:7;20935:8;20931:2;20927:17;20899:55;:::i;:::-;20893:3;20886:5;20882:15;20875:80;;20974:3;21009:41;21046:2;21042;21038:11;21009:41;:::i;:::-;20993:14;;;20986:65;21070:3;21104:11;;;21098:18;21128:16;;;21125:36;;;21157:1;21154;21147:12;21125:36;21193:76;21261:7;21250:8;21246:2;21242:17;21193:76;:::i;:::-;21177:14;;;21170:100;;;;-1:-1:-1;21289:3:1;21330:11;;;21324:18;21308:14;;;21301:42;21181:5;-1:-1:-1;21386:46:1;21428:2;21413:18;;21386:46;:::i;:::-;21376:56;;21478:2;21467:9;21463:18;21457:25;21441:41;;21507:2;21497:8;21494:16;21491:36;;;21523:1;21520;21513:12;21491:36;;21546:62;21600:7;21589:8;21578:9;21574:24;21546:62;:::i;22318:249::-;22387:6;22440:2;22428:9;22419:7;22415:23;22411:32;22408:52;;;22456:1;22453;22446:12;22408:52;22488:9;22482:16;22507:30;22531:5;22507:30;:::i;23286:184::-;23338:77;23335:1;23328:88;23435:4;23432:1;23425:15;23459:4;23456:1;23449:15;23475:128;23515:3;23546:1;23542:6;23539:1;23536:13;23533:39;;;23552:18;;:::i;:::-;-1:-1:-1;23588:9:1;;23475:128::o;24645:184::-;24697:77;24694:1;24687:88;24794:4;24791:1;24784:15;24818:4;24815:1;24808:15;24834:195;24873:3;24904:66;24897:5;24894:77;24891:103;;;24974:18;;:::i;:::-;-1:-1:-1;25021:1:1;25010:13;;24834:195::o;27252:184::-;27322:6;27375:2;27363:9;27354:7;27350:23;27346:32;27343:52;;;27391:1;27388;27381:12;27343:52;-1:-1:-1;27414:16:1;;27252:184;-1:-1:-1;27252:184:1:o;27852:382::-;28061:10;28053:6;28049:23;28038:9;28031:42;28109:2;28104;28093:9;28089:18;28082:30;28012:4;28129:45;28170:2;28159:9;28155:18;28147:6;28129:45;:::i;:::-;28121:53;;28222:4;28214:6;28210:17;28205:2;28194:9;28190:18;28183:45;27852:382;;;;;;:::o;28239:206::-;28308:6;28361:2;28349:9;28340:7;28336:23;28332:32;28329:52;;;28377:1;28374;28367:12;28329:52;28400:39;28429:9;28400:39;:::i;31621:195::-;31659:4;31696;31693:1;31689:12;31728:4;31725:1;31721:12;31753:3;31748;31745:12;31742:38;;;31760:18;;:::i;:::-;31797:13;;;31621:195;-1:-1:-1;;;31621:195:1:o;31821:482::-;31910:1;31953:5;31910:1;31967:330;31988:7;31978:8;31975:21;31967:330;;;32107:4;32039:66;32035:77;32029:4;32026:87;32023:113;;;32116:18;;:::i;:::-;32166:7;32156:8;32152:22;32149:55;;;32186:16;;;;32149:55;32265:22;;;;32225:15;;;;31967:330;;;31971:3;31821:482;;;;;:::o;32308:866::-;32357:5;32387:8;32377:80;;-1:-1:-1;32428:1:1;32442:5;;32377:80;32476:4;32466:76;;-1:-1:-1;32513:1:1;32527:5;;32466:76;32558:4;32576:1;32571:59;;;;32644:1;32639:130;;;;32551:218;;32571:59;32601:1;32592:10;;32615:5;;;32639:130;32676:3;32666:8;32663:17;32660:43;;;32683:18;;:::i;:::-;-1:-1:-1;;32739:1:1;32725:16;;32754:5;;32551:218;;32853:2;32843:8;32840:16;32834:3;32828:4;32825:13;32821:36;32815:2;32805:8;32802:16;32797:2;32791:4;32788:12;32784:35;32781:77;32778:159;;;-1:-1:-1;32890:19:1;;;32922:5;;32778:159;32969:34;32994:8;32988:4;32969:34;:::i;:::-;33099:6;33031:66;33027:79;33018:7;33015:92;33012:118;;;33110:18;;:::i;:::-;33148:20;;32308:866;-1:-1:-1;;;32308:866:1:o;33179:140::-;33237:5;33266:47;33307:4;33297:8;33293:19;33287:4;33266:47;:::i;33324:274::-;33364:1;33390;33380:189;;33425:77;33422:1;33415:88;33526:4;33523:1;33516:15;33554:4;33551:1;33544:15;33380:189;-1:-1:-1;33583:9:1;;33324:274::o;33603:228::-;33643:7;33769:1;33701:66;33697:74;33694:1;33691:81;33686:1;33679:9;33672:17;33668:105;33665:131;;;33776:18;;:::i;:::-;-1:-1:-1;33816:9:1;;33603:228::o

Swarm Source

ipfs://271164ad7854cff628789c8e146bdea5141c1f0afd8465b07e4edc084694ac57
Loading...
Loading
[ Download: CSV Export  ]
[ 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.