ETH Price: $3,104.96 (+0.04%)

Token

The Hall Pass (THP)
 

Overview

Max Total Supply

742 THP

Holders

737

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 THP
0x523d96c2c36085a00caffebdd2713508e7ea98b4
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
TheHallPass

Compiler Version
v0.8.12+commit.f00d7308

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2024-01-06
*/

// Sources flattened with hardhat v2.10.1 https://hardhat.org

// File @openzeppelin/contracts/utils/introspection/[email protected]

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

/**
 * @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 contracts/token/onft/IONFT721Core.sol

 

pragma solidity >=0.5.0;

/**
 * @dev Interface of the ONFT Core standard
 */
interface IONFT721Core is IERC165 {
    /**
     * @dev Emitted when `_tokenIds[]` are moved from the `_sender` to (`_dstChainId`, `_toAddress`)
     * `_nonce` is the outbound nonce from
     */
    event SendToChain(uint16 indexed _dstChainId, address indexed _from, bytes indexed _toAddress, uint[] _tokenIds);
    event ReceiveFromChain(uint16 indexed _srcChainId, bytes indexed _srcAddress, address indexed _toAddress, uint[] _tokenIds);

    /**
     * @dev Emitted when `_payload` was received from lz, but not enough gas to deliver all tokenIds
     */
    event CreditStored(bytes32 _hashedPayload, bytes _payload);
    /**
     * @dev Emitted when `_hashedPayload` has been completely delivered
     */
    event CreditCleared(bytes32 _hashedPayload);

    /**
     * @dev send token `_tokenId` to (`_dstChainId`, `_toAddress`) from `_from`
     * `_toAddress` can be any size depending on the `dstChainId`.
     * `_zroPaymentAddress` set to address(0x0) if not paying in ZRO (LayerZero Token)
     * `_adapterParams` is a flexible bytes array to indicate messaging adapter services
     */
    function sendFrom(address _from, uint16 _dstChainId, bytes calldata _toAddress, uint _tokenId, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams) external payable;
    /**
     * @dev send tokens `_tokenIds[]` to (`_dstChainId`, `_toAddress`) from `_from`
     * `_toAddress` can be any size depending on the `dstChainId`.
     * `_zroPaymentAddress` set to address(0x0) if not paying in ZRO (LayerZero Token)
     * `_adapterParams` is a flexible bytes array to indicate messaging adapter services
     */
    function sendBatchFrom(address _from, uint16 _dstChainId, bytes calldata _toAddress, uint[] calldata _tokenIds, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams) external payable;

    /**
     * @dev estimate send token `_tokenId` to (`_dstChainId`, `_toAddress`)
     * _dstChainId - L0 defined chain id to send tokens too
     * _toAddress - dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain
     * _tokenId - token Id to transfer
     * _useZro - indicates to use zro to pay L0 fees
     * _adapterParams - flexible bytes array to indicate messaging adapter services in L0
     */
    function estimateSendFee(uint16 _dstChainId, bytes calldata _toAddress, uint _tokenId, bool _useZro, bytes calldata _adapterParams) external view returns (uint nativeFee, uint zroFee);
    /**
     * @dev estimate send token `_tokenId` to (`_dstChainId`, `_toAddress`)
     * _dstChainId - L0 defined chain id to send tokens too
     * _toAddress - dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain
     * _tokenIds[] - token Ids to transfer
     * _useZro - indicates to use zro to pay L0 fees
     * _adapterParams - flexible bytes array to indicate messaging adapter services in L0
     */
    function estimateSendBatchFee(uint16 _dstChainId, bytes calldata _toAddress, uint[] calldata _tokenIds, bool _useZro, bytes calldata _adapterParams) external view returns (uint nativeFee, uint zroFee);
}


// File @openzeppelin/contracts/token/ERC721/[email protected]

 
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

/**
 * @dev Required interface of an ERC721 compliant contract.
 */
interface IERC721 is IERC165 {
    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables `approved` to manage the `tokenId` token.
     */
    event Approval(address indexed owner, address indexed approved, uint256 indexed tokenId);

    /**
     * @dev Emitted when `owner` enables or disables (`approved`) `operator` to manage all of its assets.
     */
    event ApprovalForAll(address indexed owner, address indexed operator, bool approved);

    /**
     * @dev Returns the number of tokens in ``owner``'s account.
     */
    function balanceOf(address owner) external view returns (uint256 balance);

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) external view returns (address owner);

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom} whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

    /**
     * @dev Gives permission to `to` to transfer `tokenId` token to another account.
     * The approval is cleared when the token is transferred.
     *
     * Only a single account can be approved at a time, so approving the zero address clears previous approvals.
     *
     * Requirements:
     *
     * - The caller must own the token or be an approved operator.
     * - `tokenId` must exist.
     *
     * Emits an {Approval} event.
     */
    function approve(address to, uint256 tokenId) external;

    /**
     * @dev Approve or remove `operator` as an operator for the caller.
     * Operators can call {transferFrom} or {safeTransferFrom} for any token owned by the caller.
     *
     * Requirements:
     *
     * - The `operator` cannot be the caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @dev Returns if the `operator` is allowed to manage all of the assets of `owner`.
     *
     * See {setApprovalForAll}
     */
    function isApprovedForAll(address owner, address operator) external view returns (bool);
}


// File contracts/token/onft/IONFT721.sol

 

pragma solidity >=0.5.0;


/**
 * @dev Interface of the ONFT standard
 */
interface IONFT721 is IONFT721Core, IERC721 {

}


// File @openzeppelin/contracts/utils/[email protected]

 
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with 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/[email protected]

 
// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

/**
 * @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 contracts/interfaces/ILayerZeroReceiver.sol

 

pragma solidity >=0.5.0;

interface ILayerZeroReceiver {
    // @notice LayerZero endpoint will invoke this function to deliver the message on the destination
    // @param _srcChainId - the source endpoint identifier
    // @param _srcAddress - the source sending contract address from the source chain
    // @param _nonce - the ordered message nonce
    // @param _payload - the signed payload is the UA bytes has encoded to be sent
    function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) external;
}


// File contracts/interfaces/ILayerZeroUserApplicationConfig.sol

 

pragma solidity >=0.5.0;

interface ILayerZeroUserApplicationConfig {
    // @notice set the configuration of the LayerZero messaging library of the specified version
    // @param _version - messaging library version
    // @param _chainId - the chainId for the pending config change
    // @param _configType - type of configuration. every messaging library has its own convention.
    // @param _config - configuration in the bytes. can encode arbitrary content.
    function setConfig(uint16 _version, uint16 _chainId, uint _configType, bytes calldata _config) external;

    // @notice set the send() LayerZero messaging library version to _version
    // @param _version - new messaging library version
    function setSendVersion(uint16 _version) external;

    // @notice set the lzReceive() LayerZero messaging library version to _version
    // @param _version - new messaging library version
    function setReceiveVersion(uint16 _version) external;

    // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload
    // @param _srcChainId - the chainId of the source chain
    // @param _srcAddress - the contract address of the source contract at the source chain
    function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external;
}


// File contracts/interfaces/ILayerZeroEndpoint.sol

 

pragma solidity >=0.5.0;

interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig {
    // @notice send a LayerZero message to the specified address at a LayerZero endpoint.
    // @param _dstChainId - the destination chain identifier
    // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains
    // @param _payload - a custom bytes payload to send to the destination contract
    // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address
    // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction
    // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination
    function send(uint16 _dstChainId, bytes calldata _destination, bytes calldata _payload, address payable _refundAddress, address _zroPaymentAddress, bytes calldata _adapterParams) external payable;

    // @notice used by the messaging library to publish verified payload
    // @param _srcChainId - the source chain identifier
    // @param _srcAddress - the source contract (as bytes) at the source chain
    // @param _dstAddress - the address on destination chain
    // @param _nonce - the unbound message ordering nonce
    // @param _gasLimit - the gas limit for external contract execution
    // @param _payload - verified payload to send to the destination contract
    function receivePayload(uint16 _srcChainId, bytes calldata _srcAddress, address _dstAddress, uint64 _nonce, uint _gasLimit, bytes calldata _payload) external;

    // @notice get the inboundNonce of a lzApp from a source chain which could be EVM or non-EVM chain
    // @param _srcChainId - the source chain identifier
    // @param _srcAddress - the source chain contract address
    function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64);

    // @notice get the outboundNonce from this source chain which, consequently, is always an EVM
    // @param _srcAddress - the source chain contract address
    function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64);

    // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery
    // @param _dstChainId - the destination chain identifier
    // @param _userApplication - the user app address on this EVM chain
    // @param _payload - the custom message to send over LayerZero
    // @param _payInZRO - if false, user app pays the protocol fee in native token
    // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain
    function estimateFees(uint16 _dstChainId, address _userApplication, bytes calldata _payload, bool _payInZRO, bytes calldata _adapterParam) external view returns (uint nativeFee, uint zroFee);

    // @notice get this Endpoint's immutable source identifier
    function getChainId() external view returns (uint16);

    // @notice the interface to retry failed message on this Endpoint destination
    // @param _srcChainId - the source chain identifier
    // @param _srcAddress - the source chain contract address
    // @param _payload - the payload to be retried
    function retryPayload(uint16 _srcChainId, bytes calldata _srcAddress, bytes calldata _payload) external;

    // @notice query if any STORED payload (message blocking) at the endpoint.
    // @param _srcChainId - the source chain identifier
    // @param _srcAddress - the source chain contract address
    function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool);

    // @notice query if the _libraryAddress is valid for sending msgs.
    // @param _userApplication - the user app address on this EVM chain
    function getSendLibraryAddress(address _userApplication) external view returns (address);

    // @notice query if the _libraryAddress is valid for receiving msgs.
    // @param _userApplication - the user app address on this EVM chain
    function getReceiveLibraryAddress(address _userApplication) external view returns (address);

    // @notice query if the non-reentrancy guard for send() is on
    // @return true if the guard is on. false otherwise
    function isSendingPayload() external view returns (bool);

    // @notice query if the non-reentrancy guard for receive() is on
    // @return true if the guard is on. false otherwise
    function isReceivingPayload() external view returns (bool);

    // @notice get the configuration of the LayerZero messaging library of the specified version
    // @param _version - messaging library version
    // @param _chainId - the chainId for the pending config change
    // @param _userApplication - the contract address of the user application
    // @param _configType - type of configuration. every messaging library has its own convention.
    function getConfig(uint16 _version, uint16 _chainId, address _userApplication, uint _configType) external view returns (bytes memory);

    // @notice get the send() LayerZero messaging library version
    // @param _userApplication - the contract address of the user application
    function getSendVersion(address _userApplication) external view returns (uint16);

    // @notice get the lzReceive() LayerZero messaging library version
    // @param _userApplication - the contract address of the user application
    function getReceiveVersion(address _userApplication) external view returns (uint16);
}


// File contracts/util/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.
 */
pragma solidity >=0.8.0 <0.9.0;


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/lzApp/LzApp.sol

 

pragma solidity ^0.8.0;





/*
 * a generic LzReceiver implementation
 */
abstract contract LzApp is Ownable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {
    using BytesLib for bytes;

    // ua can not send payload larger than this by default, but it can be changed by the ua owner
    uint constant public DEFAULT_PAYLOAD_SIZE_LIMIT = 10000;

    ILayerZeroEndpoint public immutable lzEndpoint;
    mapping(uint16 => bytes) public trustedRemoteLookup;
    mapping(uint16 => mapping(uint16 => uint)) public minDstGasLookup;
    mapping(uint16 => uint) public payloadSizeLimitLookup;
    address public precrime;

    event SetPrecrime(address precrime);
    event SetTrustedRemote(uint16 _remoteChainId, bytes _path);
    event SetTrustedRemoteAddress(uint16 _remoteChainId, bytes _remoteAddress);
    event SetMinDstGas(uint16 _dstChainId, uint16 _type, uint _minDstGas);

    constructor(address _endpoint) {
        lzEndpoint = ILayerZeroEndpoint(_endpoint);
    }

    function lzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) public virtual override {
        // lzReceive must be called by the endpoint for security
        require(_msgSender() == address(lzEndpoint), "LzApp: invalid endpoint caller");

        bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];
        // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.
        require(_srcAddress.length == trustedRemote.length && trustedRemote.length > 0 && keccak256(_srcAddress) == keccak256(trustedRemote), "LzApp: invalid source sending contract");

        _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);
    }

    // abstract function - the default behaviour of LayerZero is blocking. See: NonblockingLzApp if you dont need to enforce ordered messaging
    function _blockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) internal virtual;

    function _lzSend(uint16 _dstChainId, bytes memory _payload, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams, uint _nativeFee) internal virtual {
        bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];
        require(trustedRemote.length != 0, "LzApp: destination chain is not a trusted source");
        _checkPayloadSize(_dstChainId, _payload.length);
        lzEndpoint.send{value: _nativeFee}(_dstChainId, trustedRemote, _payload, _refundAddress, _zroPaymentAddress, _adapterParams);
    }

    function _checkGasLimit(uint16 _dstChainId, uint16 _type, bytes memory _adapterParams, uint _extraGas) internal view virtual {
        uint providedGasLimit = _getGasLimit(_adapterParams);
        uint minGasLimit = minDstGasLookup[_dstChainId][_type] + _extraGas;
        require(minGasLimit > 0, "LzApp: minGasLimit not set");
        require(providedGasLimit >= minGasLimit, "LzApp: gas limit is too low");
    }

    function _getGasLimit(bytes memory _adapterParams) internal pure virtual returns (uint gasLimit) {
        require(_adapterParams.length >= 34, "LzApp: invalid adapterParams");
        assembly {
            gasLimit := mload(add(_adapterParams, 34))
        }
    }

    function _checkPayloadSize(uint16 _dstChainId, uint _payloadSize) internal view virtual {
        uint payloadSizeLimit = payloadSizeLimitLookup[_dstChainId];
        if (payloadSizeLimit == 0) { // use default if not set
            payloadSizeLimit = DEFAULT_PAYLOAD_SIZE_LIMIT;
        }
        require(_payloadSize <= payloadSizeLimit, "LzApp: payload size is too large");
    }

    //---------------------------UserApplication config----------------------------------------
    function getConfig(uint16 _version, uint16 _chainId, address, uint _configType) external view returns (bytes memory) {
        return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);
    }

    // generic config for LayerZero user Application
    function setConfig(uint16 _version, uint16 _chainId, uint _configType, bytes calldata _config) external override onlyOwner {
        lzEndpoint.setConfig(_version, _chainId, _configType, _config);
    }

    function setSendVersion(uint16 _version) external override onlyOwner {
        lzEndpoint.setSendVersion(_version);
    }

    function setReceiveVersion(uint16 _version) external override onlyOwner {
        lzEndpoint.setReceiveVersion(_version);
    }

    function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external override onlyOwner {
        lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);
    }

    // _path = abi.encodePacked(remoteAddress, localAddress)
    // this function set the trusted path for the cross-chain communication
    function setTrustedRemote(uint16 _srcChainId, bytes calldata _path) external onlyOwner {
        trustedRemoteLookup[_srcChainId] = _path;
        emit SetTrustedRemote(_srcChainId, _path);
    }

    function setTrustedRemoteAddress(uint16 _remoteChainId, bytes calldata _remoteAddress) external onlyOwner {
        trustedRemoteLookup[_remoteChainId] = abi.encodePacked(_remoteAddress, address(this));
        emit SetTrustedRemoteAddress(_remoteChainId, _remoteAddress);
    }

    function getTrustedRemoteAddress(uint16 _remoteChainId) external view returns (bytes memory) {
        bytes memory path = trustedRemoteLookup[_remoteChainId];
        require(path.length != 0, "LzApp: no trusted path record");
        return path.slice(0, path.length - 20); // the last 20 bytes should be address(this)
    }

    function setPrecrime(address _precrime) external onlyOwner {
        precrime = _precrime;
        emit SetPrecrime(_precrime);
    }

    function setMinDstGas(uint16 _dstChainId, uint16 _packetType, uint _minGas) external onlyOwner {
        require(_minGas > 0, "LzApp: invalid minGas");
        minDstGasLookup[_dstChainId][_packetType] = _minGas;
        emit SetMinDstGas(_dstChainId, _packetType, _minGas);
    }

    // if the size is 0, it means default size limit
    function setPayloadSizeLimit(uint16 _dstChainId, uint _size) external onlyOwner {
        payloadSizeLimitLookup[_dstChainId] = _size;
    }

    //--------------------------- VIEW FUNCTION ----------------------------------------
    function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {
        bytes memory trustedSource = trustedRemoteLookup[_srcChainId];
        return keccak256(trustedSource) == keccak256(_srcAddress);
    }
}


// File contracts/util/ExcessivelySafeCall.sol

//   OR Apache-2.0
pragma solidity >=0.7.6;

library ExcessivelySafeCall {
    uint256 constant LOW_28_MASK =
    0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff;

    /// @notice Use when you _really_ really _really_ don't trust the called
    /// contract. This prevents the called contract from causing reversion of
    /// the caller in as many ways as we can.
    /// @dev The main difference between this and a solidity low-level call is
    /// that we limit the number of bytes that the callee can cause to be
    /// copied to caller memory. This prevents stupid things like malicious
    /// contracts returning 10,000,000 bytes causing a local OOG when copying
    /// to memory.
    /// @param _target The address to call
    /// @param _gas The amount of gas to forward to the remote contract
    /// @param _maxCopy The maximum number of bytes of returndata to copy
    /// to memory.
    /// @param _calldata The data to send to the remote contract
    /// @return success and returndata, as `.call()`. Returndata is capped to
    /// `_maxCopy` bytes.
    function excessivelySafeCall(
        address _target,
        uint256 _gas,
        uint16 _maxCopy,
        bytes memory _calldata
    ) internal returns (bool, bytes memory) {
        // set up for assembly call
        uint256 _toCopy;
        bool _success;
        bytes memory _returnData = new bytes(_maxCopy);
        // dispatch message to recipient
        // by assembly calling "handle" function
        // we call via assembly to avoid memcopying a very large returndata
        // returned by a malicious contract
        assembly {
            _success := call(
            _gas, // gas
            _target, // recipient
            0, // ether value
            add(_calldata, 0x20), // inloc
            mload(_calldata), // inlen
            0, // outloc
            0 // outlen
            )
        // limit our copy to 256 bytes
            _toCopy := returndatasize()
            if gt(_toCopy, _maxCopy) {
                _toCopy := _maxCopy
            }
        // Store the length of the copied bytes
            mstore(_returnData, _toCopy)
        // copy the bytes from returndata[0:_toCopy]
            returndatacopy(add(_returnData, 0x20), 0, _toCopy)
        }
        return (_success, _returnData);
    }

    /// @notice Use when you _really_ really _really_ don't trust the called
    /// contract. This prevents the called contract from causing reversion of
    /// the caller in as many ways as we can.
    /// @dev The main difference between this and a solidity low-level call is
    /// that we limit the number of bytes that the callee can cause to be
    /// copied to caller memory. This prevents stupid things like malicious
    /// contracts returning 10,000,000 bytes causing a local OOG when copying
    /// to memory.
    /// @param _target The address to call
    /// @param _gas The amount of gas to forward to the remote contract
    /// @param _maxCopy The maximum number of bytes of returndata to copy
    /// to memory.
    /// @param _calldata The data to send to the remote contract
    /// @return success and returndata, as `.call()`. Returndata is capped to
    /// `_maxCopy` bytes.
    function excessivelySafeStaticCall(
        address _target,
        uint256 _gas,
        uint16 _maxCopy,
        bytes memory _calldata
    ) internal view returns (bool, bytes memory) {
        // set up for assembly call
        uint256 _toCopy;
        bool _success;
        bytes memory _returnData = new bytes(_maxCopy);
        // dispatch message to recipient
        // by assembly calling "handle" function
        // we call via assembly to avoid memcopying a very large returndata
        // returned by a malicious contract
        assembly {
            _success := staticcall(
            _gas, // gas
            _target, // recipient
            add(_calldata, 0x20), // inloc
            mload(_calldata), // inlen
            0, // outloc
            0 // outlen
            )
        // limit our copy to 256 bytes
            _toCopy := returndatasize()
            if gt(_toCopy, _maxCopy) {
                _toCopy := _maxCopy
            }
        // Store the length of the copied bytes
            mstore(_returnData, _toCopy)
        // copy the bytes from returndata[0:_toCopy]
            returndatacopy(add(_returnData, 0x20), 0, _toCopy)
        }
        return (_success, _returnData);
    }

    /**
     * @notice Swaps function selectors in encoded contract calls
     * @dev Allows reuse of encoded calldata for functions with identical
     * argument types but different names. It simply swaps out the first 4 bytes
     * for the new selector. This function modifies memory in place, and should
     * only be used with caution.
     * @param _newSelector The new 4-byte selector
     * @param _buf The encoded contract args
     */
    function swapSelector(bytes4 _newSelector, bytes memory _buf)
    internal
    pure
    {
        require(_buf.length >= 4);
        uint256 _mask = LOW_28_MASK;
        assembly {
        // load the first word of
            let _word := mload(add(_buf, 0x20))
        // mask out the top 4 bytes
        // /x
            _word := and(_word, _mask)
            _word := or(_newSelector, _word)
            mstore(add(_buf, 0x20), _word)
        }
    }
}


// File contracts/lzApp/NonblockingLzApp.sol

 

pragma solidity ^0.8.0;


/*
 * the default LayerZero messaging behaviour is blocking, i.e. any failed message will block the channel
 * this abstract class try-catch all fail messages and store locally for future retry. hence, non-blocking
 * NOTE: if the srcAddress is not configured properly, it will still block the message pathway from (srcChainId, srcAddress)
 */
abstract contract NonblockingLzApp is LzApp {
    using ExcessivelySafeCall for address;

    constructor(address _endpoint) LzApp(_endpoint) {}

    mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;

    event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload, bytes _reason);
    event RetryMessageSuccess(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes32 _payloadHash);

    // overriding the virtual function in LzReceiver
    function _blockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) internal virtual override {
        (bool success, bytes memory reason) = address(this).excessivelySafeCall(gasleft(), 150, abi.encodeWithSelector(this.nonblockingLzReceive.selector, _srcChainId, _srcAddress, _nonce, _payload));
        // try-catch all errors/exceptions
        if (!success) {
            _storeFailedMessage(_srcChainId, _srcAddress, _nonce, _payload, reason);
        }
    }

    function _storeFailedMessage(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload, bytes memory _reason) internal virtual {
        failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);
        emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload, _reason);
    }

    function nonblockingLzReceive(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) public virtual {
        // only internal transaction
        require(_msgSender() == address(this), "NonblockingLzApp: caller must be LzApp");
        _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);
    }

    //@notice override this function
    function _nonblockingLzReceive(uint16 _srcChainId, bytes memory _srcAddress, uint64 _nonce, bytes memory _payload) internal virtual;

    function retryMessage(uint16 _srcChainId, bytes calldata _srcAddress, uint64 _nonce, bytes calldata _payload) public payable virtual {
        // assert there is message to retry
        bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];
        require(payloadHash != bytes32(0), "NonblockingLzApp: no stored message");
        require(keccak256(_payload) == payloadHash, "NonblockingLzApp: invalid payload");
        // clear the stored message
        failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);
        // execute the message. revert if it fails again
        _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);
        emit RetryMessageSuccess(_srcChainId, _srcAddress, _nonce, payloadHash);
    }
}


// File @openzeppelin/contracts/utils/introspection/[email protected]

 
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

/**
 * @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 contracts/token/onft/ONFT721Core.sol

 

pragma solidity ^0.8.0;



abstract contract ONFT721Core is NonblockingLzApp, ERC165, IONFT721Core {
    uint16 public constant FUNCTION_TYPE_SEND = 1;

    struct StoredCredit {
        uint16 srcChainId;
        address toAddress;
        uint256 index; // which index of the tokenIds remain
        bool creditsRemain;
    }

    uint256 public minGasToTransferAndStore; // min amount of gas required to transfer, and also store the payload
    mapping(uint16 => uint256) public dstChainIdToBatchLimit;
    mapping(uint16 => uint256) public dstChainIdToTransferGas; // per transfer amount of gas required to mint/transfer on the dst
    mapping(bytes32 => StoredCredit) public storedCredits;

    constructor(uint256 _minGasToTransferAndStore, address _lzEndpoint) NonblockingLzApp(_lzEndpoint) {
        require(_minGasToTransferAndStore > 0, "ONFT721: minGasToTransferAndStore must be > 0");
        minGasToTransferAndStore = _minGasToTransferAndStore;
    }

    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return interfaceId == type(IONFT721Core).interfaceId || super.supportsInterface(interfaceId);
    }

    function estimateSendFee(uint16 _dstChainId, bytes memory _toAddress, uint _tokenId, bool _useZro, bytes memory _adapterParams) public view virtual override returns (uint nativeFee, uint zroFee) {
        return estimateSendBatchFee(_dstChainId, _toAddress, _toSingletonArray(_tokenId), _useZro, _adapterParams);
    }

    function estimateSendBatchFee(uint16 _dstChainId, bytes memory _toAddress, uint[] memory _tokenIds, bool _useZro, bytes memory _adapterParams) public view virtual override returns (uint nativeFee, uint zroFee) {
        bytes memory payload = abi.encode(_toAddress, _tokenIds);
        return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);
    }

    function sendFrom(address _from, uint16 _dstChainId, bytes memory _toAddress, uint _tokenId, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams) public payable virtual override {
        _send(_from, _dstChainId, _toAddress, _toSingletonArray(_tokenId), _refundAddress, _zroPaymentAddress, _adapterParams);
    }

    function sendBatchFrom(address _from, uint16 _dstChainId, bytes memory _toAddress, uint[] memory _tokenIds, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams) public payable virtual override {
        _send(_from, _dstChainId, _toAddress, _tokenIds, _refundAddress, _zroPaymentAddress, _adapterParams);
    }

    function _send(address _from, uint16 _dstChainId, bytes memory _toAddress, uint[] memory _tokenIds, address payable _refundAddress, address _zroPaymentAddress, bytes memory _adapterParams) internal virtual {
        // allow 1 by default
        require(_tokenIds.length > 0, "LzApp: tokenIds[] is empty");
        require(_tokenIds.length == 1 || _tokenIds.length <= dstChainIdToBatchLimit[_dstChainId], "ONFT721: batch size exceeds dst batch limit");

        for (uint i = 0; i < _tokenIds.length; i++) {
            _debitFrom(_from, _dstChainId, _toAddress, _tokenIds[i]);
        }

        bytes memory payload = abi.encode(_toAddress, _tokenIds);

        _checkGasLimit(_dstChainId, FUNCTION_TYPE_SEND, _adapterParams, dstChainIdToTransferGas[_dstChainId] * _tokenIds.length);
        _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams, msg.value);
        emit SendToChain(_dstChainId, _from, _toAddress, _tokenIds);
    }

    function _nonblockingLzReceive(
        uint16 _srcChainId,
        bytes memory _srcAddress,
        uint64, /*_nonce*/
        bytes memory _payload
    ) internal virtual override {
        // decode and load the toAddress
        (bytes memory toAddressBytes, uint[] memory tokenIds) = abi.decode(_payload, (bytes, uint[]));

        address toAddress;
        assembly {
            toAddress := mload(add(toAddressBytes, 20))
        }

        uint nextIndex = _creditTill(_srcChainId, toAddress, 0, tokenIds);
        if (nextIndex < tokenIds.length) {
            // not enough gas to complete transfers, store to be cleared in another tx
            bytes32 hashedPayload = keccak256(_payload);
            storedCredits[hashedPayload] = StoredCredit(_srcChainId, toAddress, nextIndex, true);
            emit CreditStored(hashedPayload, _payload);
        }

        emit ReceiveFromChain(_srcChainId, _srcAddress, toAddress, tokenIds);
    }

    // Public function for anyone to clear and deliver the remaining batch sent tokenIds
    function clearCredits(bytes memory _payload) external {
        bytes32 hashedPayload = keccak256(_payload);
        require(storedCredits[hashedPayload].creditsRemain, "ONFT721: no credits stored");

        (, uint[] memory tokenIds) = abi.decode(_payload, (bytes, uint[]));

        uint nextIndex = _creditTill(storedCredits[hashedPayload].srcChainId, storedCredits[hashedPayload].toAddress, storedCredits[hashedPayload].index, tokenIds);
        require(nextIndex > storedCredits[hashedPayload].index, "ONFT721: not enough gas to process credit transfer");

        if (nextIndex == tokenIds.length) {
            // cleared the credits, delete the element
            delete storedCredits[hashedPayload];
            emit CreditCleared(hashedPayload);
        } else {
            // store the next index to mint
            storedCredits[hashedPayload] = StoredCredit(storedCredits[hashedPayload].srcChainId, storedCredits[hashedPayload].toAddress, nextIndex, true);
        }
    }

    // When a srcChain has the ability to transfer more chainIds in a single tx than the dst can do.
    // Needs the ability to iterate and stop if the minGasToTransferAndStore is not met
    function _creditTill(uint16 _srcChainId, address _toAddress, uint _startIndex, uint[] memory _tokenIds) internal returns (uint256){
        uint i = _startIndex;
        while (i < _tokenIds.length) {
            // if not enough gas to process, store this index for next loop
            if (gasleft() < minGasToTransferAndStore) break;

            _creditTo(_srcChainId, _toAddress, _tokenIds[i]);
            i++;
        }

        // indicates the next index to send of tokenIds,
        // if i == tokenIds.length, we are finished
        return i;
    }

    function setMinGasToTransferAndStore(uint256 _minGasToTransferAndStore) external onlyOwner {
        require(_minGasToTransferAndStore > 0, "ONFT721: minGasToTransferAndStore must be > 0");
        minGasToTransferAndStore = _minGasToTransferAndStore;
    }

    // ensures enough gas in adapter params to handle batch transfer gas amounts on the dst
    function setDstChainIdToTransferGas(uint16 _dstChainId, uint256 _dstChainIdToTransferGas) external onlyOwner {
        require(_dstChainIdToTransferGas > 0, "ONFT721: dstChainIdToTransferGas must be > 0");
        dstChainIdToTransferGas[_dstChainId] = _dstChainIdToTransferGas;
    }

    // limit on src the amount of tokens to batch send
    function setDstChainIdToBatchLimit(uint16 _dstChainId, uint256 _dstChainIdToBatchLimit) external onlyOwner {
        require(_dstChainIdToBatchLimit > 0, "ONFT721: dstChainIdToBatchLimit must be > 0");
        dstChainIdToBatchLimit[_dstChainId] = _dstChainIdToBatchLimit;
    }

    function _debitFrom(address _from, uint16 _dstChainId, bytes memory _toAddress, uint _tokenId) internal virtual;

    function _creditTo(uint16 _srcChainId, address _toAddress, uint _tokenId) internal virtual;

    function _toSingletonArray(uint element) internal pure returns (uint[] memory) {
        uint[] memory array = new uint[](1);
        array[0] = element;
        return array;
    }
}


// File @openzeppelin/contracts/token/ERC721/[email protected]

 
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}


// File @openzeppelin/contracts/token/ERC721/extensions/[email protected]

 
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

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

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) external view returns (string memory);
}


// File @openzeppelin/contracts/utils/[email protected]

 
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @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 functionCall(target, data, "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");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(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) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(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) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason 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 {
            // 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/utils/[email protected]

 
// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}


// File @openzeppelin/contracts/token/ERC721/[email protected]

 
// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;







/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension, but not including the Enumerable extension, which is available separately as
 * {ERC721Enumerable}.
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to owner address
    mapping(uint256 => address) private _owners;

    // Mapping owner address to token count
    mapping(address => uint256) private _balances;

    // Mapping from token ID to approved address
    mapping(uint256 => address) private _tokenApprovals;

    // Mapping from owner to operator approvals
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    /**
     * @dev Initializes the contract by setting a `name` and a `symbol` to the token collection.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return
            interfaceId == type(IERC721).interfaceId ||
            interfaceId == type(IERC721Metadata).interfaceId ||
            super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: address zero is not a valid owner");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: invalid token ID");
        return owner;
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        _requireMinted(tokenId);

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, "pass.json")) : "";
    }

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be overridden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not token owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        _requireMinted(tokenId);

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

    /**
     * @dev See {IERC721-isApprovedForAll}.
     */
    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved");

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner nor approved");
        _safeTransfer(from, to, tokenId, data);
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _owners[tokenId] != address(0);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(
        address to,
        uint256 tokenId,
        bytes memory data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId);

        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(address(0), to, tokenId);

        _afterTokenTransfer(address(0), to, tokenId);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

        _beforeTokenTransfer(owner, address(0), tokenId);

        // Clear approvals
        _approve(address(0), tokenId);

        _balances[owner] -= 1;
        delete _owners[tokenId];

        emit Transfer(owner, address(0), tokenId);

        _afterTokenTransfer(owner, address(0), tokenId);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits an {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits an {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC721: approve to caller");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Reverts if the `tokenId` has not been minted yet.
     */
    function _requireMinted(uint256 tokenId) internal view virtual {
        require(_exists(tokenId), "ERC721: invalid token ID");
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) private returns (bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    /// @solidity memory-safe-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` 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 tokenId
    ) 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.
     * - `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 tokenId
    ) internal virtual {}
}


// File @openzeppelin/contracts/token/ERC721/extensions/[email protected]

 
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns a token ID owned by `owner` at a given `index` of its token list.
     * Use along with {balanceOf} to enumerate all of ``owner``'s tokens.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) external view returns (uint256);

    /**
     * @dev Returns a token ID at a given `index` of all the tokens stored by the contract.
     * Use along with {totalSupply} to enumerate all tokens.
     */
    function tokenByIndex(uint256 index) external view returns (uint256);
}


// File @openzeppelin/contracts/token/ERC721/extensions/[email protected]

 
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)

pragma solidity ^0.8.0;


/**
 * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
 * enumerability of all the token ids in the contract as well as all token ids owned by each
 * account.
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => mapping(uint256 => uint256)) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721) returns (bool) {
        return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

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

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

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

        if (from == address(0)) {
            _addTokenToAllTokensEnumeration(tokenId);
        } else if (from != to) {
            _removeTokenFromOwnerEnumeration(from, tokenId);
        }
        if (to == address(0)) {
            _removeTokenFromAllTokensEnumeration(tokenId);
        } else if (to != from) {
            _addTokenToOwnerEnumeration(to, tokenId);
        }
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        uint256 length = ERC721.balanceOf(to);
        _ownedTokens[to][length] = tokenId;
        _ownedTokensIndex[tokenId] = length;
    }

    /**
     * @dev Private function to add a token to this extension's token tracking data structures.
     * @param tokenId uint256 ID of the token to be added to the tokens list
     */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        delete _ownedTokensIndex[tokenId];
        delete _ownedTokens[from][lastTokenIndex];
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _allTokens.length - 1;
        uint256 tokenIndex = _allTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
        uint256 lastTokenId = _allTokens[lastTokenIndex];

        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

        // This also deletes the contents at the last position of the array
        delete _allTokensIndex[tokenId];
        _allTokens.pop();
    }
}


// File @openzeppelin/contracts/security/[email protected]

 
// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        _requireNotPaused();
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        _requirePaused();
        _;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Throws if the contract is paused.
     */
    function _requireNotPaused() internal view virtual {
        require(!paused(), "Pausable: paused");
    }

    /**
     * @dev Throws if the contract is not paused.
     */
    function _requirePaused() internal view virtual {
        require(paused(), "Pausable: not paused");
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}


// File @openzeppelin/contracts/access/[email protected]

 
// OpenZeppelin Contracts v4.4.1 (access/IAccessControl.sol)

pragma solidity ^0.8.0;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}


// File @openzeppelin/contracts/access/[email protected]

 
// OpenZeppelin Contracts (last updated v4.7.0) (access/AccessControl.sol)

pragma solidity ^0.8.0;




/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping(address => bool) members;
        bytes32 adminRole;
    }

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with a standardized message including the required role.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     *
     * _Available since v4.1._
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role);
        _;
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IAccessControl).interfaceId || super.supportsInterface(interfaceId);
    }

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Revert with a standard message if `_msgSender()` is missing `role`.
     * Overriding this function changes the behavior of the {onlyRole} modifier.
     *
     * Format of the revert message is described in {_checkRole}.
     *
     * _Available since v4.6._
     */
    function _checkRole(bytes32 role) internal view virtual {
        _checkRole(role, _msgSender());
    }

    /**
     * @dev Revert with a standard message if `account` is missing `role`.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     */
    function _checkRole(bytes32 role, address account) internal view virtual {
        if (!hasRole(role, account)) {
            revert(
                string(
                    abi.encodePacked(
                        "AccessControl: account ",
                        Strings.toHexString(uint160(account), 20),
                        " is missing role ",
                        Strings.toHexString(uint256(role), 32)
                    )
                )
            );
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     *
     * May emit a {RoleGranted} event.
     */
    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     *
     * May emit a {RoleRevoked} event.
     */
    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been revoked `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     *
     * May emit a {RoleRevoked} event.
     */
    function renounceRole(bytes32 role, address account) public virtual override {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * May emit a {RoleGranted} event.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     *
     * NOTE: This function is deprecated in favor of {_grantRole}.
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = getRoleAdmin(role);
        _roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * Internal function without access restriction.
     *
     * May emit a {RoleGranted} event.
     */
    function _grantRole(bytes32 role, address account) internal virtual {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * Internal function without access restriction.
     *
     * May emit a {RoleRevoked} event.
     */
    function _revokeRole(bytes32 role, address account) internal virtual {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}


// File contracts/token/onft/ONFT721.sol

 

pragma solidity ^0.8.0;





// NOTE: this ONFT contract has no public minting logic.
// must implement your own minting logic in child classes
contract ONFT721 is ONFT721Core, ERC721, IONFT721, ERC721Enumerable, Pausable, AccessControl{
    constructor(string memory _name, string memory _symbol, uint256 _minGasToTransfer, address _lzEndpoint) ERC721(_name, _symbol) ONFT721Core(_minGasToTransfer, _lzEndpoint) {}

    function supportsInterface(bytes4 interfaceId) public view virtual override(ONFT721Core, ERC721, IERC165, ERC721Enumerable, AccessControl) returns (bool) {
        return interfaceId == type(IONFT721).interfaceId || super.supportsInterface(interfaceId);
    }

    function _debitFrom(address _from, uint16, bytes memory, uint _tokenId) internal virtual override {
        require(_isApprovedOrOwner(_msgSender(), _tokenId), "ONFT721: send caller is not owner nor approved");
        require(ERC721.ownerOf(_tokenId) == _from, "ONFT721: send from incorrect owner");
        _transfer(_from, address(this), _tokenId);
    }

    function _creditTo(uint16, address _toAddress, uint _tokenId) internal virtual override {
        require(!_exists(_tokenId) || (_exists(_tokenId) && ERC721.ownerOf(_tokenId) == address(this)));
        if (!_exists(_tokenId)) {
            _safeMint(_toAddress, _tokenId);
        } else {
            _transfer(address(this), _toAddress, _tokenId);
        }
    }

    function _beforeTokenTransfer(address from, address to, uint256 tokenId)
        internal
        whenNotPaused
        override(ERC721, ERC721Enumerable)
    {
        super._beforeTokenTransfer(from, to, tokenId);
    }
}


// File contracts/token/onft/extension/UniversalONFT721.sol



pragma solidity ^0.8.0;


/// @title Interface of the UniversalONFT standard
contract UniversalONFT721 is ONFT721 {
    uint public nextMintId;
    uint public maxMintId;
    string baseURI = "https://www.blocjerk.com/pass/"; 
    mapping(address => bool) public admin;
    /// @notice Constructor for the UniversalONFT
    /// @param _name the name of the token
    /// @param _symbol the token symbol
    /// @param _layerZeroEndpoint handles message transmission across chains
    /// @param _startMintId the starting mint number on this chain
    /// @param _endMintId the max number of mints on this chain
    constructor(string memory _name, string memory _symbol, uint256 _minGasToTransfer, address _layerZeroEndpoint, uint _startMintId, uint _endMintId) ONFT721(_name, _symbol, _minGasToTransfer, _layerZeroEndpoint) {
        nextMintId = _startMintId;
        maxMintId = _endMintId;
    }

    event ChangeRangeTokenId(
        uint min,
        uint max,
        uint blockTime
    );

    event AddAdmin(
        address admin,
        uint blockTime
    );

    function _baseURI() internal view virtual override returns (string memory) {
        return baseURI;
    }

    function setBaseURI(string memory _baseUri) public onlyOwner() {
        baseURI = _baseUri;
    }

    function addAdmin(address _admin) external onlyOwner() {
        admin[_admin] = !admin[_admin];
        emit AddAdmin(_admin, block.timestamp);
    }

    function changeRangeTokenId(uint _min, uint _max) external onlyOwner() {
        require(maxMintId < _min && _min < _max, "NFT: RANGE_TOKEN_ID_WRONG");
        nextMintId = _min;
        maxMintId = _max;
        emit ChangeRangeTokenId(_min, _max, block.timestamp);
    }
    /// @notice Mint your ONFT
    function mint(address to) external {
        require(admin[msg.sender]);
        require(nextMintId <= maxMintId, "UniversalONFT721: max mint limit reached");

        uint newId = nextMintId;
        nextMintId++;

        _safeMint(to, newId);
    }
}



// File contracts/AITONFT.sol

pragma solidity ^0.8.0;

/// @title A LayerZero UniversalONFT example
/// @notice You can use this to mint ONFT and send nftIds across chain.
///  Each contract deployed to a chain should carefully set a `_startMintIndex` and a `_maxMint`
///  value to set a range of allowed mintable nftIds (so that no two chains can mint the same id!)
contract TheHallPass is UniversalONFT721 {
    constructor(uint256 _minGasToStore, address _layerZeroEndpoint, uint _startMintId, uint _endMintId) UniversalONFT721("The Hall Pass", "THP", _minGasToStore, _layerZeroEndpoint, _startMintId, _endMintId) {}
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"uint256","name":"_minGasToStore","type":"uint256"},{"internalType":"address","name":"_layerZeroEndpoint","type":"address"},{"internalType":"uint256","name":"_startMintId","type":"uint256"},{"internalType":"uint256","name":"_endMintId","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"admin","type":"address"},{"indexed":false,"internalType":"uint256","name":"blockTime","type":"uint256"}],"name":"AddAdmin","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"min","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"max","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"blockTime","type":"uint256"}],"name":"ChangeRangeTokenId","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"_hashedPayload","type":"bytes32"}],"name":"CreditCleared","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"_hashedPayload","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"CreditStored","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"_nonce","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"_payload","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"_reason","type":"bytes"}],"name":"MessageFailed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":true,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":true,"internalType":"address","name":"_toAddress","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"ReceiveFromChain","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"_nonce","type":"uint64"},{"indexed":false,"internalType":"bytes32","name":"_payloadHash","type":"bytes32"}],"name":"RetryMessageSuccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"bytes","name":"_toAddress","type":"bytes"},{"indexed":false,"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"SendToChain","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"indexed":false,"internalType":"uint16","name":"_type","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"_minDstGas","type":"uint256"}],"name":"SetMinDstGas","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"precrime","type":"address"}],"name":"SetPrecrime","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_path","type":"bytes"}],"name":"SetTrustedRemote","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_remoteAddress","type":"bytes"}],"name":"SetTrustedRemoteAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_PAYLOAD_SIZE_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FUNCTION_TYPE_SEND","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_admin","type":"address"}],"name":"addAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"admin","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_min","type":"uint256"},{"internalType":"uint256","name":"_max","type":"uint256"}],"name":"changeRangeTokenId","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"clearCredits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"dstChainIdToBatchLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"dstChainIdToTransferGas","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"bool","name":"_useZro","type":"bool"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"estimateSendBatchFee","outputs":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"zroFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bool","name":"_useZro","type":"bool"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"estimateSendFee","outputs":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"zroFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"uint64","name":"","type":"uint64"}],"name":"failedMessages","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"}],"name":"forceResumeReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"},{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"_configType","type":"uint256"}],"name":"getConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"}],"name":"getTrustedRemoteAddress","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"}],"name":"isTrustedRemote","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lzEndpoint","outputs":[{"internalType":"contract ILayerZeroEndpoint","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"lzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"maxMintId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"uint16","name":"","type":"uint16"}],"name":"minDstGasLookup","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minGasToTransferAndStore","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextMintId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"nonblockingLzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"payloadSizeLimitLookup","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"precrime","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"retryMessage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"internalType":"address","name":"_zroPaymentAddress","type":"address"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"sendBatchFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"internalType":"address","name":"_zroPaymentAddress","type":"address"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"sendFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseUri","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"},{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"uint256","name":"_configType","type":"uint256"},{"internalType":"bytes","name":"_config","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_dstChainIdToBatchLimit","type":"uint256"}],"name":"setDstChainIdToBatchLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_dstChainIdToTransferGas","type":"uint256"}],"name":"setDstChainIdToTransferGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint16","name":"_packetType","type":"uint16"},{"internalType":"uint256","name":"_minGas","type":"uint256"}],"name":"setMinDstGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minGasToTransferAndStore","type":"uint256"}],"name":"setMinGasToTransferAndStore","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_size","type":"uint256"}],"name":"setPayloadSizeLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_precrime","type":"address"}],"name":"setPrecrime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"}],"name":"setReceiveVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"}],"name":"setSendVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_path","type":"bytes"}],"name":"setTrustedRemote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"internalType":"bytes","name":"_remoteAddress","type":"bytes"}],"name":"setTrustedRemoteAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"storedCredits","outputs":[{"internalType":"uint16","name":"srcChainId","type":"uint16"},{"internalType":"address","name":"toAddress","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"bool","name":"creditsRemain","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"trustedRemoteLookup","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"}]

60e0604052601e60a08190527f68747470733a2f2f7777772e626c6f636a65726b2e636f6d2f706173732f000060c0908152620000409160189190620001fc565b503480156200004e57600080fd5b5060405162005578380380620055788339810160408190526200007191620002a2565b6040518060400160405280600d81526020016c5468652048616c6c205061737360981b8152506040518060400160405280600381526020016205448560ec1b8152508585858585858585838383838080620000db620000d5620001a860201b60201c565b620001ac565b6001600160a01b03166080525081620001505760405162461bcd60e51b815260206004820152602d60248201527f4f4e46543732313a206d696e476173546f5472616e73666572416e6453746f7260448201526c065206d757374206265203e203609c1b606482015260840160405180910390fd5b5060065581516200016990600a906020850190620001fc565b5080516200017f90600b906020840190620001fc565b50506014805460ff1916905550505060169390935550601755506200032c975050505050505050565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b8280546200020a90620002ef565b90600052602060002090601f0160209004810192826200022e576000855562000279565b82601f106200024957805160ff191683800117855562000279565b8280016001018555821562000279579182015b82811115620002795782518255916020019190600101906200025c565b50620002879291506200028b565b5090565b5b808211156200028757600081556001016200028c565b60008060008060808587031215620002b957600080fd5b845160208601519094506001600160a01b0381168114620002d957600080fd5b6040860151606090960151949790965092505050565b600181811c908216806200030457607f821691505b602082108114156200032657634e487b7160e01b600052602260045260246000fd5b50919050565b6080516151f86200038060003960008181610b3d01528181610d770152818161107b015281816112d3015281816115a1015281816120d00152818161255001528181612686015261370301526151f86000f3fe6080604052600436106103ee5760003560e01c806370a0823111610208578063b353aaa711610118578063d547741f116100ab578063eb8d72b71161007a578063eb8d72b714610cc7578063f235364114610ce7578063f2fde38b14610d07578063f5ecbdbc14610d27578063fa25f9b614610d4757600080fd5b8063d547741f14610c28578063df2a5b3b14610c48578063e1d4c87014610c68578063e985e9c514610c7e57600080fd5b8063c87b56dd116100e7578063c87b56dd14610bb5578063cbed8b9c14610bd5578063d12473a514610bf5578063d1deba1f14610c1557600080fd5b8063b353aaa714610b2b578063b88d4fde14610b5f578063baf3292d14610b7f578063c446183414610b9f57600080fd5b806395d89b411161019b578063a217fddf1161016a578063a217fddf14610a9b578063a22cb46514610ab0578063a6c3d16514610ad0578063ab3ffb9314610af0578063af3fb21c14610b0357600080fd5b806395d89b4114610a265780639a03c1cd14610a3b5780639ea5d6b114610a5b5780639f38369a14610a7b57600080fd5b80638da5cb5b116101d75780638da5cb5b146109a85780638ffa1f2a146109c657806391d14854146109e6578063950c8a7414610a0657600080fd5b806370a082311461091b578063715018a61461093b5780637533d788146109505780638cfd8f5c1461097057600080fd5b80633d8b38f61161030357806355f804b31161029657806363a846f81161026557806363a846f81461087557806366ad5c8a146108a55780636a627842146108c55780636aa99da3146108e557806370480275146108fb57600080fd5b806355f804b3146107ce5780635b8c41e6146107ee5780635c975abb1461083d5780636352211e1461085557600080fd5b806348288190116102d257806348288190146107585780634ac3f4ff1461076e5780634f6ccce71461079b57806351905636146107bb57600080fd5b80633d8b38f6146106cb5780633f1f4fa4146106eb57806342842e0e1461071857806342d65a8d1461073857600080fd5b806310ddb13711610386578063248a9ca311610355578063248a9ca3146106065780632a205e3d146106365780632f2ff15d1461066b5780632f745c591461068b57806336568abe146106ab57600080fd5b806310ddb1371461052457806318160ddd1461054457806322a3ecf91461056357806323b872dd146105e657600080fd5b8063081812fc116103c2578063081812fc1461048c578063095ea7b3146104c45780630b4cad4c146104e45780630df374831461050457600080fd5b80621d3567146103f357806301ffc9a71461041557806306fdde031461044a57806307e0db171461046c575b600080fd5b3480156103ff57600080fd5b5061041361040e366004614175565b610d74565b005b34801561042157600080fd5b5061043561043036600461421e565b610fa5565b60405190151581526020015b60405180910390f35b34801561045657600080fd5b5061045f610fc8565b6040516104419190614293565b34801561047857600080fd5b506104136104873660046142a6565b61105a565b34801561049857600080fd5b506104ac6104a73660046142c1565b6110e3565b6040516001600160a01b039091168152602001610441565b3480156104d057600080fd5b506104136104df3660046142fa565b61110a565b3480156104f057600080fd5b506104136104ff3660046142c1565b611220565b34801561051057600080fd5b5061041361051f366004614326565b611293565b34801561053057600080fd5b5061041361053f3660046142a6565b6112b2565b34801561055057600080fd5b506012545b604051908152602001610441565b34801561056f57600080fd5b506105b761057e3660046142c1565b60096020526000908152604090208054600182015460029092015461ffff821692620100009092046001600160a01b0316919060ff1684565b6040805161ffff90951685526001600160a01b0390931660208501529183015215156060820152608001610441565b3480156105f257600080fd5b50610413610601366004614342565b61130a565b34801561061257600080fd5b506105556106213660046142c1565b60009081526015602052604090206001015490565b34801561064257600080fd5b5061065661065136600461445e565b61133c565b60408051928352602083019190915201610441565b34801561067757600080fd5b506104136106863660046144ec565b611362565b34801561069757600080fd5b506105556106a63660046142fa565b611387565b3480156106b757600080fd5b506104136106c63660046144ec565b61141d565b3480156106d757600080fd5b506104356106e636600461451c565b61149b565b3480156106f757600080fd5b506105556107063660046142a6565b60036020526000908152604090205481565b34801561072457600080fd5b50610413610733366004614342565b611567565b34801561074457600080fd5b5061041361075336600461451c565b611582565b34801561076457600080fd5b5061055560065481565b34801561077a57600080fd5b506105556107893660046142a6565b60076020526000908152604090205481565b3480156107a757600080fd5b506105556107b63660046142c1565b611608565b6104136107c936600461456e565b61169b565b3480156107da57600080fd5b506104136107e9366004614627565b6116b2565b3480156107fa57600080fd5b5061055561080936600461466f565b6005602090815260009384526040808520845180860184018051928152908401958401959095209452929052825290205481565b34801561084957600080fd5b5060145460ff16610435565b34801561086157600080fd5b506104ac6108703660046142c1565b6116cd565b34801561088157600080fd5b506104356108903660046146cc565b60196020526000908152604090205460ff1681565b3480156108b157600080fd5b506104136108c0366004614175565b61172d565b3480156108d157600080fd5b506104136108e03660046146cc565b611809565b3480156108f157600080fd5b5061055560165481565b34801561090757600080fd5b506104136109163660046146cc565b6118ab565b34801561092757600080fd5b506105556109363660046146cc565b611918565b34801561094757600080fd5b5061041361199e565b34801561095c57600080fd5b5061045f61096b3660046142a6565b6119b2565b34801561097c57600080fd5b5061055561098b3660046146e9565b600260209081526000928352604080842090915290825290205481565b3480156109b457600080fd5b506000546001600160a01b03166104ac565b3480156109d257600080fd5b506104136109e136600461471c565b611a4c565b3480156109f257600080fd5b50610435610a013660046144ec565b611c9b565b348015610a1257600080fd5b506004546104ac906001600160a01b031681565b348015610a3257600080fd5b5061045f611cc6565b348015610a4757600080fd5b50610413610a56366004614750565b611cd5565b348015610a6757600080fd5b50610413610a76366004614326565b611d86565b348015610a8757600080fd5b5061045f610a963660046142a6565b611e09565b348015610aa757600080fd5b50610555600081565b348015610abc57600080fd5b50610413610acb366004614772565b611f20565b348015610adc57600080fd5b50610413610aeb36600461451c565b611f2b565b610413610afe366004614827565b611fbe565b348015610b0f57600080fd5b50610b18600181565b60405161ffff9091168152602001610441565b348015610b3757600080fd5b506104ac7f000000000000000000000000000000000000000000000000000000000000000081565b348015610b6b57600080fd5b50610413610b7a3660046148dc565b611fcd565b348015610b8b57600080fd5b50610413610b9a3660046146cc565b611fff565b348015610bab57600080fd5b5061055561271081565b348015610bc157600080fd5b5061045f610bd03660046142c1565b612055565b348015610be157600080fd5b50610413610bf0366004614947565b6120b1565b348015610c0157600080fd5b50610413610c10366004614326565b612146565b610413610c23366004614175565b6121ca565b348015610c3457600080fd5b50610413610c433660046144ec565b6123e0565b348015610c5457600080fd5b50610413610c633660046149b5565b612405565b348015610c7457600080fd5b5061055560175481565b348015610c8a57600080fd5b50610435610c993660046149f1565b6001600160a01b039182166000908152600f6020908152604080832093909416825291909152205460ff1690565b348015610cd357600080fd5b50610413610ce236600461451c565b6124b7565b348015610cf357600080fd5b50610656610d02366004614a1f565b612511565b348015610d1357600080fd5b50610413610d223660046146cc565b6125dc565b348015610d3357600080fd5b5061045f610d42366004614a98565b612655565b348015610d5357600080fd5b50610555610d623660046142a6565b60086020526000908152604090205481565b337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614610df15760405162461bcd60e51b815260206004820152601e60248201527f4c7a4170703a20696e76616c696420656e64706f696e742063616c6c6572000060448201526064015b60405180910390fd5b61ffff861660009081526001602052604081208054610e0f90614ae5565b80601f0160208091040260200160405190810160405280929190818152602001828054610e3b90614ae5565b8015610e885780601f10610e5d57610100808354040283529160200191610e88565b820191906000526020600020905b815481529060010190602001808311610e6b57829003601f168201915b50505050509050805186869050148015610ea3575060008151115b8015610ecb575080516020820120604051610ec19088908890614b20565b6040518091039020145b610f265760405162461bcd60e51b815260206004820152602660248201527f4c7a4170703a20696e76616c696420736f757263652073656e64696e6720636f6044820152651b9d1c9858dd60d21b6064820152608401610de8565b610f9c8787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881528a93509150889088908190840183828082843760009201919091525061270892505050565b50505050505050565b60006001600160e01b031982161580610fc25750610fc282612781565b92915050565b6060600a8054610fd790614ae5565b80601f016020809104026020016040519081016040528092919081815260200182805461100390614ae5565b80156110505780601f1061102557610100808354040283529160200191611050565b820191906000526020600020905b81548152906001019060200180831161103357829003601f168201915b5050505050905090565b6110626127a6565b6040516307e0db1760e01b815261ffff821660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906307e0db17906024015b600060405180830381600087803b1580156110c857600080fd5b505af11580156110dc573d6000803e3d6000fd5b5050505050565b60006110ee82612800565b506000908152600e60205260409020546001600160a01b031690565b6000611115826116cd565b9050806001600160a01b0316836001600160a01b031614156111835760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610de8565b336001600160a01b038216148061119f575061119f8133610c99565b6112115760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c00006064820152608401610de8565b61121b838361285f565b505050565b6112286127a6565b6000811161128e5760405162461bcd60e51b815260206004820152602d60248201527f4f4e46543732313a206d696e476173546f5472616e73666572416e6453746f7260448201526c065206d757374206265203e203609c1b6064820152608401610de8565b600655565b61129b6127a6565b61ffff909116600090815260036020526040902055565b6112ba6127a6565b6040516310ddb13760e01b815261ffff821660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906310ddb137906024016110ae565b611315335b826128cd565b6113315760405162461bcd60e51b8152600401610de890614b30565b61121b83838361294b565b600080611354878761134d88612af2565b8787612511565b915091509550959350505050565b60008281526015602052604090206001015461137d81612b3d565b61121b8383612b47565b600061139283611918565b82106113f45760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610de8565b506001600160a01b03919091166000908152601060209081526040808320938352929052205490565b6001600160a01b038116331461148d5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610de8565b6114978282612bcd565b5050565b61ffff8316600090815260016020526040812080548291906114bc90614ae5565b80601f01602080910402602001604051908101604052809291908181526020018280546114e890614ae5565b80156115355780601f1061150a57610100808354040283529160200191611535565b820191906000526020600020905b81548152906001019060200180831161151857829003601f168201915b50505050509050838360405161154c929190614b20565b60405180910390208180519060200120149150509392505050565b61121b83838360405180602001604052806000815250611fcd565b61158a6127a6565b6040516342d65a8d60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906342d65a8d906115da90869086908690600401614ba7565b600060405180830381600087803b1580156115f457600080fd5b505af1158015610f9c573d6000803e3d6000fd5b600061161360125490565b82106116765760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610de8565b6012828154811061168957611689614bc5565b90600052602060002001549050919050565b610f9c8787876116aa88612af2565b878787612c34565b6116ba6127a6565b8051611497906018906020840190613ff2565b6000818152600c60205260408120546001600160a01b031680610fc25760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610de8565b33301461178b5760405162461bcd60e51b815260206004820152602660248201527f4e6f6e626c6f636b696e674c7a4170703a2063616c6c6572206d7573742062656044820152650204c7a4170760d41b6064820152608401610de8565b6118018686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f890181900481028201810190925287815289935091508790879081908401838280828437600092019190915250612e1b92505050565b505050505050565b3360009081526019602052604090205460ff1661182557600080fd5b601754601654111561188a5760405162461bcd60e51b815260206004820152602860248201527f556e6976657273616c4f4e46543732313a206d6178206d696e74206c696d6974604482015267081c995858da195960c21b6064820152608401610de8565b60168054908190600061189c83614bf1565b91905055506114978282612f72565b6118b36127a6565b6001600160a01b038116600081815260196020908152604091829020805460ff81161560ff19909116179055815192835242908301527fbd5dcf0b25226117c4a68a0129ffdd4b0541ef5e482ad7de9a96ccb6d6a8ebde91015b60405180910390a150565b60006001600160a01b0382166119825760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610de8565b506001600160a01b03166000908152600d602052604090205490565b6119a66127a6565b6119b06000612f8c565b565b600160205260009081526040902080546119cb90614ae5565b80601f01602080910402602001604051908101604052809291908181526020018280546119f790614ae5565b8015611a445780601f10611a1957610100808354040283529160200191611a44565b820191906000526020600020905b815481529060010190602001808311611a2757829003601f168201915b505050505081565b80516020808301919091206000818152600990925260409091206002015460ff16611ab95760405162461bcd60e51b815260206004820152601a60248201527f4f4e46543732313a206e6f20637265646974732073746f7265640000000000006044820152606401610de8565b600082806020019051810190611acf9190614c51565b60008481526009602052604081208054600190910154929450909250611b0b9161ffff8216916201000090046001600160a01b03169085612fdc565b6000848152600960205260409020600101549091508111611b895760405162461bcd60e51b815260206004820152603260248201527f4f4e46543732313a206e6f7420656e6f7567682067617320746f2070726f636560448201527139b99031b932b234ba103a3930b739b332b960711b6064820152608401610de8565b8151811415611c015760008381526009602052604080822080546001600160b01b031916815560018101929092556002909101805460ff19169055517fd7be02b8dd0d27bd0517a9cb4d7469ce27df4313821ae5ec1ff69acc594ba23390611bf49085815260200190565b60405180910390a1611c95565b60408051608081018252600085815260096020818152848320805461ffff80821687526001600160a01b03620100008084048216868a019081529989018b8152600160608b01818152998f90529790965297519851169096026001600160b01b03199091169690951695909517939093178455915191830191909155516002909101805491151560ff199092169190911790555b50505050565b60009182526015602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6060600b8054610fd790614ae5565b611cdd6127a6565b81601754108015611ced57508082105b611d395760405162461bcd60e51b815260206004820152601960248201527f4e46543a2052414e47455f544f4b454e5f49445f57524f4e47000000000000006044820152606401610de8565b601682905560178190556040805183815260208101839052428183015290517f7db56eb2742bf8b3ecbd53c305e1b52da85b7d34804466938417948949d91a209181900360600190a15050565b611d8e6127a6565b60008111611df25760405162461bcd60e51b815260206004820152602b60248201527f4f4e46543732313a20647374436861696e4964546f42617463684c696d69742060448201526a06d757374206265203e20360ac1b6064820152608401610de8565b61ffff909116600090815260076020526040902055565b61ffff8116600090815260016020526040812080546060929190611e2c90614ae5565b80601f0160208091040260200160405190810160405280929190818152602001828054611e5890614ae5565b8015611ea55780601f10611e7a57610100808354040283529160200191611ea5565b820191906000526020600020905b815481529060010190602001808311611e8857829003601f168201915b50505050509050805160001415611efe5760405162461bcd60e51b815260206004820152601d60248201527f4c7a4170703a206e6f20747275737465642070617468207265636f72640000006044820152606401610de8565b611f19600060148351611f119190614d0b565b83919061302e565b9392505050565b61149733838361313b565b611f336127a6565b818130604051602001611f4893929190614d22565b60408051601f1981840301815291815261ffff85166000908152600160209081529190208251611f7d93919290910190613ff2565b507f8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce838383604051611fb193929190614ba7565b60405180910390a1505050565b610f9c87878787878787612c34565b611fd733836128cd565b611ff35760405162461bcd60e51b8152600401610de890614b30565b611c958484848461320a565b6120076127a6565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b9060200161190d565b606061206082612800565b600061206a61323d565b9050600081511161208a5760405180602001604052806000815250611f19565b8060405160200161209b9190614d48565b6040516020818303038152906040529392505050565b6120b96127a6565b6040516332fb62e760e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063cbed8b9c9061210d9088908890889088908890600401614d75565b600060405180830381600087803b15801561212757600080fd5b505af115801561213b573d6000803e3d6000fd5b505050505050505050565b61214e6127a6565b600081116121b35760405162461bcd60e51b815260206004820152602c60248201527f4f4e46543732313a20647374436861696e4964546f5472616e7366657247617360448201526b0206d757374206265203e20360a41b6064820152608401610de8565b61ffff909116600090815260086020526040902055565b61ffff861660009081526005602052604080822090516121ed9088908890614b20565b90815260408051602092819003830190206001600160401b0387166000908152925290205490508061226d5760405162461bcd60e51b815260206004820152602360248201527f4e6f6e626c6f636b696e674c7a4170703a206e6f2073746f726564206d65737360448201526261676560e81b6064820152608401610de8565b80838360405161227e929190614b20565b6040518091039020146122dd5760405162461bcd60e51b815260206004820152602160248201527f4e6f6e626c6f636b696e674c7a4170703a20696e76616c6964207061796c6f616044820152601960fa1b6064820152608401610de8565b61ffff871660009081526005602052604080822090516123009089908990614b20565b90815260408051602092819003830181206001600160401b038916600090815290845282902093909355601f88018290048202830182019052868252612398918991899089908190840183828082843760009201919091525050604080516020601f8a018190048102820181019092528881528a935091508890889081908401838280828437600092019190915250612e1b92505050565b7fc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e587878787856040516123cf959493929190614dae565b60405180910390a150505050505050565b6000828152601560205260409020600101546123fb81612b3d565b61121b8383612bcd565b61240d6127a6565b600081116124555760405162461bcd60e51b81526020600482015260156024820152744c7a4170703a20696e76616c6964206d696e47617360581b6044820152606401610de8565b61ffff83811660008181526002602090815260408083209487168084529482529182902085905581519283528201929092529081018290527f9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac090606001611fb1565b6124bf6127a6565b61ffff831660009081526001602052604090206124dd908383614076565b507ffa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab838383604051611fb193929190614ba7565b60008060008686604051602001612529929190614e24565b60408051601f198184030181529082905263040a7bb160e41b825291506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906340a7bb109061258d908b90309086908b908b90600401614e52565b6040805180830381865afa1580156125a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125cd9190614ea6565b92509250509550959350505050565b6125e46127a6565b6001600160a01b0381166126495760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610de8565b61265281612f8c565b50565b604051633d7b2f6f60e21b815261ffff808616600483015284166024820152306044820152606481018290526060907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f5ecbdbc90608401600060405180830381865afa1580156126d5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526126fd9190810190614eca565b90505b949350505050565b60008061276b5a60966366ad5c8a60e01b898989896040516024016127309493929190614efe565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091523092919061324c565b91509150816118015761180186868686856132d6565b60006001600160e01b03198216637965db0b60e01b1480610fc25750610fc282613373565b6000546001600160a01b031633146119b05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610de8565b6000818152600c60205260409020546001600160a01b03166126525760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610de8565b6000818152600e6020526040902080546001600160a01b0319166001600160a01b0384169081179091558190612894826116cd565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000806128d9836116cd565b9050806001600160a01b0316846001600160a01b0316148061292057506001600160a01b038082166000908152600f602090815260408083209388168352929052205460ff165b806127005750836001600160a01b0316612939846110e3565b6001600160a01b031614949350505050565b826001600160a01b031661295e826116cd565b6001600160a01b0316146129c25760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610de8565b6001600160a01b038216612a245760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610de8565b612a2f838383613398565b612a3a60008261285f565b6001600160a01b0383166000908152600d60205260408120805460019290612a63908490614d0b565b90915550506001600160a01b0382166000908152600d60205260408120805460019290612a91908490614f3c565b90915550506000818152600c602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b60408051600180825281830190925260609160009190602080830190803683370190505090508281600081518110612b2c57612b2c614bc5565b602090810291909101015292915050565b61265281336133ab565b612b518282611c9b565b6114975760008281526015602090815260408083206001600160a01b03851684529091529020805460ff19166001179055612b893390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b612bd78282611c9b565b156114975760008281526015602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000845111612c855760405162461bcd60e51b815260206004820152601a60248201527f4c7a4170703a20746f6b656e4964735b5d20697320656d7074790000000000006044820152606401610de8565b835160011480612ca9575061ffff8616600090815260076020526040902054845111155b612d095760405162461bcd60e51b815260206004820152602b60248201527f4f4e46543732313a2062617463682073697a652065786365656473206473742060448201526a18985d18da081b1a5b5a5d60aa1b6064820152608401610de8565b60005b8451811015612d4c57612d3a888888888581518110612d2d57612d2d614bc5565b602002602001015161340f565b80612d4481614bf1565b915050612d0c565b5060008585604051602001612d62929190614e24565b6040516020818303038152906040529050612da7876001848851600860008d61ffff1661ffff16815260200190815260200160002054612da29190614f54565b6134fa565b612db58782868686346135d9565b85604051612dc39190614f73565b6040518091039020886001600160a01b03168861ffff167fe1b87c47fdeb4f9cbadbca9df3af7aba453bb6e501075d0440d88125b711522a88604051612e099190614f8f565b60405180910390a45050505050505050565b60008082806020019051810190612e329190614c51565b601482015191935091506000612e4a88838386612fdc565b90508251811015612f1e5784516020808701919091206040805160808101825261ffff808d1682526001600160a01b0380881683870190815283850188815260016060860181815260008981526009909a529887902095518654935190941662010000026001600160b01b03199093169390941692909217178355519082015592516002909301805493151560ff199094169390931790925590517f10e0b70d256bccc84b7027506978bd8b68984a870788b93b479def144c839ad790612f149083908990614fa2565b60405180910390a1505b816001600160a01b031687604051612f369190614f73565b60405180910390208961ffff167f5b821db8a46f8ecbe1941ba2f51cfeea9643268b56631f70d45e2a745d99026586604051612e099190614f8f565b61149782826040518060200160405280600081525061377f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000825b82518110156126fd576006545a1015612ff8576126fd565b61301c868685848151811061300f5761300f614bc5565b60200260200101516137b2565b8061302681614bf1565b915050612fe0565b60608161303c81601f614f3c565b101561307b5760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b6044820152606401610de8565b6130858284614f3c565b845110156130c95760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b6044820152606401610de8565b6060821580156130e85760405191506000825260208201604052613132565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015613121578051835260209283019201613109565b5050858452601f01601f1916604052505b50949350505050565b816001600160a01b0316836001600160a01b0316141561319d5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610de8565b6001600160a01b038381166000818152600f6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b61321584848461294b565b61322184848484613841565b611c955760405162461bcd60e51b8152600401610de890614fbb565b606060188054610fd790614ae5565b6000606060008060008661ffff166001600160401b0381111561327157613271614383565b6040519080825280601f01601f19166020018201604052801561329b576020820181803683370190505b50905060008087516020890160008d8df191503d9250868311156132bd578692505b828152826000602083013e909890975095505050505050565b8180519060200120600560008761ffff1661ffff168152602001908152602001600020856040516133079190614f73565b9081526040805191829003602090810183206001600160401b0388166000908152915220919091557fe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c90613364908790879087908790879061500d565b60405180910390a15050505050565b60006001600160e01b0319821663780e9d6360e01b1480610fc25750610fc28261393c565b6133a061397c565b61121b8383836139c2565b6133b58282611c9b565b611497576133cd816001600160a01b03166014613a7a565b6133d8836020613a7a565b6040516020016133e992919061505f565b60408051601f198184030181529082905262461bcd60e51b8252610de891600401614293565b6134183361130f565b61347b5760405162461bcd60e51b815260206004820152602e60248201527f4f4e46543732313a2073656e642063616c6c6572206973206e6f74206f776e6560448201526d1c881b9bdc88185c1c1c9bdd995960921b6064820152608401610de8565b836001600160a01b031661348e826116cd565b6001600160a01b0316146134ef5760405162461bcd60e51b815260206004820152602260248201527f4f4e46543732313a2073656e642066726f6d20696e636f7272656374206f776e60448201526132b960f11b6064820152608401610de8565b611c9584308361294b565b600061350583613c15565b61ffff808716600090815260026020908152604080832093891683529290529081205491925090613537908490614f3c565b9050600081116135895760405162461bcd60e51b815260206004820152601a60248201527f4c7a4170703a206d696e4761734c696d6974206e6f74207365740000000000006044820152606401610de8565b808210156118015760405162461bcd60e51b815260206004820152601b60248201527f4c7a4170703a20676173206c696d697420697320746f6f206c6f7700000000006044820152606401610de8565b61ffff8616600090815260016020526040812080546135f790614ae5565b80601f016020809104026020016040519081016040528092919081815260200182805461362390614ae5565b80156136705780601f1061364557610100808354040283529160200191613670565b820191906000526020600020905b81548152906001019060200180831161365357829003601f168201915b505050505090508051600014156136e25760405162461bcd60e51b815260206004820152603060248201527f4c7a4170703a2064657374696e6174696f6e20636861696e206973206e6f742060448201526f61207472757374656420736f7572636560801b6064820152608401610de8565b6136ed878751613c71565b60405162c5803160e81b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c5803100908490613744908b9086908c908c908c908c906004016150d4565b6000604051808303818588803b15801561375d57600080fd5b505af1158015613771573d6000803e3d6000fd5b505050505050505050505050565b6137898383613cdf565b6137966000848484613841565b61121b5760405162461bcd60e51b8152600401610de890614fbb565b6000818152600c60205260409020546001600160a01b0316158061380757506000818152600c60205260409020546001600160a01b0316151580156138075750306137fc826116cd565b6001600160a01b0316145b61381057600080fd5b6000818152600c60205260409020546001600160a01b03166138365761121b8282612f72565b61121b30838361294b565b60006001600160a01b0384163b1561393457604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061388590339089908890889060040161513b565b6020604051808303816000875af19250505080156138c0575060408051601f3d908101601f191682019092526138bd91810190615178565b60015b61391a573d8080156138ee576040519150601f19603f3d011682016040523d82523d6000602084013e6138f3565b606091505b5080516139125760405162461bcd60e51b8152600401610de890614fbb565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612700565b506001612700565b60006001600160e01b031982166380ac58cd60e01b148061396d57506001600160e01b03198216635b5e139f60e01b145b80610fc25750610fc282613e2d565b60145460ff16156119b05760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610de8565b6001600160a01b038316613a1d57613a1881601280546000838152601360205260408120829055600182018355919091527fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34440155565b613a40565b816001600160a01b0316836001600160a01b031614613a4057613a408382613e62565b6001600160a01b038216613a575761121b81613eff565b826001600160a01b0316826001600160a01b03161461121b5761121b8282613fae565b60606000613a89836002614f54565b613a94906002614f3c565b6001600160401b03811115613aab57613aab614383565b6040519080825280601f01601f191660200182016040528015613ad5576020820181803683370190505b509050600360fc1b81600081518110613af057613af0614bc5565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110613b1f57613b1f614bc5565b60200101906001600160f81b031916908160001a9053506000613b43846002614f54565b613b4e906001614f3c565b90505b6001811115613bc6576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110613b8257613b82614bc5565b1a60f81b828281518110613b9857613b98614bc5565b60200101906001600160f81b031916908160001a90535060049490941c93613bbf81615195565b9050613b51565b508315611f195760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610de8565b6000602282511015613c695760405162461bcd60e51b815260206004820152601c60248201527f4c7a4170703a20696e76616c69642061646170746572506172616d73000000006044820152606401610de8565b506022015190565b61ffff821660009081526003602052604090205480613c8f57506127105b8082111561121b5760405162461bcd60e51b815260206004820181905260248201527f4c7a4170703a207061796c6f61642073697a6520697320746f6f206c617267656044820152606401610de8565b6001600160a01b038216613d355760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610de8565b6000818152600c60205260409020546001600160a01b031615613d9a5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610de8565b613da660008383613398565b6001600160a01b0382166000908152600d60205260408120805460019290613dcf908490614f3c565b90915550506000818152600c602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001600160e01b031982166322bac5d960e01b1480610fc257506301ffc9a760e01b6001600160e01b0319831614610fc2565b60006001613e6f84611918565b613e799190614d0b565b600083815260116020526040902054909150808214613ecc576001600160a01b03841660009081526010602090815260408083208584528252808320548484528184208190558352601190915290208190555b5060009182526011602090815260408084208490556001600160a01b039094168352601081528383209183525290812055565b601254600090613f1190600190614d0b565b60008381526013602052604081205460128054939450909284908110613f3957613f39614bc5565b906000526020600020015490508060128381548110613f5a57613f5a614bc5565b6000918252602080832090910192909255828152601390915260408082208490558582528120556012805480613f9257613f926151ac565b6001900381819060005260206000200160009055905550505050565b6000613fb983611918565b6001600160a01b039093166000908152601060209081526040808320868452825280832085905593825260119052919091209190915550565b828054613ffe90614ae5565b90600052602060002090601f0160209004810192826140205760008555614066565b82601f1061403957805160ff1916838001178555614066565b82800160010185558215614066579182015b8281111561406657825182559160200191906001019061404b565b506140729291506140ea565b5090565b82805461408290614ae5565b90600052602060002090601f0160209004810192826140a45760008555614066565b82601f106140bd5782800160ff19823516178555614066565b82800160010185558215614066579182015b828111156140665782358255916020019190600101906140cf565b5b8082111561407257600081556001016140eb565b803561ffff8116811461411157600080fd5b919050565b60008083601f84011261412857600080fd5b5081356001600160401b0381111561413f57600080fd5b60208301915083602082850101111561415757600080fd5b9250929050565b80356001600160401b038116811461411157600080fd5b6000806000806000806080878903121561418e57600080fd5b614197876140ff565b955060208701356001600160401b03808211156141b357600080fd5b6141bf8a838b01614116565b90975095508591506141d360408a0161415e565b945060608901359150808211156141e957600080fd5b506141f689828a01614116565b979a9699509497509295939492505050565b6001600160e01b03198116811461265257600080fd5b60006020828403121561423057600080fd5b8135611f1981614208565b60005b8381101561425657818101518382015260200161423e565b83811115611c955750506000910152565b6000815180845261427f81602086016020860161423b565b601f01601f19169290920160200192915050565b602081526000611f196020830184614267565b6000602082840312156142b857600080fd5b611f19826140ff565b6000602082840312156142d357600080fd5b5035919050565b6001600160a01b038116811461265257600080fd5b8035614111816142da565b6000806040838503121561430d57600080fd5b8235614318816142da565b946020939093013593505050565b6000806040838503121561433957600080fd5b614318836140ff565b60008060006060848603121561435757600080fd5b8335614362816142da565b92506020840135614372816142da565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156143c1576143c1614383565b604052919050565b60006001600160401b038211156143e2576143e2614383565b50601f01601f191660200190565b60006144036143fe846143c9565b614399565b905082815283838301111561441757600080fd5b828260208301376000602084830101529392505050565b600082601f83011261443f57600080fd5b611f19838335602085016143f0565b8035801515811461411157600080fd5b600080600080600060a0868803121561447657600080fd5b61447f866140ff565b945060208601356001600160401b038082111561449b57600080fd5b6144a789838a0161442e565b9550604088013594506144bc6060890161444e565b935060808801359150808211156144d257600080fd5b506144df8882890161442e565b9150509295509295909350565b600080604083850312156144ff57600080fd5b823591506020830135614511816142da565b809150509250929050565b60008060006040848603121561453157600080fd5b61453a846140ff565b925060208401356001600160401b0381111561455557600080fd5b61456186828701614116565b9497909650939450505050565b600080600080600080600060e0888a03121561458957600080fd5b8735614594816142da565b96506145a2602089016140ff565b955060408801356001600160401b03808211156145be57600080fd5b6145ca8b838c0161442e565b965060608a0135955060808a013591506145e3826142da565b90935060a0890135906145f5826142da565b90925060c0890135908082111561460b57600080fd5b506146188a828b0161442e565b91505092959891949750929550565b60006020828403121561463957600080fd5b81356001600160401b0381111561464f57600080fd5b8201601f8101841361466057600080fd5b612700848235602084016143f0565b60008060006060848603121561468457600080fd5b61468d846140ff565b925060208401356001600160401b038111156146a857600080fd5b6146b48682870161442e565b9250506146c36040850161415e565b90509250925092565b6000602082840312156146de57600080fd5b8135611f19816142da565b600080604083850312156146fc57600080fd5b614705836140ff565b9150614713602084016140ff565b90509250929050565b60006020828403121561472e57600080fd5b81356001600160401b0381111561474457600080fd5b6127008482850161442e565b6000806040838503121561476357600080fd5b50508035926020909101359150565b6000806040838503121561478557600080fd5b8235614790816142da565b91506147136020840161444e565b60006001600160401b038211156147b7576147b7614383565b5060051b60200190565b600082601f8301126147d257600080fd5b813560206147e26143fe8361479e565b82815260059290921b8401810191818101908684111561480157600080fd5b8286015b8481101561481c5780358352918301918301614805565b509695505050505050565b600080600080600080600060e0888a03121561484257600080fd5b873561484d816142da565b965061485b602089016140ff565b955060408801356001600160401b038082111561487757600080fd5b6148838b838c0161442e565b965060608a013591508082111561489957600080fd5b6148a58b838c016147c1565b955060808a013591506148b7826142da565b8194506148c660a08b016142ef565b935060c08a013591508082111561460b57600080fd5b600080600080608085870312156148f257600080fd5b84356148fd816142da565b9350602085013561490d816142da565b92506040850135915060608501356001600160401b0381111561492f57600080fd5b61493b8782880161442e565b91505092959194509250565b60008060008060006080868803121561495f57600080fd5b614968866140ff565b9450614976602087016140ff565b93506040860135925060608601356001600160401b0381111561499857600080fd5b6149a488828901614116565b969995985093965092949392505050565b6000806000606084860312156149ca57600080fd5b6149d3846140ff565b92506149e1602085016140ff565b9150604084013590509250925092565b60008060408385031215614a0457600080fd5b8235614a0f816142da565b91506020830135614511816142da565b600080600080600060a08688031215614a3757600080fd5b614a40866140ff565b945060208601356001600160401b0380821115614a5c57600080fd5b614a6889838a0161442e565b95506040880135915080821115614a7e57600080fd5b614a8a89838a016147c1565b94506144bc6060890161444e565b60008060008060808587031215614aae57600080fd5b614ab7856140ff565b9350614ac5602086016140ff565b92506040850135614ad5816142da565b9396929550929360600135925050565b600181811c90821680614af957607f821691505b60208210811415614b1a57634e487b7160e01b600052602260045260246000fd5b50919050565b8183823760009101908152919050565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b61ffff841681526040602082015260006126fd604083018486614b7e565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600019821415614c0557614c05614bdb565b5060010190565b600082601f830112614c1d57600080fd5b8151614c2b6143fe826143c9565b818152846020838601011115614c4057600080fd5b61270082602083016020870161423b565b60008060408385031215614c6457600080fd5b82516001600160401b0380821115614c7b57600080fd5b614c8786838701614c0c565b9350602091508185015181811115614c9e57600080fd5b85019050601f81018613614cb157600080fd5b8051614cbf6143fe8261479e565b81815260059190911b82018301908381019088831115614cde57600080fd5b928401925b82841015614cfc57835182529284019290840190614ce3565b80955050505050509250929050565b600082821015614d1d57614d1d614bdb565b500390565b8284823760609190911b6bffffffffffffffffffffffff19169101908152601401919050565b60008251614d5a81846020870161423b565b683830b9b9973539b7b760b91b920191825250600901919050565b600061ffff808816835280871660208401525084604083015260806060830152614da3608083018486614b7e565b979650505050505050565b61ffff86168152608060208201526000614dcc608083018688614b7e565b6001600160401b0394909416604083015250606001529392505050565b600081518084526020808501945080840160005b83811015614e1957815187529582019590820190600101614dfd565b509495945050505050565b604081526000614e376040830185614267565b8281036020840152614e498185614de9565b95945050505050565b61ffff861681526001600160a01b038516602082015260a060408201819052600090614e8090830186614267565b84151560608401528281036080840152614e9a8185614267565b98975050505050505050565b60008060408385031215614eb957600080fd5b505080516020909101519092909150565b600060208284031215614edc57600080fd5b81516001600160401b03811115614ef257600080fd5b61270084828501614c0c565b61ffff85168152608060208201526000614f1b6080830186614267565b6001600160401b03851660408401528281036060840152614da38185614267565b60008219821115614f4f57614f4f614bdb565b500190565b6000816000190483118215151615614f6e57614f6e614bdb565b500290565b60008251614f8581846020870161423b565b9190910192915050565b602081526000611f196020830184614de9565b8281526040602082015260006127006040830184614267565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b61ffff8616815260a06020820152600061502a60a0830187614267565b6001600160401b0386166040840152828103606084015261504b8186614267565b90508281036080840152614e9a8185614267565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161509781601785016020880161423b565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516150c881602884016020880161423b565b01602801949350505050565b61ffff8716815260c0602082015260006150f160c0830188614267565b82810360408401526151038188614267565b6001600160a01b0387811660608601528616608085015283810360a0850152905061512e8185614267565b9998505050505050505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061516e90830184614267565b9695505050505050565b60006020828403121561518a57600080fd5b8151611f1981614208565b6000816151a4576151a4614bdb565b506000190190565b634e487b7160e01b600052603160045260246000fdfea26469706673582212209bf4e74d33912aceb8133ff3eec9cd4434ae1623fda0887647cfe8e44a8d0cd964736f6c634300080c0033000000000000000000000000000000000000000000000000000000000000000100000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd67500000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000002710

Deployed Bytecode

0x6080604052600436106103ee5760003560e01c806370a0823111610208578063b353aaa711610118578063d547741f116100ab578063eb8d72b71161007a578063eb8d72b714610cc7578063f235364114610ce7578063f2fde38b14610d07578063f5ecbdbc14610d27578063fa25f9b614610d4757600080fd5b8063d547741f14610c28578063df2a5b3b14610c48578063e1d4c87014610c68578063e985e9c514610c7e57600080fd5b8063c87b56dd116100e7578063c87b56dd14610bb5578063cbed8b9c14610bd5578063d12473a514610bf5578063d1deba1f14610c1557600080fd5b8063b353aaa714610b2b578063b88d4fde14610b5f578063baf3292d14610b7f578063c446183414610b9f57600080fd5b806395d89b411161019b578063a217fddf1161016a578063a217fddf14610a9b578063a22cb46514610ab0578063a6c3d16514610ad0578063ab3ffb9314610af0578063af3fb21c14610b0357600080fd5b806395d89b4114610a265780639a03c1cd14610a3b5780639ea5d6b114610a5b5780639f38369a14610a7b57600080fd5b80638da5cb5b116101d75780638da5cb5b146109a85780638ffa1f2a146109c657806391d14854146109e6578063950c8a7414610a0657600080fd5b806370a082311461091b578063715018a61461093b5780637533d788146109505780638cfd8f5c1461097057600080fd5b80633d8b38f61161030357806355f804b31161029657806363a846f81161026557806363a846f81461087557806366ad5c8a146108a55780636a627842146108c55780636aa99da3146108e557806370480275146108fb57600080fd5b806355f804b3146107ce5780635b8c41e6146107ee5780635c975abb1461083d5780636352211e1461085557600080fd5b806348288190116102d257806348288190146107585780634ac3f4ff1461076e5780634f6ccce71461079b57806351905636146107bb57600080fd5b80633d8b38f6146106cb5780633f1f4fa4146106eb57806342842e0e1461071857806342d65a8d1461073857600080fd5b806310ddb13711610386578063248a9ca311610355578063248a9ca3146106065780632a205e3d146106365780632f2ff15d1461066b5780632f745c591461068b57806336568abe146106ab57600080fd5b806310ddb1371461052457806318160ddd1461054457806322a3ecf91461056357806323b872dd146105e657600080fd5b8063081812fc116103c2578063081812fc1461048c578063095ea7b3146104c45780630b4cad4c146104e45780630df374831461050457600080fd5b80621d3567146103f357806301ffc9a71461041557806306fdde031461044a57806307e0db171461046c575b600080fd5b3480156103ff57600080fd5b5061041361040e366004614175565b610d74565b005b34801561042157600080fd5b5061043561043036600461421e565b610fa5565b60405190151581526020015b60405180910390f35b34801561045657600080fd5b5061045f610fc8565b6040516104419190614293565b34801561047857600080fd5b506104136104873660046142a6565b61105a565b34801561049857600080fd5b506104ac6104a73660046142c1565b6110e3565b6040516001600160a01b039091168152602001610441565b3480156104d057600080fd5b506104136104df3660046142fa565b61110a565b3480156104f057600080fd5b506104136104ff3660046142c1565b611220565b34801561051057600080fd5b5061041361051f366004614326565b611293565b34801561053057600080fd5b5061041361053f3660046142a6565b6112b2565b34801561055057600080fd5b506012545b604051908152602001610441565b34801561056f57600080fd5b506105b761057e3660046142c1565b60096020526000908152604090208054600182015460029092015461ffff821692620100009092046001600160a01b0316919060ff1684565b6040805161ffff90951685526001600160a01b0390931660208501529183015215156060820152608001610441565b3480156105f257600080fd5b50610413610601366004614342565b61130a565b34801561061257600080fd5b506105556106213660046142c1565b60009081526015602052604090206001015490565b34801561064257600080fd5b5061065661065136600461445e565b61133c565b60408051928352602083019190915201610441565b34801561067757600080fd5b506104136106863660046144ec565b611362565b34801561069757600080fd5b506105556106a63660046142fa565b611387565b3480156106b757600080fd5b506104136106c63660046144ec565b61141d565b3480156106d757600080fd5b506104356106e636600461451c565b61149b565b3480156106f757600080fd5b506105556107063660046142a6565b60036020526000908152604090205481565b34801561072457600080fd5b50610413610733366004614342565b611567565b34801561074457600080fd5b5061041361075336600461451c565b611582565b34801561076457600080fd5b5061055560065481565b34801561077a57600080fd5b506105556107893660046142a6565b60076020526000908152604090205481565b3480156107a757600080fd5b506105556107b63660046142c1565b611608565b6104136107c936600461456e565b61169b565b3480156107da57600080fd5b506104136107e9366004614627565b6116b2565b3480156107fa57600080fd5b5061055561080936600461466f565b6005602090815260009384526040808520845180860184018051928152908401958401959095209452929052825290205481565b34801561084957600080fd5b5060145460ff16610435565b34801561086157600080fd5b506104ac6108703660046142c1565b6116cd565b34801561088157600080fd5b506104356108903660046146cc565b60196020526000908152604090205460ff1681565b3480156108b157600080fd5b506104136108c0366004614175565b61172d565b3480156108d157600080fd5b506104136108e03660046146cc565b611809565b3480156108f157600080fd5b5061055560165481565b34801561090757600080fd5b506104136109163660046146cc565b6118ab565b34801561092757600080fd5b506105556109363660046146cc565b611918565b34801561094757600080fd5b5061041361199e565b34801561095c57600080fd5b5061045f61096b3660046142a6565b6119b2565b34801561097c57600080fd5b5061055561098b3660046146e9565b600260209081526000928352604080842090915290825290205481565b3480156109b457600080fd5b506000546001600160a01b03166104ac565b3480156109d257600080fd5b506104136109e136600461471c565b611a4c565b3480156109f257600080fd5b50610435610a013660046144ec565b611c9b565b348015610a1257600080fd5b506004546104ac906001600160a01b031681565b348015610a3257600080fd5b5061045f611cc6565b348015610a4757600080fd5b50610413610a56366004614750565b611cd5565b348015610a6757600080fd5b50610413610a76366004614326565b611d86565b348015610a8757600080fd5b5061045f610a963660046142a6565b611e09565b348015610aa757600080fd5b50610555600081565b348015610abc57600080fd5b50610413610acb366004614772565b611f20565b348015610adc57600080fd5b50610413610aeb36600461451c565b611f2b565b610413610afe366004614827565b611fbe565b348015610b0f57600080fd5b50610b18600181565b60405161ffff9091168152602001610441565b348015610b3757600080fd5b506104ac7f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd67581565b348015610b6b57600080fd5b50610413610b7a3660046148dc565b611fcd565b348015610b8b57600080fd5b50610413610b9a3660046146cc565b611fff565b348015610bab57600080fd5b5061055561271081565b348015610bc157600080fd5b5061045f610bd03660046142c1565b612055565b348015610be157600080fd5b50610413610bf0366004614947565b6120b1565b348015610c0157600080fd5b50610413610c10366004614326565b612146565b610413610c23366004614175565b6121ca565b348015610c3457600080fd5b50610413610c433660046144ec565b6123e0565b348015610c5457600080fd5b50610413610c633660046149b5565b612405565b348015610c7457600080fd5b5061055560175481565b348015610c8a57600080fd5b50610435610c993660046149f1565b6001600160a01b039182166000908152600f6020908152604080832093909416825291909152205460ff1690565b348015610cd357600080fd5b50610413610ce236600461451c565b6124b7565b348015610cf357600080fd5b50610656610d02366004614a1f565b612511565b348015610d1357600080fd5b50610413610d223660046146cc565b6125dc565b348015610d3357600080fd5b5061045f610d42366004614a98565b612655565b348015610d5357600080fd5b50610555610d623660046142a6565b60086020526000908152604090205481565b337f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd6756001600160a01b031614610df15760405162461bcd60e51b815260206004820152601e60248201527f4c7a4170703a20696e76616c696420656e64706f696e742063616c6c6572000060448201526064015b60405180910390fd5b61ffff861660009081526001602052604081208054610e0f90614ae5565b80601f0160208091040260200160405190810160405280929190818152602001828054610e3b90614ae5565b8015610e885780601f10610e5d57610100808354040283529160200191610e88565b820191906000526020600020905b815481529060010190602001808311610e6b57829003601f168201915b50505050509050805186869050148015610ea3575060008151115b8015610ecb575080516020820120604051610ec19088908890614b20565b6040518091039020145b610f265760405162461bcd60e51b815260206004820152602660248201527f4c7a4170703a20696e76616c696420736f757263652073656e64696e6720636f6044820152651b9d1c9858dd60d21b6064820152608401610de8565b610f9c8787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881528a93509150889088908190840183828082843760009201919091525061270892505050565b50505050505050565b60006001600160e01b031982161580610fc25750610fc282612781565b92915050565b6060600a8054610fd790614ae5565b80601f016020809104026020016040519081016040528092919081815260200182805461100390614ae5565b80156110505780601f1061102557610100808354040283529160200191611050565b820191906000526020600020905b81548152906001019060200180831161103357829003601f168201915b5050505050905090565b6110626127a6565b6040516307e0db1760e01b815261ffff821660048201527f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd6756001600160a01b0316906307e0db17906024015b600060405180830381600087803b1580156110c857600080fd5b505af11580156110dc573d6000803e3d6000fd5b5050505050565b60006110ee82612800565b506000908152600e60205260409020546001600160a01b031690565b6000611115826116cd565b9050806001600160a01b0316836001600160a01b031614156111835760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610de8565b336001600160a01b038216148061119f575061119f8133610c99565b6112115760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c00006064820152608401610de8565b61121b838361285f565b505050565b6112286127a6565b6000811161128e5760405162461bcd60e51b815260206004820152602d60248201527f4f4e46543732313a206d696e476173546f5472616e73666572416e6453746f7260448201526c065206d757374206265203e203609c1b6064820152608401610de8565b600655565b61129b6127a6565b61ffff909116600090815260036020526040902055565b6112ba6127a6565b6040516310ddb13760e01b815261ffff821660048201527f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd6756001600160a01b0316906310ddb137906024016110ae565b611315335b826128cd565b6113315760405162461bcd60e51b8152600401610de890614b30565b61121b83838361294b565b600080611354878761134d88612af2565b8787612511565b915091509550959350505050565b60008281526015602052604090206001015461137d81612b3d565b61121b8383612b47565b600061139283611918565b82106113f45760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610de8565b506001600160a01b03919091166000908152601060209081526040808320938352929052205490565b6001600160a01b038116331461148d5760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610de8565b6114978282612bcd565b5050565b61ffff8316600090815260016020526040812080548291906114bc90614ae5565b80601f01602080910402602001604051908101604052809291908181526020018280546114e890614ae5565b80156115355780601f1061150a57610100808354040283529160200191611535565b820191906000526020600020905b81548152906001019060200180831161151857829003601f168201915b50505050509050838360405161154c929190614b20565b60405180910390208180519060200120149150509392505050565b61121b83838360405180602001604052806000815250611fcd565b61158a6127a6565b6040516342d65a8d60e01b81526001600160a01b037f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd67516906342d65a8d906115da90869086908690600401614ba7565b600060405180830381600087803b1580156115f457600080fd5b505af1158015610f9c573d6000803e3d6000fd5b600061161360125490565b82106116765760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610de8565b6012828154811061168957611689614bc5565b90600052602060002001549050919050565b610f9c8787876116aa88612af2565b878787612c34565b6116ba6127a6565b8051611497906018906020840190613ff2565b6000818152600c60205260408120546001600160a01b031680610fc25760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610de8565b33301461178b5760405162461bcd60e51b815260206004820152602660248201527f4e6f6e626c6f636b696e674c7a4170703a2063616c6c6572206d7573742062656044820152650204c7a4170760d41b6064820152608401610de8565b6118018686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f890181900481028201810190925287815289935091508790879081908401838280828437600092019190915250612e1b92505050565b505050505050565b3360009081526019602052604090205460ff1661182557600080fd5b601754601654111561188a5760405162461bcd60e51b815260206004820152602860248201527f556e6976657273616c4f4e46543732313a206d6178206d696e74206c696d6974604482015267081c995858da195960c21b6064820152608401610de8565b60168054908190600061189c83614bf1565b91905055506114978282612f72565b6118b36127a6565b6001600160a01b038116600081815260196020908152604091829020805460ff81161560ff19909116179055815192835242908301527fbd5dcf0b25226117c4a68a0129ffdd4b0541ef5e482ad7de9a96ccb6d6a8ebde91015b60405180910390a150565b60006001600160a01b0382166119825760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610de8565b506001600160a01b03166000908152600d602052604090205490565b6119a66127a6565b6119b06000612f8c565b565b600160205260009081526040902080546119cb90614ae5565b80601f01602080910402602001604051908101604052809291908181526020018280546119f790614ae5565b8015611a445780601f10611a1957610100808354040283529160200191611a44565b820191906000526020600020905b815481529060010190602001808311611a2757829003601f168201915b505050505081565b80516020808301919091206000818152600990925260409091206002015460ff16611ab95760405162461bcd60e51b815260206004820152601a60248201527f4f4e46543732313a206e6f20637265646974732073746f7265640000000000006044820152606401610de8565b600082806020019051810190611acf9190614c51565b60008481526009602052604081208054600190910154929450909250611b0b9161ffff8216916201000090046001600160a01b03169085612fdc565b6000848152600960205260409020600101549091508111611b895760405162461bcd60e51b815260206004820152603260248201527f4f4e46543732313a206e6f7420656e6f7567682067617320746f2070726f636560448201527139b99031b932b234ba103a3930b739b332b960711b6064820152608401610de8565b8151811415611c015760008381526009602052604080822080546001600160b01b031916815560018101929092556002909101805460ff19169055517fd7be02b8dd0d27bd0517a9cb4d7469ce27df4313821ae5ec1ff69acc594ba23390611bf49085815260200190565b60405180910390a1611c95565b60408051608081018252600085815260096020818152848320805461ffff80821687526001600160a01b03620100008084048216868a019081529989018b8152600160608b01818152998f90529790965297519851169096026001600160b01b03199091169690951695909517939093178455915191830191909155516002909101805491151560ff199092169190911790555b50505050565b60009182526015602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6060600b8054610fd790614ae5565b611cdd6127a6565b81601754108015611ced57508082105b611d395760405162461bcd60e51b815260206004820152601960248201527f4e46543a2052414e47455f544f4b454e5f49445f57524f4e47000000000000006044820152606401610de8565b601682905560178190556040805183815260208101839052428183015290517f7db56eb2742bf8b3ecbd53c305e1b52da85b7d34804466938417948949d91a209181900360600190a15050565b611d8e6127a6565b60008111611df25760405162461bcd60e51b815260206004820152602b60248201527f4f4e46543732313a20647374436861696e4964546f42617463684c696d69742060448201526a06d757374206265203e20360ac1b6064820152608401610de8565b61ffff909116600090815260076020526040902055565b61ffff8116600090815260016020526040812080546060929190611e2c90614ae5565b80601f0160208091040260200160405190810160405280929190818152602001828054611e5890614ae5565b8015611ea55780601f10611e7a57610100808354040283529160200191611ea5565b820191906000526020600020905b815481529060010190602001808311611e8857829003601f168201915b50505050509050805160001415611efe5760405162461bcd60e51b815260206004820152601d60248201527f4c7a4170703a206e6f20747275737465642070617468207265636f72640000006044820152606401610de8565b611f19600060148351611f119190614d0b565b83919061302e565b9392505050565b61149733838361313b565b611f336127a6565b818130604051602001611f4893929190614d22565b60408051601f1981840301815291815261ffff85166000908152600160209081529190208251611f7d93919290910190613ff2565b507f8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce838383604051611fb193929190614ba7565b60405180910390a1505050565b610f9c87878787878787612c34565b611fd733836128cd565b611ff35760405162461bcd60e51b8152600401610de890614b30565b611c958484848461320a565b6120076127a6565b600480546001600160a01b0319166001600160a01b0383169081179091556040519081527f5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b9060200161190d565b606061206082612800565b600061206a61323d565b9050600081511161208a5760405180602001604052806000815250611f19565b8060405160200161209b9190614d48565b6040516020818303038152906040529392505050565b6120b96127a6565b6040516332fb62e760e21b81526001600160a01b037f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd675169063cbed8b9c9061210d9088908890889088908890600401614d75565b600060405180830381600087803b15801561212757600080fd5b505af115801561213b573d6000803e3d6000fd5b505050505050505050565b61214e6127a6565b600081116121b35760405162461bcd60e51b815260206004820152602c60248201527f4f4e46543732313a20647374436861696e4964546f5472616e7366657247617360448201526b0206d757374206265203e20360a41b6064820152608401610de8565b61ffff909116600090815260086020526040902055565b61ffff861660009081526005602052604080822090516121ed9088908890614b20565b90815260408051602092819003830190206001600160401b0387166000908152925290205490508061226d5760405162461bcd60e51b815260206004820152602360248201527f4e6f6e626c6f636b696e674c7a4170703a206e6f2073746f726564206d65737360448201526261676560e81b6064820152608401610de8565b80838360405161227e929190614b20565b6040518091039020146122dd5760405162461bcd60e51b815260206004820152602160248201527f4e6f6e626c6f636b696e674c7a4170703a20696e76616c6964207061796c6f616044820152601960fa1b6064820152608401610de8565b61ffff871660009081526005602052604080822090516123009089908990614b20565b90815260408051602092819003830181206001600160401b038916600090815290845282902093909355601f88018290048202830182019052868252612398918991899089908190840183828082843760009201919091525050604080516020601f8a018190048102820181019092528881528a935091508890889081908401838280828437600092019190915250612e1b92505050565b7fc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e587878787856040516123cf959493929190614dae565b60405180910390a150505050505050565b6000828152601560205260409020600101546123fb81612b3d565b61121b8383612bcd565b61240d6127a6565b600081116124555760405162461bcd60e51b81526020600482015260156024820152744c7a4170703a20696e76616c6964206d696e47617360581b6044820152606401610de8565b61ffff83811660008181526002602090815260408083209487168084529482529182902085905581519283528201929092529081018290527f9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac090606001611fb1565b6124bf6127a6565b61ffff831660009081526001602052604090206124dd908383614076565b507ffa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470dab838383604051611fb193929190614ba7565b60008060008686604051602001612529929190614e24565b60408051601f198184030181529082905263040a7bb160e41b825291506001600160a01b037f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd67516906340a7bb109061258d908b90309086908b908b90600401614e52565b6040805180830381865afa1580156125a9573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125cd9190614ea6565b92509250509550959350505050565b6125e46127a6565b6001600160a01b0381166126495760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610de8565b61265281612f8c565b50565b604051633d7b2f6f60e21b815261ffff808616600483015284166024820152306044820152606481018290526060907f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd6756001600160a01b03169063f5ecbdbc90608401600060405180830381865afa1580156126d5573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526126fd9190810190614eca565b90505b949350505050565b60008061276b5a60966366ad5c8a60e01b898989896040516024016127309493929190614efe565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b0319909316929092179091523092919061324c565b91509150816118015761180186868686856132d6565b60006001600160e01b03198216637965db0b60e01b1480610fc25750610fc282613373565b6000546001600160a01b031633146119b05760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610de8565b6000818152600c60205260409020546001600160a01b03166126525760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610de8565b6000818152600e6020526040902080546001600160a01b0319166001600160a01b0384169081179091558190612894826116cd565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000806128d9836116cd565b9050806001600160a01b0316846001600160a01b0316148061292057506001600160a01b038082166000908152600f602090815260408083209388168352929052205460ff165b806127005750836001600160a01b0316612939846110e3565b6001600160a01b031614949350505050565b826001600160a01b031661295e826116cd565b6001600160a01b0316146129c25760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610de8565b6001600160a01b038216612a245760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610de8565b612a2f838383613398565b612a3a60008261285f565b6001600160a01b0383166000908152600d60205260408120805460019290612a63908490614d0b565b90915550506001600160a01b0382166000908152600d60205260408120805460019290612a91908490614f3c565b90915550506000818152600c602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b60408051600180825281830190925260609160009190602080830190803683370190505090508281600081518110612b2c57612b2c614bc5565b602090810291909101015292915050565b61265281336133ab565b612b518282611c9b565b6114975760008281526015602090815260408083206001600160a01b03851684529091529020805460ff19166001179055612b893390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b612bd78282611c9b565b156114975760008281526015602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000845111612c855760405162461bcd60e51b815260206004820152601a60248201527f4c7a4170703a20746f6b656e4964735b5d20697320656d7074790000000000006044820152606401610de8565b835160011480612ca9575061ffff8616600090815260076020526040902054845111155b612d095760405162461bcd60e51b815260206004820152602b60248201527f4f4e46543732313a2062617463682073697a652065786365656473206473742060448201526a18985d18da081b1a5b5a5d60aa1b6064820152608401610de8565b60005b8451811015612d4c57612d3a888888888581518110612d2d57612d2d614bc5565b602002602001015161340f565b80612d4481614bf1565b915050612d0c565b5060008585604051602001612d62929190614e24565b6040516020818303038152906040529050612da7876001848851600860008d61ffff1661ffff16815260200190815260200160002054612da29190614f54565b6134fa565b612db58782868686346135d9565b85604051612dc39190614f73565b6040518091039020886001600160a01b03168861ffff167fe1b87c47fdeb4f9cbadbca9df3af7aba453bb6e501075d0440d88125b711522a88604051612e099190614f8f565b60405180910390a45050505050505050565b60008082806020019051810190612e329190614c51565b601482015191935091506000612e4a88838386612fdc565b90508251811015612f1e5784516020808701919091206040805160808101825261ffff808d1682526001600160a01b0380881683870190815283850188815260016060860181815260008981526009909a529887902095518654935190941662010000026001600160b01b03199093169390941692909217178355519082015592516002909301805493151560ff199094169390931790925590517f10e0b70d256bccc84b7027506978bd8b68984a870788b93b479def144c839ad790612f149083908990614fa2565b60405180910390a1505b816001600160a01b031687604051612f369190614f73565b60405180910390208961ffff167f5b821db8a46f8ecbe1941ba2f51cfeea9643268b56631f70d45e2a745d99026586604051612e099190614f8f565b61149782826040518060200160405280600081525061377f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000825b82518110156126fd576006545a1015612ff8576126fd565b61301c868685848151811061300f5761300f614bc5565b60200260200101516137b2565b8061302681614bf1565b915050612fe0565b60608161303c81601f614f3c565b101561307b5760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b6044820152606401610de8565b6130858284614f3c565b845110156130c95760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b6044820152606401610de8565b6060821580156130e85760405191506000825260208201604052613132565b6040519150601f8416801560200281840101858101878315602002848b0101015b81831015613121578051835260209283019201613109565b5050858452601f01601f1916604052505b50949350505050565b816001600160a01b0316836001600160a01b0316141561319d5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610de8565b6001600160a01b038381166000818152600f6020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b61321584848461294b565b61322184848484613841565b611c955760405162461bcd60e51b8152600401610de890614fbb565b606060188054610fd790614ae5565b6000606060008060008661ffff166001600160401b0381111561327157613271614383565b6040519080825280601f01601f19166020018201604052801561329b576020820181803683370190505b50905060008087516020890160008d8df191503d9250868311156132bd578692505b828152826000602083013e909890975095505050505050565b8180519060200120600560008761ffff1661ffff168152602001908152602001600020856040516133079190614f73565b9081526040805191829003602090810183206001600160401b0388166000908152915220919091557fe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c90613364908790879087908790879061500d565b60405180910390a15050505050565b60006001600160e01b0319821663780e9d6360e01b1480610fc25750610fc28261393c565b6133a061397c565b61121b8383836139c2565b6133b58282611c9b565b611497576133cd816001600160a01b03166014613a7a565b6133d8836020613a7a565b6040516020016133e992919061505f565b60408051601f198184030181529082905262461bcd60e51b8252610de891600401614293565b6134183361130f565b61347b5760405162461bcd60e51b815260206004820152602e60248201527f4f4e46543732313a2073656e642063616c6c6572206973206e6f74206f776e6560448201526d1c881b9bdc88185c1c1c9bdd995960921b6064820152608401610de8565b836001600160a01b031661348e826116cd565b6001600160a01b0316146134ef5760405162461bcd60e51b815260206004820152602260248201527f4f4e46543732313a2073656e642066726f6d20696e636f7272656374206f776e60448201526132b960f11b6064820152608401610de8565b611c9584308361294b565b600061350583613c15565b61ffff808716600090815260026020908152604080832093891683529290529081205491925090613537908490614f3c565b9050600081116135895760405162461bcd60e51b815260206004820152601a60248201527f4c7a4170703a206d696e4761734c696d6974206e6f74207365740000000000006044820152606401610de8565b808210156118015760405162461bcd60e51b815260206004820152601b60248201527f4c7a4170703a20676173206c696d697420697320746f6f206c6f7700000000006044820152606401610de8565b61ffff8616600090815260016020526040812080546135f790614ae5565b80601f016020809104026020016040519081016040528092919081815260200182805461362390614ae5565b80156136705780601f1061364557610100808354040283529160200191613670565b820191906000526020600020905b81548152906001019060200180831161365357829003601f168201915b505050505090508051600014156136e25760405162461bcd60e51b815260206004820152603060248201527f4c7a4170703a2064657374696e6174696f6e20636861696e206973206e6f742060448201526f61207472757374656420736f7572636560801b6064820152608401610de8565b6136ed878751613c71565b60405162c5803160e81b81526001600160a01b037f00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd675169063c5803100908490613744908b9086908c908c908c908c906004016150d4565b6000604051808303818588803b15801561375d57600080fd5b505af1158015613771573d6000803e3d6000fd5b505050505050505050505050565b6137898383613cdf565b6137966000848484613841565b61121b5760405162461bcd60e51b8152600401610de890614fbb565b6000818152600c60205260409020546001600160a01b0316158061380757506000818152600c60205260409020546001600160a01b0316151580156138075750306137fc826116cd565b6001600160a01b0316145b61381057600080fd5b6000818152600c60205260409020546001600160a01b03166138365761121b8282612f72565b61121b30838361294b565b60006001600160a01b0384163b1561393457604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061388590339089908890889060040161513b565b6020604051808303816000875af19250505080156138c0575060408051601f3d908101601f191682019092526138bd91810190615178565b60015b61391a573d8080156138ee576040519150601f19603f3d011682016040523d82523d6000602084013e6138f3565b606091505b5080516139125760405162461bcd60e51b8152600401610de890614fbb565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050612700565b506001612700565b60006001600160e01b031982166380ac58cd60e01b148061396d57506001600160e01b03198216635b5e139f60e01b145b80610fc25750610fc282613e2d565b60145460ff16156119b05760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610de8565b6001600160a01b038316613a1d57613a1881601280546000838152601360205260408120829055600182018355919091527fbb8a6a4669ba250d26cd7a459eca9d215f8307e33aebe50379bc5a3617ec34440155565b613a40565b816001600160a01b0316836001600160a01b031614613a4057613a408382613e62565b6001600160a01b038216613a575761121b81613eff565b826001600160a01b0316826001600160a01b03161461121b5761121b8282613fae565b60606000613a89836002614f54565b613a94906002614f3c565b6001600160401b03811115613aab57613aab614383565b6040519080825280601f01601f191660200182016040528015613ad5576020820181803683370190505b509050600360fc1b81600081518110613af057613af0614bc5565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110613b1f57613b1f614bc5565b60200101906001600160f81b031916908160001a9053506000613b43846002614f54565b613b4e906001614f3c565b90505b6001811115613bc6576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110613b8257613b82614bc5565b1a60f81b828281518110613b9857613b98614bc5565b60200101906001600160f81b031916908160001a90535060049490941c93613bbf81615195565b9050613b51565b508315611f195760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610de8565b6000602282511015613c695760405162461bcd60e51b815260206004820152601c60248201527f4c7a4170703a20696e76616c69642061646170746572506172616d73000000006044820152606401610de8565b506022015190565b61ffff821660009081526003602052604090205480613c8f57506127105b8082111561121b5760405162461bcd60e51b815260206004820181905260248201527f4c7a4170703a207061796c6f61642073697a6520697320746f6f206c617267656044820152606401610de8565b6001600160a01b038216613d355760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610de8565b6000818152600c60205260409020546001600160a01b031615613d9a5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610de8565b613da660008383613398565b6001600160a01b0382166000908152600d60205260408120805460019290613dcf908490614f3c565b90915550506000818152600c602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001600160e01b031982166322bac5d960e01b1480610fc257506301ffc9a760e01b6001600160e01b0319831614610fc2565b60006001613e6f84611918565b613e799190614d0b565b600083815260116020526040902054909150808214613ecc576001600160a01b03841660009081526010602090815260408083208584528252808320548484528184208190558352601190915290208190555b5060009182526011602090815260408084208490556001600160a01b039094168352601081528383209183525290812055565b601254600090613f1190600190614d0b565b60008381526013602052604081205460128054939450909284908110613f3957613f39614bc5565b906000526020600020015490508060128381548110613f5a57613f5a614bc5565b6000918252602080832090910192909255828152601390915260408082208490558582528120556012805480613f9257613f926151ac565b6001900381819060005260206000200160009055905550505050565b6000613fb983611918565b6001600160a01b039093166000908152601060209081526040808320868452825280832085905593825260119052919091209190915550565b828054613ffe90614ae5565b90600052602060002090601f0160209004810192826140205760008555614066565b82601f1061403957805160ff1916838001178555614066565b82800160010185558215614066579182015b8281111561406657825182559160200191906001019061404b565b506140729291506140ea565b5090565b82805461408290614ae5565b90600052602060002090601f0160209004810192826140a45760008555614066565b82601f106140bd5782800160ff19823516178555614066565b82800160010185558215614066579182015b828111156140665782358255916020019190600101906140cf565b5b8082111561407257600081556001016140eb565b803561ffff8116811461411157600080fd5b919050565b60008083601f84011261412857600080fd5b5081356001600160401b0381111561413f57600080fd5b60208301915083602082850101111561415757600080fd5b9250929050565b80356001600160401b038116811461411157600080fd5b6000806000806000806080878903121561418e57600080fd5b614197876140ff565b955060208701356001600160401b03808211156141b357600080fd5b6141bf8a838b01614116565b90975095508591506141d360408a0161415e565b945060608901359150808211156141e957600080fd5b506141f689828a01614116565b979a9699509497509295939492505050565b6001600160e01b03198116811461265257600080fd5b60006020828403121561423057600080fd5b8135611f1981614208565b60005b8381101561425657818101518382015260200161423e565b83811115611c955750506000910152565b6000815180845261427f81602086016020860161423b565b601f01601f19169290920160200192915050565b602081526000611f196020830184614267565b6000602082840312156142b857600080fd5b611f19826140ff565b6000602082840312156142d357600080fd5b5035919050565b6001600160a01b038116811461265257600080fd5b8035614111816142da565b6000806040838503121561430d57600080fd5b8235614318816142da565b946020939093013593505050565b6000806040838503121561433957600080fd5b614318836140ff565b60008060006060848603121561435757600080fd5b8335614362816142da565b92506020840135614372816142da565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156143c1576143c1614383565b604052919050565b60006001600160401b038211156143e2576143e2614383565b50601f01601f191660200190565b60006144036143fe846143c9565b614399565b905082815283838301111561441757600080fd5b828260208301376000602084830101529392505050565b600082601f83011261443f57600080fd5b611f19838335602085016143f0565b8035801515811461411157600080fd5b600080600080600060a0868803121561447657600080fd5b61447f866140ff565b945060208601356001600160401b038082111561449b57600080fd5b6144a789838a0161442e565b9550604088013594506144bc6060890161444e565b935060808801359150808211156144d257600080fd5b506144df8882890161442e565b9150509295509295909350565b600080604083850312156144ff57600080fd5b823591506020830135614511816142da565b809150509250929050565b60008060006040848603121561453157600080fd5b61453a846140ff565b925060208401356001600160401b0381111561455557600080fd5b61456186828701614116565b9497909650939450505050565b600080600080600080600060e0888a03121561458957600080fd5b8735614594816142da565b96506145a2602089016140ff565b955060408801356001600160401b03808211156145be57600080fd5b6145ca8b838c0161442e565b965060608a0135955060808a013591506145e3826142da565b90935060a0890135906145f5826142da565b90925060c0890135908082111561460b57600080fd5b506146188a828b0161442e565b91505092959891949750929550565b60006020828403121561463957600080fd5b81356001600160401b0381111561464f57600080fd5b8201601f8101841361466057600080fd5b612700848235602084016143f0565b60008060006060848603121561468457600080fd5b61468d846140ff565b925060208401356001600160401b038111156146a857600080fd5b6146b48682870161442e565b9250506146c36040850161415e565b90509250925092565b6000602082840312156146de57600080fd5b8135611f19816142da565b600080604083850312156146fc57600080fd5b614705836140ff565b9150614713602084016140ff565b90509250929050565b60006020828403121561472e57600080fd5b81356001600160401b0381111561474457600080fd5b6127008482850161442e565b6000806040838503121561476357600080fd5b50508035926020909101359150565b6000806040838503121561478557600080fd5b8235614790816142da565b91506147136020840161444e565b60006001600160401b038211156147b7576147b7614383565b5060051b60200190565b600082601f8301126147d257600080fd5b813560206147e26143fe8361479e565b82815260059290921b8401810191818101908684111561480157600080fd5b8286015b8481101561481c5780358352918301918301614805565b509695505050505050565b600080600080600080600060e0888a03121561484257600080fd5b873561484d816142da565b965061485b602089016140ff565b955060408801356001600160401b038082111561487757600080fd5b6148838b838c0161442e565b965060608a013591508082111561489957600080fd5b6148a58b838c016147c1565b955060808a013591506148b7826142da565b8194506148c660a08b016142ef565b935060c08a013591508082111561460b57600080fd5b600080600080608085870312156148f257600080fd5b84356148fd816142da565b9350602085013561490d816142da565b92506040850135915060608501356001600160401b0381111561492f57600080fd5b61493b8782880161442e565b91505092959194509250565b60008060008060006080868803121561495f57600080fd5b614968866140ff565b9450614976602087016140ff565b93506040860135925060608601356001600160401b0381111561499857600080fd5b6149a488828901614116565b969995985093965092949392505050565b6000806000606084860312156149ca57600080fd5b6149d3846140ff565b92506149e1602085016140ff565b9150604084013590509250925092565b60008060408385031215614a0457600080fd5b8235614a0f816142da565b91506020830135614511816142da565b600080600080600060a08688031215614a3757600080fd5b614a40866140ff565b945060208601356001600160401b0380821115614a5c57600080fd5b614a6889838a0161442e565b95506040880135915080821115614a7e57600080fd5b614a8a89838a016147c1565b94506144bc6060890161444e565b60008060008060808587031215614aae57600080fd5b614ab7856140ff565b9350614ac5602086016140ff565b92506040850135614ad5816142da565b9396929550929360600135925050565b600181811c90821680614af957607f821691505b60208210811415614b1a57634e487b7160e01b600052602260045260246000fd5b50919050565b8183823760009101908152919050565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b61ffff841681526040602082015260006126fd604083018486614b7e565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b6000600019821415614c0557614c05614bdb565b5060010190565b600082601f830112614c1d57600080fd5b8151614c2b6143fe826143c9565b818152846020838601011115614c4057600080fd5b61270082602083016020870161423b565b60008060408385031215614c6457600080fd5b82516001600160401b0380821115614c7b57600080fd5b614c8786838701614c0c565b9350602091508185015181811115614c9e57600080fd5b85019050601f81018613614cb157600080fd5b8051614cbf6143fe8261479e565b81815260059190911b82018301908381019088831115614cde57600080fd5b928401925b82841015614cfc57835182529284019290840190614ce3565b80955050505050509250929050565b600082821015614d1d57614d1d614bdb565b500390565b8284823760609190911b6bffffffffffffffffffffffff19169101908152601401919050565b60008251614d5a81846020870161423b565b683830b9b9973539b7b760b91b920191825250600901919050565b600061ffff808816835280871660208401525084604083015260806060830152614da3608083018486614b7e565b979650505050505050565b61ffff86168152608060208201526000614dcc608083018688614b7e565b6001600160401b0394909416604083015250606001529392505050565b600081518084526020808501945080840160005b83811015614e1957815187529582019590820190600101614dfd565b509495945050505050565b604081526000614e376040830185614267565b8281036020840152614e498185614de9565b95945050505050565b61ffff861681526001600160a01b038516602082015260a060408201819052600090614e8090830186614267565b84151560608401528281036080840152614e9a8185614267565b98975050505050505050565b60008060408385031215614eb957600080fd5b505080516020909101519092909150565b600060208284031215614edc57600080fd5b81516001600160401b03811115614ef257600080fd5b61270084828501614c0c565b61ffff85168152608060208201526000614f1b6080830186614267565b6001600160401b03851660408401528281036060840152614da38185614267565b60008219821115614f4f57614f4f614bdb565b500190565b6000816000190483118215151615614f6e57614f6e614bdb565b500290565b60008251614f8581846020870161423b565b9190910192915050565b602081526000611f196020830184614de9565b8281526040602082015260006127006040830184614267565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b61ffff8616815260a06020820152600061502a60a0830187614267565b6001600160401b0386166040840152828103606084015261504b8186614267565b90508281036080840152614e9a8185614267565b7f416363657373436f6e74726f6c3a206163636f756e742000000000000000000081526000835161509781601785016020880161423b565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516150c881602884016020880161423b565b01602801949350505050565b61ffff8716815260c0602082015260006150f160c0830188614267565b82810360408401526151038188614267565b6001600160a01b0387811660608601528616608085015283810360a0850152905061512e8185614267565b9998505050505050505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061516e90830184614267565b9695505050505050565b60006020828403121561518a57600080fd5b8151611f1981614208565b6000816151a4576151a4614bdb565b506000190190565b634e487b7160e01b600052603160045260246000fdfea26469706673582212209bf4e74d33912aceb8133ff3eec9cd4434ae1623fda0887647cfe8e44a8d0cd964736f6c634300080c0033

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

000000000000000000000000000000000000000000000000000000000000000100000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd67500000000000000000000000000000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000002710

-----Decoded View---------------
Arg [0] : _minGasToStore (uint256): 1
Arg [1] : _layerZeroEndpoint (address): 0x66A71Dcef29A0fFBDBE3c6a460a3B5BC225Cd675
Arg [2] : _startMintId (uint256): 1
Arg [3] : _endMintId (uint256): 10000

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [1] : 00000000000000000000000066a71dcef29a0ffbdbe3c6a460a3b5bc225cd675
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [3] : 0000000000000000000000000000000000000000000000000000000000002710


Deployed Bytecode Sourcemap

118372:256:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40938:762;;;;;;;;;;-1:-1:-1;40938:762:0;;;;;:::i;:::-;;:::i;:::-;;114596:261;;;;;;;;;;-1:-1:-1;114596:261:0;;;;;:::i;:::-;;:::i;:::-;;;2124:14:1;;2117:22;2099:41;;2087:2;2072:18;114596:261:0;;;;;;;;79634:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;44236:123::-;;;;;;;;;;-1:-1:-1;44236:123:0;;;;;:::i;:::-;;:::i;81140:171::-;;;;;;;;;;-1:-1:-1;81140:171:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;3440:32:1;;;3422:51;;3410:2;3395:18;81140:171:0;3276:203:1;80657:417:0;;;;;;;;;;-1:-1:-1;80657:417:0;;;;;:::i;:::-;;:::i;62930:260::-;;;;;;;;;;-1:-1:-1;62930:260:0;;;;;:::i;:::-;;:::i;46152:142::-;;;;;;;;;;-1:-1:-1;46152:142:0;;;;;:::i;:::-;;:::i;44367:129::-;;;;;;;;;;-1:-1:-1;44367:129:0;;;;;:::i;:::-;;:::i;94627:113::-;;;;;;;;;;-1:-1:-1;94715:10:0;:17;94627:113;;;4482:25:1;;;4470:2;4455:18;94627:113:0;4336:177:1;57082:53:0;;;;;;;;;;-1:-1:-1;57082:53:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;57082:53:0;;;;;;;;;;;4956:6:1;4944:19;;;4926:38;;-1:-1:-1;;;;;5000:32:1;;;4995:2;4980:18;;4973:60;5049:18;;;5042:34;5119:14;5112:22;5107:2;5092:18;;5085:50;4913:3;4898:19;57082:53:0;4703:438:1;81840:336:0;;;;;;;;;;-1:-1:-1;81840:336:0;;;;;:::i;:::-;;:::i;110267:131::-;;;;;;;;;;-1:-1:-1;110267:131:0;;;;;:::i;:::-;110341:7;110368:12;;;:6;:12;;;;;:22;;;;110267:131;57646:320;;;;;;;;;;-1:-1:-1;57646:320:0;;;;;:::i;:::-;;:::i;:::-;;;;8051:25:1;;;8107:2;8092:18;;8085:34;;;;8024:18;57646:320:0;7877:248:1;110708:147:0;;;;;;;;;;-1:-1:-1;110708:147:0;;;;;:::i;:::-;;:::i;94295:256::-;;;;;;;;;;-1:-1:-1;94295:256:0;;;;;:::i;:::-;;:::i;111852:218::-;;;;;;;;;;-1:-1:-1;111852:218:0;;;;;:::i;:::-;;:::i;46392:250::-;;;;;;;;;;-1:-1:-1;46392:250:0;;;;;:::i;:::-;;:::i;40480:53::-;;;;;;;;;;-1:-1:-1;40480:53:0;;;;;:::i;:::-;;;;;;;;;;;;;;82247:185;;;;;;;;;;-1:-1:-1;82247:185:0;;;;;:::i;:::-;;:::i;44504:178::-;;;;;;;;;;-1:-1:-1;44504:178:0;;;;;:::i;:::-;;:::i;56772:39::-;;;;;;;;;;;;;;;;56888:56;;;;;;;;;;-1:-1:-1;56888:56:0;;;;;:::i;:::-;;;;;;;;;;;;;;94817:233;;;;;;;;;;-1:-1:-1;94817:233:0;;;;;:::i;:::-;;:::i;58370:351::-;;;;;;:::i;:::-;;:::i;117141:100::-;;;;;;;;;;-1:-1:-1;117141:100:0;;;;;:::i;:::-;;:::i;52806:85::-;;;;;;;;;;-1:-1:-1;52806:85:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;101815:86;;;;;;;;;;-1:-1:-1;101886:7:0;;;;101815:86;;79345:222;;;;;;;;;;-1:-1:-1;79345:222:0;;;;;:::i;:::-;;:::i;116157:37::-;;;;;;;;;;-1:-1:-1;116157:37:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;54028:346;;;;;;;;;;-1:-1:-1;54028:346:0;;;;;:::i;:::-;;:::i;117725:259::-;;;;;;;;;;-1:-1:-1;117725:259:0;;;;;:::i;:::-;;:::i;116043:22::-;;;;;;;;;;;;;;;;117249:153;;;;;;;;;;-1:-1:-1;117249:153:0;;;;;:::i;:::-;;:::i;79076:207::-;;;;;;;;;;-1:-1:-1;79076:207:0;;;;;:::i;:::-;;:::i;12252:103::-;;;;;;;;;;;;;:::i;40350:51::-;;;;;;;;;;-1:-1:-1;40350:51:0;;;;;:::i;:::-;;:::i;40408:65::-;;;;;;;;;;-1:-1:-1;40408:65:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;11604:87;;;;;;;;;;-1:-1:-1;11650:7:0;11677:6;-1:-1:-1;;;;;11677:6:0;11604:87;;61143:1006;;;;;;;;;;-1:-1:-1;61143:1006:0;;;;;:::i;:::-;;:::i;108727:147::-;;;;;;;;;;-1:-1:-1;108727:147:0;;;;;:::i;:::-;;:::i;40540:23::-;;;;;;;;;;-1:-1:-1;40540:23:0;;;;-1:-1:-1;;;;;40540:23:0;;;79803:104;;;;;;;;;;;;;:::i;117410:277::-;;;;;;;;;;-1:-1:-1;117410:277:0;;;;;:::i;:::-;;:::i;63642:281::-;;;;;;;;;;-1:-1:-1;63642:281:0;;;;;:::i;:::-;;:::i;45324:330::-;;;;;;;;;;-1:-1:-1;45324:330:0;;;;;:::i;:::-;;:::i;107832:49::-;;;;;;;;;;-1:-1:-1;107832:49:0;107877:4;107832:49;;81383:155;;;;;;;;;;-1:-1:-1;81383:155:0;;;;;:::i;:::-;;:::i;45035:281::-;;;;;;;;;;-1:-1:-1;45035:281:0;;;;;:::i;:::-;;:::i;58729:348::-;;;;;;:::i;:::-;;:::i;56535:45::-;;;;;;;;;;;;56579:1;56535:45;;;;;14840:6:1;14828:19;;;14810:38;;14798:2;14783:18;56535:45:0;14666:188:1;40297:46:0;;;;;;;;;;;;;;;82503:323;;;;;;;;;;-1:-1:-1;82503:323:0;;;;;:::i;:::-;;:::i;45662:136::-;;;;;;;;;;-1:-1:-1;45662:136:0;;;;;:::i;:::-;;:::i;40233:55::-;;;;;;;;;;;;40283:5;40233:55;;79978:274;;;;;;;;;;-1:-1:-1;79978:274:0;;;;;:::i;:::-;;:::i;44024:204::-;;;;;;;;;;-1:-1:-1;44024:204:0;;;;;:::i;:::-;;:::i;63291:287::-;;;;;;;;;;-1:-1:-1;63291:287:0;;;;;:::i;:::-;;:::i;54560:767::-;;;;;;:::i;:::-;;:::i;111148:149::-;;;;;;;;;;-1:-1:-1;111148:149:0;;;;;:::i;:::-;;:::i;45806:284::-;;;;;;;;;;-1:-1:-1;45806:284:0;;;;;:::i;:::-;;:::i;116072:21::-;;;;;;;;;;;;;;;;81609:164;;;;;;;;;;-1:-1:-1;81609:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;81730:25:0;;;81706:4;81730:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;81609:164;44829:198;;;;;;;;;;-1:-1:-1;44829:198:0;;;;;:::i;:::-;;:::i;57974:388::-;;;;;;;;;;-1:-1:-1;57974:388:0;;;;;:::i;:::-;;:::i;12510:201::-;;;;;;;;;;-1:-1:-1;12510:201:0;;;;;:::i;:::-;;:::i;43751:211::-;;;;;;;;;;-1:-1:-1;43751:211:0;;;;;:::i;:::-;;:::i;56951:57::-;;;;;;;;;;-1:-1:-1;56951:57:0;;;;;:::i;:::-;;;;;;;;;;;;;;40938:762;10228:10;41178;-1:-1:-1;;;;;41154:35:0;;41146:78;;;;-1:-1:-1;;;41146:78:0;;18691:2:1;41146:78:0;;;18673:21:1;18730:2;18710:18;;;18703:30;18769:32;18749:18;;;18742:60;18819:18;;41146:78:0;;;;;;;;;41266:32;;;41237:26;41266:32;;;:19;:32;;;;;41237:61;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41472:13;:20;41450:11;;:18;;:42;:70;;;;;41519:1;41496:13;:20;:24;41450:70;:124;;;;-1:-1:-1;41550:24:0;;;;;;41524:22;;;;41534:11;;;;41524:22;:::i;:::-;;;;;;;;:50;41450:124;41442:175;;;;-1:-1:-1;;;41442:175:0;;19711:2:1;41442:175:0;;;19693:21:1;19750:2;19730:18;;;19723:30;19789:34;19769:18;;;19762:62;-1:-1:-1;;;19840:18:1;;;19833:36;19886:19;;41442:175:0;19509:402:1;41442:175:0;41630:62;41649:11;41662;;41630:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;41630:62:0;;;;;;;;;;;;;;;;;;;;;;41675:6;;-1:-1:-1;41630:62:0;-1:-1:-1;41683:8:0;;;;;;41630:62;;41683:8;;;;41630:62;;;;;;;;;-1:-1:-1;41630:18:0;;-1:-1:-1;;;41630:62:0:i;:::-;41069:631;40938:762;;;;;;:::o;114596:261::-;114744:4;-1:-1:-1;;;;;;114768:41:0;;;;:81;;;114813:36;114837:11;114813:23;:36::i;:::-;114761:88;114596:261;-1:-1:-1;;114596:261:0:o;79634:100::-;79688:13;79721:5;79714:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79634:100;:::o;44236:123::-;11490:13;:11;:13::i;:::-;44316:35:::1;::::0;-1:-1:-1;;;44316:35:0;;14840:6:1;14828:19;;44316:35:0::1;::::0;::::1;14810:38:1::0;44316:10:0::1;-1:-1:-1::0;;;;;44316:25:0::1;::::0;::::1;::::0;14783:18:1;;44316:35:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;44236:123:::0;:::o;81140:171::-;81216:7;81236:23;81251:7;81236:14;:23::i;:::-;-1:-1:-1;81279:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;81279:24:0;;81140:171::o;80657:417::-;80738:13;80754:23;80769:7;80754:14;:23::i;:::-;80738:39;;80802:5;-1:-1:-1;;;;;80796:11:0;:2;-1:-1:-1;;;;;80796:11:0;;;80788:57;;;;-1:-1:-1;;;80788:57:0;;20118:2:1;80788:57:0;;;20100:21:1;20157:2;20137:18;;;20130:30;20196:34;20176:18;;;20169:62;-1:-1:-1;;;20247:18:1;;;20240:31;20288:19;;80788:57:0;19916:397:1;80788:57:0;10228:10;-1:-1:-1;;;;;80880:21:0;;;;:62;;-1:-1:-1;80905:37:0;80922:5;10228:10;81609:164;:::i;80905:37::-;80858:174;;;;-1:-1:-1;;;80858:174:0;;20520:2:1;80858:174:0;;;20502:21:1;20559:2;20539:18;;;20532:30;20598:34;20578:18;;;20571:62;20669:32;20649:18;;;20642:60;20719:19;;80858:174:0;20318:426:1;80858:174:0;81045:21;81054:2;81058:7;81045:8;:21::i;:::-;80727:347;80657:417;;:::o;62930:260::-;11490:13;:11;:13::i;:::-;63068:1:::1;63040:25;:29;63032:87;;;::::0;-1:-1:-1;;;63032:87:0;;20951:2:1;63032:87:0::1;::::0;::::1;20933:21:1::0;20990:2;20970:18;;;20963:30;21029:34;21009:18;;;21002:62;-1:-1:-1;;;21080:18:1;;;21073:43;21133:19;;63032:87:0::1;20749:409:1::0;63032:87:0::1;63130:24;:52:::0;62930:260::o;46152:142::-;11490:13;:11;:13::i;:::-;46243:35:::1;::::0;;::::1;;::::0;;;:22:::1;:35;::::0;;;;:43;46152:142::o;44367:129::-;11490:13;:11;:13::i;:::-;44450:38:::1;::::0;-1:-1:-1;;;44450:38:0;;14840:6:1;14828:19;;44450:38:0::1;::::0;::::1;14810::1::0;44450:10:0::1;-1:-1:-1::0;;;;;44450:28:0::1;::::0;::::1;::::0;14783:18:1;;44450:38:0::1;14666:188:1::0;81840:336:0;82035:41;10228:10;82054:12;82068:7;82035:18;:41::i;:::-;82027:100;;;;-1:-1:-1;;;82027:100:0;;;;;;;:::i;:::-;82140:28;82150:4;82156:2;82160:7;82140:9;:28::i;57646:320::-;57812:14;57828:11;57859:99;57880:11;57893:10;57905:27;57923:8;57905:17;:27::i;:::-;57934:7;57943:14;57859:20;:99::i;:::-;57852:106;;;;57646:320;;;;;;;;:::o;110708:147::-;110341:7;110368:12;;;:6;:12;;;;;:22;;;108323:16;108334:4;108323:10;:16::i;:::-;110822:25:::1;110833:4;110839:7;110822:10;:25::i;94295:256::-:0;94392:7;94428:23;94445:5;94428:16;:23::i;:::-;94420:5;:31;94412:87;;;;-1:-1:-1;;;94412:87:0;;21780:2:1;94412:87:0;;;21762:21:1;21819:2;21799:18;;;21792:30;21858:34;21838:18;;;21831:62;-1:-1:-1;;;21909:18:1;;;21902:41;21960:19;;94412:87:0;21578:407:1;94412:87:0;-1:-1:-1;;;;;;94517:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;94295:256::o;111852:218::-;-1:-1:-1;;;;;111948:23:0;;10228:10;111948:23;111940:83;;;;-1:-1:-1;;;111940:83:0;;22192:2:1;111940:83:0;;;22174:21:1;22231:2;22211:18;;;22204:30;22270:34;22250:18;;;22243:62;-1:-1:-1;;;22321:18:1;;;22314:45;22376:19;;111940:83:0;21990:411:1;111940:83:0;112036:26;112048:4;112054:7;112036:11;:26::i;:::-;111852:218;;:::o;46392:250::-;46534:32;;;46488:4;46534:32;;;:19;:32;;;;;46505:61;;46488:4;;46534:32;46505:61;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46622:11;;46612:22;;;;;;;:::i;:::-;;;;;;;;46594:13;46584:24;;;;;;:50;46577:57;;;46392:250;;;;;:::o;82247:185::-;82385:39;82402:4;82408:2;82412:7;82385:39;;;;;;;;;;;;:16;:39::i;44504:178::-;11490:13;:11;:13::i;:::-;44619:55:::1;::::0;-1:-1:-1;;;44619:55:0;;-1:-1:-1;;;;;44619:10:0::1;:29;::::0;::::1;::::0;:55:::1;::::0;44649:11;;44662;;;;44619:55:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;94817:233:::0;94892:7;94928:30;94715:10;:17;;94627:113;94928:30;94920:5;:38;94912:95;;;;-1:-1:-1;;;94912:95:0;;23210:2:1;94912:95:0;;;23192:21:1;23249:2;23229:18;;;23222:30;23288:34;23268:18;;;23261:62;-1:-1:-1;;;23339:18:1;;;23332:42;23391:19;;94912:95:0;23008:408:1;94912:95:0;95025:10;95036:5;95025:17;;;;;;;;:::i;:::-;;;;;;;;;95018:24;;94817:233;;;:::o;58370:351::-;58595:118;58601:5;58608:11;58621:10;58633:27;58651:8;58633:17;:27::i;:::-;58662:14;58678:18;58698:14;58595:5;:118::i;117141:100::-;11490:13;:11;:13::i;:::-;117215:18;;::::1;::::0;:7:::1;::::0;:18:::1;::::0;::::1;::::0;::::1;:::i;79345:222::-:0;79417:7;79453:16;;;:7;:16;;;;;;-1:-1:-1;;;;;79453:16:0;79488:19;79480:56;;;;-1:-1:-1;;;79480:56:0;;23755:2:1;79480:56:0;;;23737:21:1;23794:2;23774:18;;;23767:30;-1:-1:-1;;;23813:18:1;;;23806:54;23877:18;;79480:56:0;23553:348:1;54028:346:0;10228:10;54242:4;54218:29;54210:80;;;;-1:-1:-1;;;54210:80:0;;24108:2:1;54210:80:0;;;24090:21:1;24147:2;24127:18;;;24120:30;24186:34;24166:18;;;24159:62;-1:-1:-1;;;24237:18:1;;;24230:36;24283:19;;54210:80:0;23906:402:1;54210:80:0;54301:65;54323:11;54336;;54301:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;54301:65:0;;;;;;;;;;;;;;;;;;;;;;54349:6;;-1:-1:-1;54301:65:0;-1:-1:-1;54357:8:0;;;;;;54301:65;;54357:8;;;;54301:65;;;;;;;;;-1:-1:-1;54301:21:0;;-1:-1:-1;;;54301:65:0:i;:::-;54028:346;;;;;;:::o;117725:259::-;117785:10;117779:17;;;;:5;:17;;;;;;;;117771:26;;;;;;117830:9;;117816:10;;:23;;117808:76;;;;-1:-1:-1;;;117808:76:0;;24515:2:1;117808:76:0;;;24497:21:1;24554:2;24534:18;;;24527:30;24593:34;24573:18;;;24566:62;-1:-1:-1;;;24644:18:1;;;24637:38;24692:19;;117808:76:0;24313:404:1;117808:76:0;117910:10;;;;;;117897;117931:12;117910:10;117931:12;:::i;:::-;;;;;;117956:20;117966:2;117970:5;117956:9;:20::i;117249:153::-;11490:13;:11;:13::i;:::-;-1:-1:-1;;;;;117332:13:0;::::1;;::::0;;;:5:::1;:13;::::0;;;;;;;;;;::::1;::::0;::::1;117331:14;-1:-1:-1::0;;117315:30:0;;::::1;;::::0;;117361:33;;25168:51:1;;;117378:15:0::1;25235:18:1::0;;;25228:34;117361:33:0::1;::::0;25141:18:1;117361:33:0::1;;;;;;;;117249:153:::0;:::o;79076:207::-;79148:7;-1:-1:-1;;;;;79176:19:0;;79168:73;;;;-1:-1:-1;;;79168:73:0;;25475:2:1;79168:73:0;;;25457:21:1;25514:2;25494:18;;;25487:30;25553:34;25533:18;;;25526:62;-1:-1:-1;;;25604:18:1;;;25597:39;25653:19;;79168:73:0;25273:405:1;79168:73:0;-1:-1:-1;;;;;;79259:16:0;;;;;:9;:16;;;;;;;79076:207::o;12252:103::-;11490:13;:11;:13::i;:::-;12317:30:::1;12344:1;12317:18;:30::i;:::-;12252:103::o:0;40350:51::-;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;61143:1006::-;61232:19;;;;;;;;;;61208:21;61270:28;;;:13;:28;;;;;;;:42;;;;;61262:81;;;;-1:-1:-1;;;61262:81:0;;25885:2:1;61262:81:0;;;25867:21:1;25924:2;25904:18;;;25897:30;25963:28;25943:18;;;25936:56;26009:18;;61262:81:0;25683:350:1;61262:81:0;61359:22;61396:8;61385:37;;;;;;;;;;;;:::i;:::-;61435:14;61464:28;;;:13;:28;;;;;:39;;;61545:34;;;;61356:66;;-1:-1:-1;61435:14:0;;-1:-1:-1;61452:138:0;;61464:39;;;;61505:38;;;-1:-1:-1;;;;;61505:38:0;;61356:66;61452:11;:138::i;:::-;61621:28;;;;:13;:28;;;;;:34;;;61435:155;;-1:-1:-1;61609:46:0;;61601:109;;;;-1:-1:-1;;;61601:109:0;;27782:2:1;61601:109:0;;;27764:21:1;27821:2;27801:18;;;27794:30;27860:34;27840:18;;;27833:62;-1:-1:-1;;;27911:18:1;;;27904:48;27969:19;;61601:109:0;27580:414:1;61601:109:0;61740:8;:15;61727:9;:28;61723:419;;;61835:28;;;;:13;:28;;;;;;61828:35;;-1:-1:-1;;;;;;61828:35:0;;;;;;;;;;;;;;;;-1:-1:-1;;61828:35:0;;;61883:28;;;;;61849:13;4482:25:1;;4470:2;4455:18;;4336:177;61883:28:0;;;;;;;;61723:419;;;62020:110;;;;;;;;-1:-1:-1;62033:28:0;;;:13;:28;;;;;;;:39;;;;;;62020:110;;-1:-1:-1;;;;;62074:38:0;;;;;;62020:110;;;;;;;;;;;;62033:39;62020:110;;;;;;61989:28;;;;;;;;:141;;;;;;;;-1:-1:-1;;;;;;61989:141:0;;;;;;;;;;;;;;;;;;;;;;;;;;;62074:38;61989:141;;;;;;;;-1:-1:-1;;61989:141:0;;;;;;;;;61723:419;61197:952;;;61143:1006;:::o;108727:147::-;108813:4;108837:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;108837:29:0;;;;;;;;;;;;;;;108727:147::o;79803:104::-;79859:13;79892:7;79885:14;;;;;:::i;117410:277::-;11490:13;:11;:13::i;:::-;117512:4:::1;117500:9;;:16;:31;;;;;117527:4;117520;:11;117500:31;117492:69;;;::::0;-1:-1:-1;;;117492:69:0;;28201:2:1;117492:69:0::1;::::0;::::1;28183:21:1::0;28240:2;28220:18;;;28213:30;28279:27;28259:18;;;28252:55;28324:18;;117492:69:0::1;27999:349:1::0;117492:69:0::1;117572:10;:17:::0;;;117600:9:::1;:16:::0;;;117632:47:::1;::::0;;28555:25:1;;;28611:2;28596:18;;28589:34;;;117663:15:0::1;28639:18:1::0;;;28632:34;117632:47:0;;::::1;::::0;;;;28543:2:1;117632:47:0;;::::1;117410:277:::0;;:::o;63642:281::-;11490:13;:11;:13::i;:::-;63794:1:::1;63768:23;:27;63760:83;;;::::0;-1:-1:-1;;;63760:83:0;;28879:2:1;63760:83:0::1;::::0;::::1;28861:21:1::0;28918:2;28898:18;;;28891:30;28957:34;28937:18;;;28930:62;-1:-1:-1;;;29008:18:1;;;29001:41;29059:19;;63760:83:0::1;28677:407:1::0;63760:83:0::1;63854:35;::::0;;::::1;;::::0;;;:22:::1;:35;::::0;;;;:61;63642:281::o;45324:330::-;45448:35;;;45428:17;45448:35;;;:19;:35;;;;;45428:55;;45403:12;;45428:17;45448:35;45428:55;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45502:4;:11;45517:1;45502:16;;45494:58;;;;-1:-1:-1;;;45494:58:0;;29291:2:1;45494:58:0;;;29273:21:1;29330:2;29310:18;;;29303:30;29369:31;29349:18;;;29342:59;29418:18;;45494:58:0;29089:353:1;45494:58:0;45570:31;45581:1;45598:2;45584:4;:11;:16;;;;:::i;:::-;45570:4;;:31;:10;:31::i;:::-;45563:38;45324:330;-1:-1:-1;;;45324:330:0:o;81383:155::-;81478:52;10228:10;81511:8;81521;81478:18;:52::i;45035:281::-;11490:13;:11;:13::i;:::-;45207:14:::1;;45231:4;45190:47;;;;;;;;;;:::i;:::-;;::::0;;-1:-1:-1;;45190:47:0;;::::1;::::0;;;;;;45152:35:::1;::::0;::::1;;::::0;;;:19:::1;45190:47;45152:35:::0;;;;;;:85;;::::1;::::0;:35;;:85;;::::1;::::0;::::1;:::i;:::-;;45253:55;45277:14;45293;;45253:55;;;;;;;;:::i;:::-;;;;;;;;45035:281:::0;;;:::o;58729:348::-;58969:100;58975:5;58982:11;58995:10;59007:9;59018:14;59034:18;59054:14;58969:5;:100::i;82503:323::-;82677:41;10228:10;82710:7;82677:18;:41::i;:::-;82669:100;;;;-1:-1:-1;;;82669:100:0;;;;;;;:::i;:::-;82780:38;82794:4;82800:2;82804:7;82813:4;82780:13;:38::i;45662:136::-;11490:13;:11;:13::i;:::-;45732:8:::1;:20:::0;;-1:-1:-1;;;;;;45732:20:0::1;-1:-1:-1::0;;;;;45732:20:0;::::1;::::0;;::::1;::::0;;;45768:22:::1;::::0;3422:51:1;;;45768:22:0::1;::::0;3410:2:1;3395:18;45768:22:0::1;3276:203:1::0;79978:274:0;80051:13;80077:23;80092:7;80077:14;:23::i;:::-;80113:21;80137:10;:8;:10::i;:::-;80113:34;;80189:1;80171:7;80165:21;:25;:79;;;;;;;;;;;;;;;;;80217:7;80200:38;;;;;;;;:::i;:::-;;;;;;;;;;;;;80158:86;79978:274;-1:-1:-1;;;79978:274:0:o;44024:204::-;11490:13;:11;:13::i;:::-;44158:62:::1;::::0;-1:-1:-1;;;44158:62:0;;-1:-1:-1;;;;;44158:10:0::1;:20;::::0;::::1;::::0;:62:::1;::::0;44179:8;;44189;;44199:11;;44212:7;;;;44158:62:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;44024:204:::0;;;;;:::o;63291:287::-;11490:13;:11;:13::i;:::-;63446:1:::1;63419:24;:28;63411:85;;;::::0;-1:-1:-1;;;63411:85:0;;31121:2:1;63411:85:0::1;::::0;::::1;31103:21:1::0;31160:2;31140:18;;;31133:30;31199:34;31179:18;;;31172:62;-1:-1:-1;;;31250:18:1;;;31243:42;31302:19;;63411:85:0::1;30919:408:1::0;63411:85:0::1;63507:36;::::0;;::::1;;::::0;;;:23:::1;:36;::::0;;;;:63;63291:287::o;54560:767::-;54771:27;;;54749:19;54771:27;;;:14;:27;;;;;;:40;;;;54799:11;;;;54771:40;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;54771:48:0;;;;;;;;;;;;-1:-1:-1;54771:48:0;54830:73;;;;-1:-1:-1;;;54830:73:0;;31534:2:1;54830:73:0;;;31516:21:1;31573:2;31553:18;;;31546:30;31612:34;31592:18;;;31585:62;-1:-1:-1;;;31663:18:1;;;31656:33;31706:19;;54830:73:0;31332:399:1;54830:73:0;54945:11;54932:8;;54922:19;;;;;;;:::i;:::-;;;;;;;;:34;54914:80;;;;-1:-1:-1;;;54914:80:0;;31938:2:1;54914:80:0;;;31920:21:1;31977:2;31957:18;;;31950:30;32016:34;31996:18;;;31989:62;-1:-1:-1;;;32067:18:1;;;32060:31;32108:19;;54914:80:0;31736:397:1;54914:80:0;55042:27;;;55101:1;55042:27;;;:14;:27;;;;;;:40;;;;55070:11;;;;55042:40;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;55042:48:0;;;;;;;;;;;;:61;;;;55172:65;;;;;;;;;;;;;;;;;;;55194:11;;55207;;55172:65;;;;;;55207:11;55172:65;;55207:11;55172:65;;;;;;;;;-1:-1:-1;;55172:65:0;;;;;;;;;;;;;;;;;;;;;;55220:6;;-1:-1:-1;55172:65:0;-1:-1:-1;55228:8:0;;;;;;55172:65;;55228:8;;;;55172:65;;;;;;;;;-1:-1:-1;55172:21:0;;-1:-1:-1;;;55172:65:0:i;:::-;55253:66;55273:11;55286;;55299:6;55307:11;55253:66;;;;;;;;;;:::i;:::-;;;;;;;;54693:634;54560:767;;;;;;:::o;111148:149::-;110341:7;110368:12;;;:6;:12;;;;;:22;;;108323:16;108334:4;108323:10;:16::i;:::-;111263:26:::1;111275:4;111281:7;111263:11;:26::i;45806:284::-:0;11490:13;:11;:13::i;:::-;45930:1:::1;45920:7;:11;45912:45;;;::::0;-1:-1:-1;;;45912:45:0;;32838:2:1;45912:45:0::1;::::0;::::1;32820:21:1::0;32877:2;32857:18;;;32850:30;-1:-1:-1;;;32896:18:1;;;32889:51;32957:18;;45912:45:0::1;32636:345:1::0;45912:45:0::1;45968:28;::::0;;::::1;;::::0;;;:15:::1;:28;::::0;;;;;;;:41;;::::1;::::0;;;;;;;;;;:51;;;46035:47;;33209:34:1;;;33259:18;;33252:43;;;;33311:18;;;33304:34;;;46035:47:0::1;::::0;33172:2:1;33157:18;46035:47:0::1;32986:358:1::0;44829:198:0;11490:13;:11;:13::i;:::-;44927:32:::1;::::0;::::1;;::::0;;;:19:::1;:32;::::0;;;;:40:::1;::::0;44962:5;;44927:40:::1;:::i;:::-;;44983:36;45000:11;45013:5;;44983:36;;;;;;;;:::i;57974:388::-:0;58155:14;58171:11;58195:20;58229:10;58241:9;58218:33;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;58218:33:0;;;;;;;;;;-1:-1:-1;;;58269:85:0;;58218:33;-1:-1:-1;;;;;;58269:10:0;:23;;;;:85;;58293:11;;58314:4;;58218:33;;58330:7;;58339:14;;58269:85;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;58262:92;;;;;57974:388;;;;;;;;:::o;12510:201::-;11490:13;:11;:13::i;:::-;-1:-1:-1;;;;;12599:22:0;::::1;12591:73;;;::::0;-1:-1:-1;;;12591:73:0;;35315:2:1;12591:73:0::1;::::0;::::1;35297:21:1::0;35354:2;35334:18;;;35327:30;35393:34;35373:18;;;35366:62;-1:-1:-1;;;35444:18:1;;;35437:36;35490:19;;12591:73:0::1;35113:402:1::0;12591:73:0::1;12675:28;12694:8;12675:18;:28::i;:::-;12510:201:::0;:::o;43751:211::-;43886:68;;-1:-1:-1;;;43886:68:0;;35757:6:1;35790:15;;;43886:68:0;;;35772:34:1;35842:15;;35822:18;;;35815:43;43935:4:0;35874:18:1;;;35867:60;35943:18;;;35936:34;;;43854:12:0;;43886:10;-1:-1:-1;;;;;43886:20:0;;;;35719:19:1;;43886:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;43886:68:0;;;;;;;;;;;;:::i;:::-;43879:75;;43751:211;;;;;;;:::o;53175:514::-;53325:12;53339:19;53362:153;53396:9;53407:3;53435:34;;;53471:11;53484;53497:6;53505:8;53412:102;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;53412:102:0;;;;;;;;;;;;;;-1:-1:-1;;;;;53412:102:0;-1:-1:-1;;;;;;53412:102:0;;;;;;;;;;53370:4;;53362:153;;:33;:153::i;:::-;53324:191;;;;53575:7;53570:112;;53599:71;53619:11;53632;53645:6;53653:8;53663:6;53599:19;:71::i;108431:204::-;108516:4;-1:-1:-1;;;;;;108540:47:0;;-1:-1:-1;;;108540:47:0;;:87;;;108591:36;108615:11;108591:23;:36::i;11769:132::-;11650:7;11677:6;-1:-1:-1;;;;;11677:6:0;10228:10;11833:23;11825:68;;;;-1:-1:-1;;;11825:68:0;;37085:2:1;11825:68:0;;;37067:21:1;;;37104:18;;;37097:30;37163:34;37143:18;;;37136:62;37215:18;;11825:68:0;36883:356:1;89115:135:0;84398:4;84422:16;;;:7;:16;;;;;;-1:-1:-1;;;;;84422:16:0;89189:53;;;;-1:-1:-1;;;89189:53:0;;23755:2:1;89189:53:0;;;23737:21:1;23794:2;23774:18;;;23767:30;-1:-1:-1;;;23813:18:1;;;23806:54;23877:18;;89189:53:0;23553:348:1;88394:174:0;88469:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;88469:29:0;-1:-1:-1;;;;;88469:29:0;;;;;;;;:24;;88523:23;88469:24;88523:14;:23::i;:::-;-1:-1:-1;;;;;88514:46:0;;;;;;;;;;;88394:174;;:::o;84627:264::-;84720:4;84737:13;84753:23;84768:7;84753:14;:23::i;:::-;84737:39;;84806:5;-1:-1:-1;;;;;84795:16:0;:7;-1:-1:-1;;;;;84795:16:0;;:52;;;-1:-1:-1;;;;;;81730:25:0;;;81706:4;81730:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;84815:32;84795:87;;;;84875:7;-1:-1:-1;;;;;84851:31:0;:20;84863:7;84851:11;:20::i;:::-;-1:-1:-1;;;;;84851:31:0;;84787:96;84627:264;-1:-1:-1;;;;84627:264:0:o;87650:625::-;87809:4;-1:-1:-1;;;;;87782:31:0;:23;87797:7;87782:14;:23::i;:::-;-1:-1:-1;;;;;87782:31:0;;87774:81;;;;-1:-1:-1;;;87774:81:0;;37446:2:1;87774:81:0;;;37428:21:1;37485:2;37465:18;;;37458:30;37524:34;37504:18;;;37497:62;-1:-1:-1;;;37575:18:1;;;37568:35;37620:19;;87774:81:0;37244:401:1;87774:81:0;-1:-1:-1;;;;;87874:16:0;;87866:65;;;;-1:-1:-1;;;87866:65:0;;37852:2:1;87866:65:0;;;37834:21:1;37891:2;37871:18;;;37864:30;37930:34;37910:18;;;37903:62;-1:-1:-1;;;37981:18:1;;;37974:34;38025:19;;87866:65:0;37650:400:1;87866:65:0;87944:39;87965:4;87971:2;87975:7;87944:20;:39::i;:::-;88048:29;88065:1;88069:7;88048:8;:29::i;:::-;-1:-1:-1;;;;;88090:15:0;;;;;;:9;:15;;;;;:20;;88109:1;;88090:15;:20;;88109:1;;88090:20;:::i;:::-;;;;-1:-1:-1;;;;;;;88121:13:0;;;;;;:9;:13;;;;;:18;;88138:1;;88121:13;:18;;88138:1;;88121:18;:::i;:::-;;;;-1:-1:-1;;88150:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;88150:21:0;-1:-1:-1;;;;;88150:21:0;;;;;;;;;88189:27;;88150:16;;88189:27;;;;;;;80727:347;80657:417;;:::o;64150:185::-;64262:13;;;64273:1;64262:13;;;;;;;;;64214;;64240:19;;64262:13;;;;;;;;;;;;-1:-1:-1;64262:13:0;64240:35;;64297:7;64286:5;64292:1;64286:8;;;;;;;;:::i;:::-;;;;;;;;;;:18;64322:5;64150:185;-1:-1:-1;;64150:185:0:o;109178:105::-;109245:30;109256:4;10228:10;109245;:30::i;113449:238::-;113533:22;113541:4;113547:7;113533;:22::i;:::-;113528:152;;113572:12;;;;:6;:12;;;;;;;;-1:-1:-1;;;;;113572:29:0;;;;;;;;;:36;;-1:-1:-1;;113572:36:0;113604:4;113572:36;;;113655:12;10228:10;;10148:98;113655:12;-1:-1:-1;;;;;113628:40:0;113646:7;-1:-1:-1;;;;;113628:40:0;113640:4;113628:40;;;;;;;;;;113449:238;;:::o;113867:239::-;113951:22;113959:4;113965:7;113951;:22::i;:::-;113947:152;;;114022:5;113990:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;113990:29:0;;;;;;;;;;:37;;-1:-1:-1;;113990:37:0;;;114047:40;10228:10;;113990:12;;114047:40;;114022:5;114047:40;113867:239;;:::o;59085:976::-;59360:1;59341:9;:16;:20;59333:59;;;;-1:-1:-1;;;59333:59:0;;38390:2:1;59333:59:0;;;38372:21:1;38429:2;38409:18;;;38402:30;38468:28;38448:18;;;38441:56;38514:18;;59333:59:0;38188:350:1;59333:59:0;59411:9;:16;59431:1;59411:21;:80;;;-1:-1:-1;59456:35:0;;;;;;;:22;:35;;;;;;59436:16;;:55;;59411:80;59403:136;;;;-1:-1:-1;;;59403:136:0;;38745:2:1;59403:136:0;;;38727:21:1;38784:2;38764:18;;;38757:30;38823:34;38803:18;;;38796:62;-1:-1:-1;;;38874:18:1;;;38867:41;38925:19;;59403:136:0;38543:407:1;59403:136:0;59557:6;59552:127;59573:9;:16;59569:1;:20;59552:127;;;59611:56;59622:5;59629:11;59642:10;59654:9;59664:1;59654:12;;;;;;;;:::i;:::-;;;;;;;59611:10;:56::i;:::-;59591:3;;;;:::i;:::-;;;;59552:127;;;;59691:20;59725:10;59737:9;59714:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;59691:56;;59760:120;59775:11;56579:1;59808:14;59863:9;:16;59824:23;:36;59848:11;59824:36;;;;;;;;;;;;;;;;:55;;;;:::i;:::-;59760:14;:120::i;:::-;59891:92;59899:11;59912:7;59921:14;59937:18;59957:14;59973:9;59891:7;:92::i;:::-;60031:10;59999:54;;;;;;:::i;:::-;;;;;;;;60024:5;-1:-1:-1;;;;;59999:54:0;60011:11;59999:54;;;60043:9;59999:54;;;;;;:::i;:::-;;;;;;;;59291:770;59085:976;;;;;;;:::o;60069:::-;60311:27;60340:22;60377:8;60366:37;;;;;;;;;;;;:::i;:::-;60507:2;60487:23;;60481:30;60310:93;;-1:-1:-1;60310:93:0;-1:-1:-1;60416:17:0;60551:48;60563:11;60481:30;60416:17;60310:93;60551:11;:48::i;:::-;60534:65;;60626:8;:15;60614:9;:27;60610:347;;;60770:19;;;;;;;;;;60835:53;;;;;;;;;;;;;;-1:-1:-1;;;;;60835:53:0;;;;;;;;;;;;;;;60883:4;60835:53;;;;;;60746:21;60804:28;;;:13;:28;;;;;;;:84;;;;;;;;;;;-1:-1:-1;;;;;;60804:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;60804:84:0;;;;;;;;;;60908:37;;;;;;60770:19;;60780:8;;60908:37;:::i;:::-;;;;;;;;60643:314;60610:347;61017:9;-1:-1:-1;;;;;60974:63:0;61004:11;60974:63;;;;;;:::i;:::-;;;;;;;;60991:11;60974:63;;;61028:8;60974:63;;;;;;:::i;85233:110::-;85309:26;85319:2;85323:7;85309:26;;;;;;;;;;;;:9;:26::i;12871:191::-;12945:16;12964:6;;-1:-1:-1;;;;;12981:17:0;;;-1:-1:-1;;;;;;12981:17:0;;;;;;13014:40;;12964:6;;;;;;;13014:40;;12945:16;13014:40;12934:128;12871:191;:::o;62348:574::-;62470:7;62498:11;62520:263;62531:9;:16;62527:1;:20;62520:263;;;62657:24;;62645:9;:36;62641:47;;;62683:5;;62641:47;62705:48;62715:11;62728:10;62740:9;62750:1;62740:12;;;;;;;;:::i;:::-;;;;;;;62705:9;:48::i;:::-;62768:3;;;;:::i;:::-;;;;62520:263;;29979:2779;30120:12;30174:7;30158:12;30174:7;30168:2;30158:12;:::i;:::-;:23;;30150:50;;;;-1:-1:-1;;;30150:50:0;;40169:2:1;30150:50:0;;;40151:21:1;40208:2;40188:18;;;40181:30;-1:-1:-1;;;40227:18:1;;;40220:44;40281:18;;30150:50:0;39967:338:1;30150:50:0;30236:16;30245:7;30236:6;:16;:::i;:::-;30219:6;:13;:33;;30211:63;;;;-1:-1:-1;;;30211:63:0;;40512:2:1;30211:63:0;;;40494:21:1;40551:2;40531:18;;;40524:30;-1:-1:-1;;;40570:18:1;;;40563:47;40627:18;;30211:63:0;40310:341:1;30211:63:0;30287:22;30353:15;;30382:1933;;;;32459:4;32453:11;32440:24;;32640:1;32629:9;32622:20;32690:4;32679:9;32675:20;32669:4;32662:34;30346:2365;;30382:1933;30559:4;30553:11;30540:24;;31196:2;31187:7;31183:16;31568:9;31561:17;31555:4;31551:28;31539:9;31528;31524:25;31520:60;31617:7;31613:2;31609:16;31866:6;31852:9;31845:17;31839:4;31835:28;31823:9;31815:6;31811:22;31807:57;31803:70;31645:426;31900:3;31896:2;31893:11;31645:426;;;32042:9;;32031:21;;31942:4;31934:13;;;;31975;31645:426;;;-1:-1:-1;;32091:26:0;;;32295:2;32278:11;-1:-1:-1;;32274:25:0;32268:4;32261:39;-1:-1:-1;30346:2365:0;-1:-1:-1;32741:9:0;29979:2779;-1:-1:-1;;;;29979:2779:0:o;88711:315::-;88866:8;-1:-1:-1;;;;;88857:17:0;:5;-1:-1:-1;;;;;88857:17:0;;;88849:55;;;;-1:-1:-1;;;88849:55:0;;40858:2:1;88849:55:0;;;40840:21:1;40897:2;40877:18;;;40870:30;40936:27;40916:18;;;40909:55;40981:18;;88849:55:0;40656:349:1;88849:55:0;-1:-1:-1;;;;;88915:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;88915:46:0;;;;;;;;;;88977:41;;2099::1;;;88977::0;;2072:18:1;88977:41:0;;;;;;;88711:315;;;:::o;83707:313::-;83863:28;83873:4;83879:2;83883:7;83863:9;:28::i;:::-;83910:47;83933:4;83939:2;83943:7;83952:4;83910:22;:47::i;:::-;83902:110;;;;-1:-1:-1;;;83902:110:0;;;;;;;:::i;117025:108::-;117085:13;117118:7;117111:14;;;;;:::i;47814:1275::-;47976:4;47982:12;48044:15;48070:13;48094:24;48131:8;48121:19;;-1:-1:-1;;;;;48121:19:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;48121:19:0;;48094:46;;48622:1;48596;48562:9;48556:16;48527:4;48516:9;48512:20;48481:1;48446:7;48420:4;48401:247;48389:259;;48713:16;48702:27;;48758:8;48749:7;48746:21;48743:78;;;48798:8;48787:19;;48743:78;48904:7;48891:11;48884:28;49022:7;49019:1;49012:4;48999:11;48995:22;48980:50;49059:8;;;;-1:-1:-1;47814:1275:0;-1:-1:-1;;;;;;47814:1275:0:o;53697:323::-;53921:8;53911:19;;;;;;53860:14;:27;53875:11;53860:27;;;;;;;;;;;;;;;53888:11;53860:40;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;53860:48:0;;;;;;;;;:70;;;;53946:66;;;;53960:11;;53973;;53901:6;;53994:8;;54004:7;;53946:66;:::i;:::-;;;;;;;;53697:323;;;;;:::o;93987:224::-;94089:4;-1:-1:-1;;;;;;94113:50:0;;-1:-1:-1;;;94113:50:0;;:90;;;94167:36;94191:11;94167:23;:36::i;115615:227::-;101420:19;:17;:19::i;:::-;115789:45:::1;115816:4;115822:2;115826:7;115789:26;:45::i;109573:505::-:0;109662:22;109670:4;109676:7;109662;:22::i;:::-;109657:414;;109850:41;109878:7;-1:-1:-1;;;;;109850:41:0;109888:2;109850:19;:41::i;:::-;109964:38;109992:4;109999:2;109964:19;:38::i;:::-;109755:270;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;109755:270:0;;;;;;;;;;-1:-1:-1;;;109701:358:0;;;;;;;:::i;114865:361::-;114982:42;10228:10;115001:12;10148:98;114982:42;114974:101;;;;-1:-1:-1;;;114974:101:0;;43146:2:1;114974:101:0;;;43128:21:1;43185:2;43165:18;;;43158:30;43224:34;43204:18;;;43197:62;-1:-1:-1;;;43275:18:1;;;43268:44;43329:19;;114974:101:0;42944:410:1;114974:101:0;115122:5;-1:-1:-1;;;;;115094:33:0;:24;115109:8;115094:14;:24::i;:::-;-1:-1:-1;;;;;115094:33:0;;115086:80;;;;-1:-1:-1;;;115086:80:0;;43561:2:1;115086:80:0;;;43543:21:1;43600:2;43580:18;;;43573:30;43639:34;43619:18;;;43612:62;-1:-1:-1;;;43690:18:1;;;43683:32;43732:19;;115086:80:0;43359:398:1;115086:80:0;115177:41;115187:5;115202:4;115209:8;115177:9;:41::i;42550:420::-;42686:21;42710:28;42723:14;42710:12;:28::i;:::-;42768;;;;42749:16;42768:28;;;:15;:28;;;;;;;;:35;;;;;;;;;;;;42686:52;;-1:-1:-1;42749:16:0;42768:47;;42806:9;;42768:47;:::i;:::-;42749:66;;42848:1;42834:11;:15;42826:54;;;;-1:-1:-1;;;42826:54:0;;43964:2:1;42826:54:0;;;43946:21:1;44003:2;43983:18;;;43976:30;44042:28;44022:18;;;44015:56;44088:18;;42826:54:0;43762:350:1;42826:54:0;42919:11;42899:16;:31;;42891:71;;;;-1:-1:-1;;;42891:71:0;;44319:2:1;42891:71:0;;;44301:21:1;44358:2;44338:18;;;44331:30;44397:29;44377:18;;;44370:57;44444:18;;42891:71:0;44117:351:1;41989:553:0;42212:32;;;42183:26;42212:32;;;:19;:32;;;;;42183:61;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42263:13;:20;42287:1;42263:25;;42255:86;;;;-1:-1:-1;;;42255:86:0;;44675:2:1;42255:86:0;;;44657:21:1;44714:2;44694:18;;;44687:30;44753:34;44733:18;;;44726:62;-1:-1:-1;;;44804:18:1;;;44797:46;44860:19;;42255:86:0;44473:412:1;42255:86:0;42352:47;42370:11;42383:8;:15;42352:17;:47::i;:::-;42410:124;;-1:-1:-1;;;42410:124:0;;-1:-1:-1;;;;;42410:10:0;:15;;;;42433:10;;42410:124;;42445:11;;42458:13;;42473:8;;42483:14;;42499:18;;42519:14;;42410:124;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42172:370;41989:553;;;;;;:::o;85570:319::-;85699:18;85705:2;85709:7;85699:5;:18::i;:::-;85750:53;85781:1;85785:2;85789:7;85798:4;85750:22;:53::i;:::-;85728:153;;;;-1:-1:-1;;;85728:153:0;;;;;;;:::i;115234:373::-;84398:4;84422:16;;;:7;:16;;;;;;-1:-1:-1;;;;;84422:16:0;:30;;115341:86;;-1:-1:-1;84398:4:0;84422:16;;;:7;:16;;;;;;-1:-1:-1;;;;;84422:16:0;:30;;115364:62;;;;-1:-1:-1;115421:4:0;115385:24;115400:8;115385:14;:24::i;:::-;-1:-1:-1;;;;;115385:41:0;;115364:62;115333:95;;;;;;84398:4;84422:16;;;:7;:16;;;;;;-1:-1:-1;;;;;84422:16:0;115439:161;;115478:31;115488:10;115500:8;115478:9;:31::i;115439:161::-;115542:46;115560:4;115567:10;115579:8;115542:9;:46::i;89814:853::-;89968:4;-1:-1:-1;;;;;89989:13:0;;67762:19;:23;89985:675;;90025:71;;-1:-1:-1;;;90025:71:0;;-1:-1:-1;;;;;90025:36:0;;;;;:71;;10228:10;;90076:4;;90082:7;;90091:4;;90025:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;90025:71:0;;;;;;;;-1:-1:-1;;90025:71:0;;;;;;;;;;;;:::i;:::-;;;90021:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;90266:13:0;;90262:328;;90309:60;;-1:-1:-1;;;90309:60:0;;;;;;;:::i;90262:328::-;90540:6;90534:13;90525:6;90521:2;90517:15;90510:38;90021:584;-1:-1:-1;;;;;;90147:51:0;-1:-1:-1;;;90147:51:0;;-1:-1:-1;90140:58:0;;89985:675;-1:-1:-1;90644:4:0;90637:11;;78707:305;78809:4;-1:-1:-1;;;;;;78846:40:0;;-1:-1:-1;;;78846:40:0;;:105;;-1:-1:-1;;;;;;;78903:48:0;;-1:-1:-1;;;78903:48:0;78846:105;:158;;;;78968:36;78992:11;78968:23;:36::i;101974:108::-;101886:7;;;;102044:9;102036:38;;;;-1:-1:-1;;;102036:38:0;;46685:2:1;102036:38:0;;;46667:21:1;46724:2;46704:18;;;46697:30;-1:-1:-1;;;46743:18:1;;;46736:46;46799:18;;102036:38:0;46483:340:1;95663:589:0;-1:-1:-1;;;;;95869:18:0;;95865:187;;95904:40;95936:7;97079:10;:17;;97052:24;;;;:15;:24;;;;;:44;;;97107:24;;;;;;;;;;;;96975:164;95904:40;95865:187;;;95974:2;-1:-1:-1;;;;;95966:10:0;:4;-1:-1:-1;;;;;95966:10:0;;95962:90;;95993:47;96026:4;96032:7;95993:32;:47::i;:::-;-1:-1:-1;;;;;96066:16:0;;96062:183;;96099:45;96136:7;96099:36;:45::i;96062:183::-;96172:4;-1:-1:-1;;;;;96166:10:0;:2;-1:-1:-1;;;;;96166:10:0;;96162:83;;96193:40;96221:2;96225:7;96193:27;:40::i;76527:451::-;76602:13;76628:19;76660:10;76664:6;76660:1;:10;:::i;:::-;:14;;76673:1;76660:14;:::i;:::-;-1:-1:-1;;;;;76650:25:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;76650:25:0;;76628:47;;-1:-1:-1;;;76686:6:0;76693:1;76686:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;76686:15:0;;;;;;;;;-1:-1:-1;;;76712:6:0;76719:1;76712:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;76712:15:0;;;;;;;;-1:-1:-1;76743:9:0;76755:10;76759:6;76755:1;:10;:::i;:::-;:14;;76768:1;76755:14;:::i;:::-;76743:26;;76738:135;76775:1;76771;:5;76738:135;;;-1:-1:-1;;;76823:5:0;76831:3;76823:11;76810:25;;;;;;;:::i;:::-;;;;76798:6;76805:1;76798:9;;;;;;;;:::i;:::-;;;;:37;-1:-1:-1;;;;;76798:37:0;;;;;;;;-1:-1:-1;76860:1:0;76850:11;;;;;76778:3;;;:::i;:::-;;;76738:135;;;-1:-1:-1;76891:10:0;;76883:55;;;;-1:-1:-1;;;76883:55:0;;47171:2:1;76883:55:0;;;47153:21:1;;;47190:18;;;47183:30;47249:34;47229:18;;;47222:62;47301:18;;76883:55:0;46969:356:1;42978:271:0;43060:13;43119:2;43094:14;:21;:27;;43086:68;;;;-1:-1:-1;;;43086:68:0;;47532:2:1;43086:68:0;;;47514:21:1;47571:2;47551:18;;;47544:30;47610;47590:18;;;47583:58;47658:18;;43086:68:0;47330:352:1;43086:68:0;-1:-1:-1;43227:2:0;43207:23;43201:30;;42978:271::o;43257:389::-;43380:35;;;43356:21;43380:35;;;:22;:35;;;;;;43430:21;43426:125;;-1:-1:-1;40283:5:0;43426:125;43585:16;43569:12;:32;;43561:77;;;;-1:-1:-1;;;43561:77:0;;47889:2:1;43561:77:0;;;47871:21:1;;;47908:18;;;47901:30;47967:34;47947:18;;;47940:62;48019:18;;43561:77:0;47687:356:1;86225:439:0;-1:-1:-1;;;;;86305:16:0;;86297:61;;;;-1:-1:-1;;;86297:61:0;;48250:2:1;86297:61:0;;;48232:21:1;;;48269:18;;;48262:30;48328:34;48308:18;;;48301:62;48380:18;;86297:61:0;48048:356:1;86297:61:0;84398:4;84422:16;;;:7;:16;;;;;;-1:-1:-1;;;;;84422:16:0;:30;86369:58;;;;-1:-1:-1;;;86369:58:0;;48611:2:1;86369:58:0;;;48593:21:1;48650:2;48630:18;;;48623:30;48689;48669:18;;;48662:58;48737:18;;86369:58:0;48409:352:1;86369:58:0;86440:45;86469:1;86473:2;86477:7;86440:20;:45::i;:::-;-1:-1:-1;;;;;86498:13:0;;;;;;:9;:13;;;;;:18;;86515:1;;86498:13;:18;;86515:1;;86498:18;:::i;:::-;;;;-1:-1:-1;;86527:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;86527:21:0;-1:-1:-1;;;;;86527:21:0;;;;;;;;86566:33;;86527:16;;;86566:33;;86527:16;;86566:33;111852:218;;:::o;57419:219::-;57521:4;-1:-1:-1;;;;;;57545:45:0;;-1:-1:-1;;;57545:45:0;;:85;;-1:-1:-1;;;;;;;;;;56315:40:0;;;57594:36;56206:157;97766:988;98032:22;98082:1;98057:22;98074:4;98057:16;:22::i;:::-;:26;;;;:::i;:::-;98094:18;98115:26;;;:17;:26;;;;;;98032:51;;-1:-1:-1;98248:28:0;;;98244:328;;-1:-1:-1;;;;;98315:18:0;;98293:19;98315:18;;;:12;:18;;;;;;;;:34;;;;;;;;;98366:30;;;;;;:44;;;98483:30;;:17;:30;;;;;:43;;;98244:328;-1:-1:-1;98668:26:0;;;;:17;:26;;;;;;;;98661:33;;;-1:-1:-1;;;;;98712:18:0;;;;;:12;:18;;;;;:34;;;;;;;98705:41;97766:988::o;99049:1079::-;99327:10;:17;99302:22;;99327:21;;99347:1;;99327:21;:::i;:::-;99359:18;99380:24;;;:15;:24;;;;;;99753:10;:26;;99302:46;;-1:-1:-1;99380:24:0;;99302:46;;99753:26;;;;;;:::i;:::-;;;;;;;;;99731:48;;99817:11;99792:10;99803;99792:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;99897:28;;;:15;:28;;;;;;;:41;;;100069:24;;;;;100062:31;100104:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;99120:1008;;;99049:1079;:::o;96553:221::-;96638:14;96655:20;96672:2;96655:16;:20::i;:::-;-1:-1:-1;;;;;96686:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;96731:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;96553:221:0:o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:159:1;81:20;;141:6;130:18;;120:29;;110:57;;163:1;160;153:12;110:57;14:159;;;:::o;178:347::-;229:8;239:6;293:3;286:4;278:6;274:17;270:27;260:55;;311:1;308;301:12;260:55;-1:-1:-1;334:20:1;;-1:-1:-1;;;;;366:30:1;;363:50;;;409:1;406;399:12;363:50;446:4;438:6;434:17;422:29;;498:3;491:4;482:6;474;470:19;466:30;463:39;460:59;;;515:1;512;505:12;460:59;178:347;;;;;:::o;530:171::-;597:20;;-1:-1:-1;;;;;646:30:1;;636:41;;626:69;;691:1;688;681:12;706:862;812:6;820;828;836;844;852;905:3;893:9;884:7;880:23;876:33;873:53;;;922:1;919;912:12;873:53;945:28;963:9;945:28;:::i;:::-;935:38;;1024:2;1013:9;1009:18;996:32;-1:-1:-1;;;;;1088:2:1;1080:6;1077:14;1074:34;;;1104:1;1101;1094:12;1074:34;1143:58;1193:7;1184:6;1173:9;1169:22;1143:58;:::i;:::-;1220:8;;-1:-1:-1;1117:84:1;-1:-1:-1;1117:84:1;;-1:-1:-1;1274:37:1;1307:2;1292:18;;1274:37;:::i;:::-;1264:47;;1364:2;1353:9;1349:18;1336:32;1320:48;;1393:2;1383:8;1380:16;1377:36;;;1409:1;1406;1399:12;1377:36;;1448:60;1500:7;1489:8;1478:9;1474:24;1448:60;:::i;:::-;706:862;;;;-1:-1:-1;706:862:1;;-1:-1:-1;706:862:1;;1527:8;;706:862;-1:-1:-1;;;706:862:1:o;1573:131::-;-1:-1:-1;;;;;;1647:32:1;;1637:43;;1627:71;;1694:1;1691;1684:12;1709:245;1767:6;1820:2;1808:9;1799:7;1795:23;1791:32;1788:52;;;1836:1;1833;1826:12;1788:52;1875:9;1862:23;1894:30;1918:5;1894:30;:::i;2151:258::-;2223:1;2233:113;2247:6;2244:1;2241:13;2233:113;;;2323:11;;;2317:18;2304:11;;;2297:39;2269:2;2262:10;2233:113;;;2364:6;2361:1;2358:13;2355:48;;;-1:-1:-1;;2399:1:1;2381:16;;2374:27;2151:258::o;2414:::-;2456:3;2494:5;2488:12;2521:6;2516:3;2509:19;2537:63;2593:6;2586:4;2581:3;2577:14;2570:4;2563:5;2559:16;2537:63;:::i;:::-;2654:2;2633:15;-1:-1:-1;;2629:29:1;2620:39;;;;2661:4;2616:50;;2414:258;-1:-1:-1;;2414:258:1:o;2677:220::-;2826:2;2815:9;2808:21;2789:4;2846:45;2887:2;2876:9;2872:18;2864:6;2846:45;:::i;2902:184::-;2960:6;3013:2;3001:9;2992:7;2988:23;2984:32;2981:52;;;3029:1;3026;3019:12;2981:52;3052:28;3070:9;3052:28;:::i;3091:180::-;3150:6;3203:2;3191:9;3182:7;3178:23;3174:32;3171:52;;;3219:1;3216;3209:12;3171:52;-1:-1:-1;3242:23:1;;3091:180;-1:-1:-1;3091:180:1:o;3484:131::-;-1:-1:-1;;;;;3559:31:1;;3549:42;;3539:70;;3605:1;3602;3595:12;3620:134;3688:20;;3717:31;3688:20;3717:31;:::i;3759:315::-;3827:6;3835;3888:2;3876:9;3867:7;3863:23;3859:32;3856:52;;;3904:1;3901;3894:12;3856:52;3943:9;3930:23;3962:31;3987:5;3962:31;:::i;:::-;4012:5;4064:2;4049:18;;;;4036:32;;-1:-1:-1;;;3759:315:1:o;4079:252::-;4146:6;4154;4207:2;4195:9;4186:7;4182:23;4178:32;4175:52;;;4223:1;4220;4213:12;4175:52;4246:28;4264:9;4246:28;:::i;5146:456::-;5223:6;5231;5239;5292:2;5280:9;5271:7;5267:23;5263:32;5260:52;;;5308:1;5305;5298:12;5260:52;5347:9;5334:23;5366:31;5391:5;5366:31;:::i;:::-;5416:5;-1:-1:-1;5473:2:1;5458:18;;5445:32;5486:33;5445:32;5486:33;:::i;:::-;5146:456;;5538:7;;-1:-1:-1;;;5592:2:1;5577:18;;;;5564:32;;5146:456::o;5789:127::-;5850:10;5845:3;5841:20;5838:1;5831:31;5881:4;5878:1;5871:15;5905:4;5902:1;5895:15;5921:275;5992:2;5986:9;6057:2;6038:13;;-1:-1:-1;;6034:27:1;6022:40;;-1:-1:-1;;;;;6077:34:1;;6113:22;;;6074:62;6071:88;;;6139:18;;:::i;:::-;6175:2;6168:22;5921:275;;-1:-1:-1;5921:275:1:o;6201:186::-;6249:4;-1:-1:-1;;;;;6274:6:1;6271:30;6268:56;;;6304:18;;:::i;:::-;-1:-1:-1;6370:2:1;6349:15;-1:-1:-1;;6345:29:1;6376:4;6341:40;;6201:186::o;6392:336::-;6456:5;6485:52;6501:35;6529:6;6501:35;:::i;:::-;6485:52;:::i;:::-;6476:61;;6560:6;6553:5;6546:21;6600:3;6591:6;6586:3;6582:16;6579:25;6576:45;;;6617:1;6614;6607:12;6576:45;6666:6;6661:3;6654:4;6647:5;6643:16;6630:43;6720:1;6713:4;6704:6;6697:5;6693:18;6689:29;6682:40;6392:336;;;;;:::o;6733:220::-;6775:5;6828:3;6821:4;6813:6;6809:17;6805:27;6795:55;;6846:1;6843;6836:12;6795:55;6868:79;6943:3;6934:6;6921:20;6914:4;6906:6;6902:17;6868:79;:::i;6958:160::-;7023:20;;7079:13;;7072:21;7062:32;;7052:60;;7108:1;7105;7098:12;7123:749;7232:6;7240;7248;7256;7264;7317:3;7305:9;7296:7;7292:23;7288:33;7285:53;;;7334:1;7331;7324:12;7285:53;7357:28;7375:9;7357:28;:::i;:::-;7347:38;;7436:2;7425:9;7421:18;7408:32;-1:-1:-1;;;;;7500:2:1;7492:6;7489:14;7486:34;;;7516:1;7513;7506:12;7486:34;7539:49;7580:7;7571:6;7560:9;7556:22;7539:49;:::i;:::-;7529:59;;7635:2;7624:9;7620:18;7607:32;7597:42;;7658:35;7689:2;7678:9;7674:18;7658:35;:::i;:::-;7648:45;;7746:3;7735:9;7731:19;7718:33;7702:49;;7776:2;7766:8;7763:16;7760:36;;;7792:1;7789;7782:12;7760:36;;7815:51;7858:7;7847:8;7836:9;7832:24;7815:51;:::i;:::-;7805:61;;;7123:749;;;;;;;;:::o;8130:315::-;8198:6;8206;8259:2;8247:9;8238:7;8234:23;8230:32;8227:52;;;8275:1;8272;8265:12;8227:52;8311:9;8298:23;8288:33;;8371:2;8360:9;8356:18;8343:32;8384:31;8409:5;8384:31;:::i;:::-;8434:5;8424:15;;;8130:315;;;;;:::o;8450:481::-;8528:6;8536;8544;8597:2;8585:9;8576:7;8572:23;8568:32;8565:52;;;8613:1;8610;8603:12;8565:52;8636:28;8654:9;8636:28;:::i;:::-;8626:38;;8715:2;8704:9;8700:18;8687:32;-1:-1:-1;;;;;8734:6:1;8731:30;8728:50;;;8774:1;8771;8764:12;8728:50;8813:58;8863:7;8854:6;8843:9;8839:22;8813:58;:::i;:::-;8450:481;;8890:8;;-1:-1:-1;8787:84:1;;-1:-1:-1;;;;8450:481:1:o;8936:1108::-;9074:6;9082;9090;9098;9106;9114;9122;9175:3;9163:9;9154:7;9150:23;9146:33;9143:53;;;9192:1;9189;9182:12;9143:53;9231:9;9218:23;9250:31;9275:5;9250:31;:::i;:::-;9300:5;-1:-1:-1;9324:37:1;9357:2;9342:18;;9324:37;:::i;:::-;9314:47;;9412:2;9401:9;9397:18;9384:32;-1:-1:-1;;;;;9476:2:1;9468:6;9465:14;9462:34;;;9492:1;9489;9482:12;9462:34;9515:49;9556:7;9547:6;9536:9;9532:22;9515:49;:::i;:::-;9505:59;;9611:2;9600:9;9596:18;9583:32;9573:42;;9667:3;9656:9;9652:19;9639:33;9624:48;;9681:33;9706:7;9681:33;:::i;:::-;9733:7;;-1:-1:-1;9792:3:1;9777:19;;9764:33;;9806;9764;9806;:::i;:::-;9858:7;;-1:-1:-1;9918:3:1;9903:19;;9890:33;;9935:16;;;9932:36;;;9964:1;9961;9954:12;9932:36;;9987:51;10030:7;10019:8;10008:9;10004:24;9987:51;:::i;:::-;9977:61;;;8936:1108;;;;;;;;;;:::o;10049:450::-;10118:6;10171:2;10159:9;10150:7;10146:23;10142:32;10139:52;;;10187:1;10184;10177:12;10139:52;10227:9;10214:23;-1:-1:-1;;;;;10252:6:1;10249:30;10246:50;;;10292:1;10289;10282:12;10246:50;10315:22;;10368:4;10360:13;;10356:27;-1:-1:-1;10346:55:1;;10397:1;10394;10387:12;10346:55;10420:73;10485:7;10480:2;10467:16;10462:2;10458;10454:11;10420:73;:::i;10504:464::-;10588:6;10596;10604;10657:2;10645:9;10636:7;10632:23;10628:32;10625:52;;;10673:1;10670;10663:12;10625:52;10696:28;10714:9;10696:28;:::i;:::-;10686:38;;10775:2;10764:9;10760:18;10747:32;-1:-1:-1;;;;;10794:6:1;10791:30;10788:50;;;10834:1;10831;10824:12;10788:50;10857:49;10898:7;10889:6;10878:9;10874:22;10857:49;:::i;:::-;10847:59;;;10925:37;10958:2;10947:9;10943:18;10925:37;:::i;:::-;10915:47;;10504:464;;;;;:::o;10973:247::-;11032:6;11085:2;11073:9;11064:7;11060:23;11056:32;11053:52;;;11101:1;11098;11091:12;11053:52;11140:9;11127:23;11159:31;11184:5;11159:31;:::i;11448:256::-;11514:6;11522;11575:2;11563:9;11554:7;11550:23;11546:32;11543:52;;;11591:1;11588;11581:12;11543:52;11614:28;11632:9;11614:28;:::i;:::-;11604:38;;11661:37;11694:2;11683:9;11679:18;11661:37;:::i;:::-;11651:47;;11448:256;;;;;:::o;11709:320::-;11777:6;11830:2;11818:9;11809:7;11805:23;11801:32;11798:52;;;11846:1;11843;11836:12;11798:52;11886:9;11873:23;-1:-1:-1;;;;;11911:6:1;11908:30;11905:50;;;11951:1;11948;11941:12;11905:50;11974:49;12015:7;12006:6;11995:9;11991:22;11974:49;:::i;12034:248::-;12102:6;12110;12163:2;12151:9;12142:7;12138:23;12134:32;12131:52;;;12179:1;12176;12169:12;12131:52;-1:-1:-1;;12202:23:1;;;12272:2;12257:18;;;12244:32;;-1:-1:-1;12034:248:1:o;12287:315::-;12352:6;12360;12413:2;12401:9;12392:7;12388:23;12384:32;12381:52;;;12429:1;12426;12419:12;12381:52;12468:9;12455:23;12487:31;12512:5;12487:31;:::i;:::-;12537:5;-1:-1:-1;12561:35:1;12592:2;12577:18;;12561:35;:::i;12607:183::-;12667:4;-1:-1:-1;;;;;12692:6:1;12689:30;12686:56;;;12722:18;;:::i;:::-;-1:-1:-1;12767:1:1;12763:14;12779:4;12759:25;;12607:183::o;12795:662::-;12849:5;12902:3;12895:4;12887:6;12883:17;12879:27;12869:55;;12920:1;12917;12910:12;12869:55;12956:6;12943:20;12982:4;13006:60;13022:43;13062:2;13022:43;:::i;13006:60::-;13100:15;;;13186:1;13182:10;;;;13170:23;;13166:32;;;13131:12;;;;13210:15;;;13207:35;;;13238:1;13235;13228:12;13207:35;13274:2;13266:6;13262:15;13286:142;13302:6;13297:3;13294:15;13286:142;;;13368:17;;13356:30;;13406:12;;;;13319;;13286:142;;;-1:-1:-1;13446:5:1;12795:662;-1:-1:-1;;;;;;12795:662:1:o;13462:1199::-;13625:6;13633;13641;13649;13657;13665;13673;13726:3;13714:9;13705:7;13701:23;13697:33;13694:53;;;13743:1;13740;13733:12;13694:53;13782:9;13769:23;13801:31;13826:5;13801:31;:::i;:::-;13851:5;-1:-1:-1;13875:37:1;13908:2;13893:18;;13875:37;:::i;:::-;13865:47;;13963:2;13952:9;13948:18;13935:32;-1:-1:-1;;;;;14027:2:1;14019:6;14016:14;14013:34;;;14043:1;14040;14033:12;14013:34;14066:49;14107:7;14098:6;14087:9;14083:22;14066:49;:::i;:::-;14056:59;;14168:2;14157:9;14153:18;14140:32;14124:48;;14197:2;14187:8;14184:16;14181:36;;;14213:1;14210;14203:12;14181:36;14236:63;14291:7;14280:8;14269:9;14265:24;14236:63;:::i;:::-;14226:73;;14351:3;14340:9;14336:19;14323:33;14308:48;;14365:33;14390:7;14365:33;:::i;:::-;14417:7;14407:17;;14443:39;14477:3;14466:9;14462:19;14443:39;:::i;:::-;14433:49;;14535:3;14524:9;14520:19;14507:33;14491:49;;14565:2;14555:8;14552:16;14549:36;;;14581:1;14578;14571:12;15093:665;15188:6;15196;15204;15212;15265:3;15253:9;15244:7;15240:23;15236:33;15233:53;;;15282:1;15279;15272:12;15233:53;15321:9;15308:23;15340:31;15365:5;15340:31;:::i;:::-;15390:5;-1:-1:-1;15447:2:1;15432:18;;15419:32;15460:33;15419:32;15460:33;:::i;:::-;15512:7;-1:-1:-1;15566:2:1;15551:18;;15538:32;;-1:-1:-1;15621:2:1;15606:18;;15593:32;-1:-1:-1;;;;;15637:30:1;;15634:50;;;15680:1;15677;15670:12;15634:50;15703:49;15744:7;15735:6;15724:9;15720:22;15703:49;:::i;:::-;15693:59;;;15093:665;;;;;;;:::o;15763:622::-;15858:6;15866;15874;15882;15890;15943:3;15931:9;15922:7;15918:23;15914:33;15911:53;;;15960:1;15957;15950:12;15911:53;15983:28;16001:9;15983:28;:::i;:::-;15973:38;;16030:37;16063:2;16052:9;16048:18;16030:37;:::i;:::-;16020:47;;16114:2;16103:9;16099:18;16086:32;16076:42;;16169:2;16158:9;16154:18;16141:32;-1:-1:-1;;;;;16188:6:1;16185:30;16182:50;;;16228:1;16225;16218:12;16182:50;16267:58;16317:7;16308:6;16297:9;16293:22;16267:58;:::i;:::-;15763:622;;;;-1:-1:-1;15763:622:1;;-1:-1:-1;16344:8:1;;16241:84;15763:622;-1:-1:-1;;;15763:622:1:o;16390:324::-;16465:6;16473;16481;16534:2;16522:9;16513:7;16509:23;16505:32;16502:52;;;16550:1;16547;16540:12;16502:52;16573:28;16591:9;16573:28;:::i;:::-;16563:38;;16620:37;16653:2;16642:9;16638:18;16620:37;:::i;:::-;16610:47;;16704:2;16693:9;16689:18;16676:32;16666:42;;16390:324;;;;;:::o;16719:388::-;16787:6;16795;16848:2;16836:9;16827:7;16823:23;16819:32;16816:52;;;16864:1;16861;16854:12;16816:52;16903:9;16890:23;16922:31;16947:5;16922:31;:::i;:::-;16972:5;-1:-1:-1;17029:2:1;17014:18;;17001:32;17042:33;17001:32;17042:33;:::i;17112:907::-;17246:6;17254;17262;17270;17278;17331:3;17319:9;17310:7;17306:23;17302:33;17299:53;;;17348:1;17345;17338:12;17299:53;17371:28;17389:9;17371:28;:::i;:::-;17361:38;;17450:2;17439:9;17435:18;17422:32;-1:-1:-1;;;;;17514:2:1;17506:6;17503:14;17500:34;;;17530:1;17527;17520:12;17500:34;17553:49;17594:7;17585:6;17574:9;17570:22;17553:49;:::i;:::-;17543:59;;17655:2;17644:9;17640:18;17627:32;17611:48;;17684:2;17674:8;17671:16;17668:36;;;17700:1;17697;17690:12;17668:36;17723:63;17778:7;17767:8;17756:9;17752:24;17723:63;:::i;:::-;17713:73;;17805:35;17836:2;17825:9;17821:18;17805:35;:::i;18024:460::-;18108:6;18116;18124;18132;18185:3;18173:9;18164:7;18160:23;18156:33;18153:53;;;18202:1;18199;18192:12;18153:53;18225:28;18243:9;18225:28;:::i;:::-;18215:38;;18272:37;18305:2;18294:9;18290:18;18272:37;:::i;:::-;18262:47;;18359:2;18348:9;18344:18;18331:32;18372:31;18397:5;18372:31;:::i;:::-;18024:460;;;;-1:-1:-1;18422:5:1;;18474:2;18459:18;18446:32;;-1:-1:-1;;18024:460:1:o;18848:380::-;18927:1;18923:12;;;;18970;;;18991:61;;19045:4;19037:6;19033:17;19023:27;;18991:61;19098:2;19090:6;19087:14;19067:18;19064:38;19061:161;;;19144:10;19139:3;19135:20;19132:1;19125:31;19179:4;19176:1;19169:15;19207:4;19204:1;19197:15;19061:161;;18848:380;;;:::o;19233:271::-;19416:6;19408;19403:3;19390:33;19372:3;19442:16;;19467:13;;;19442:16;19233:271;-1:-1:-1;19233:271:1:o;21163:410::-;21365:2;21347:21;;;21404:2;21384:18;;;21377:30;21443:34;21438:2;21423:18;;21416:62;-1:-1:-1;;;21509:2:1;21494:18;;21487:44;21563:3;21548:19;;21163:410::o;22406:266::-;22494:6;22489:3;22482:19;22546:6;22539:5;22532:4;22527:3;22523:14;22510:43;-1:-1:-1;22598:1:1;22573:16;;;22591:4;22569:27;;;22562:38;;;;22654:2;22633:15;;;-1:-1:-1;;22629:29:1;22620:39;;;22616:50;;22406:266::o;22677:326::-;22872:6;22864;22860:19;22849:9;22842:38;22916:2;22911;22900:9;22896:18;22889:30;22823:4;22936:61;22993:2;22982:9;22978:18;22970:6;22962;22936:61;:::i;23421:127::-;23482:10;23477:3;23473:20;23470:1;23463:31;23513:4;23510:1;23503:15;23537:4;23534:1;23527:15;24722:127;24783:10;24778:3;24774:20;24771:1;24764:31;24814:4;24811:1;24804:15;24838:4;24835:1;24828:15;24854:135;24893:3;-1:-1:-1;;24914:17:1;;24911:43;;;24934:18;;:::i;:::-;-1:-1:-1;24981:1:1;24970:13;;24854:135::o;26038:428::-;26091:5;26144:3;26137:4;26129:6;26125:17;26121:27;26111:55;;26162:1;26159;26152:12;26111:55;26191:6;26185:13;26222:48;26238:31;26266:2;26238:31;:::i;26222:48::-;26295:2;26286:7;26279:19;26341:3;26334:4;26329:2;26321:6;26317:15;26313:26;26310:35;26307:55;;;26358:1;26355;26348:12;26307:55;26371:64;26432:2;26425:4;26416:7;26412:18;26405:4;26397:6;26393:17;26371:64;:::i;26471:1104::-;26584:6;26592;26645:2;26633:9;26624:7;26620:23;26616:32;26613:52;;;26661:1;26658;26651:12;26613:52;26694:9;26688:16;-1:-1:-1;;;;;26764:2:1;26756:6;26753:14;26750:34;;;26780:1;26777;26770:12;26750:34;26803:60;26855:7;26846:6;26835:9;26831:22;26803:60;:::i;:::-;26793:70;;26882:2;26872:12;;26930:2;26919:9;26915:18;26909:25;26959:2;26949:8;26946:16;26943:36;;;26975:1;26972;26965:12;26943:36;26998:24;;;-1:-1:-1;27053:4:1;27045:13;;27041:27;-1:-1:-1;27031:55:1;;27082:1;27079;27072:12;27031:55;27111:2;27105:9;27134:60;27150:43;27190:2;27150:43;:::i;27134:60::-;27228:15;;;27310:1;27306:10;;;;27298:19;;27294:28;;;27259:12;;;;27334:19;;;27331:39;;;27366:1;27363;27356:12;27331:39;27390:11;;;;27410:135;27426:6;27421:3;27418:15;27410:135;;;27492:10;;27480:23;;27443:12;;;;27523;;;;27410:135;;;27564:5;27554:15;;;;;;;26471:1104;;;;;:::o;29447:125::-;29487:4;29515:1;29512;29509:8;29506:34;;;29520:18;;:::i;:::-;-1:-1:-1;29557:9:1;;29447:125::o;29577:382::-;29788:6;29780;29775:3;29762:33;29880:2;29876:15;;;;-1:-1:-1;;29872:53:1;29814:16;;29861:65;;;29950:2;29942:11;;29577:382;-1:-1:-1;29577:382:1:o;29964:447::-;30196:3;30234:6;30228:13;30250:53;30296:6;30291:3;30284:4;30276:6;30272:17;30250:53;:::i;:::-;-1:-1:-1;;;30325:16:1;;30350:26;;;-1:-1:-1;30403:1:1;30392:13;;29964:447;-1:-1:-1;29964:447:1:o;30416:498::-;30616:4;30645:6;30690:2;30682:6;30678:15;30667:9;30660:34;30742:2;30734:6;30730:15;30725:2;30714:9;30710:18;30703:43;;30782:6;30777:2;30766:9;30762:18;30755:34;30825:3;30820:2;30809:9;30805:18;30798:31;30846:62;30903:3;30892:9;30888:19;30880:6;30872;30846:62;:::i;:::-;30838:70;30416:498;-1:-1:-1;;;;;;;30416:498:1:o;32138:493::-;32387:6;32379;32375:19;32364:9;32357:38;32431:3;32426:2;32415:9;32411:18;32404:31;32338:4;32452:62;32509:3;32498:9;32494:19;32486:6;32478;32452:62;:::i;:::-;-1:-1:-1;;;;;32550:31:1;;;;32545:2;32530:18;;32523:59;-1:-1:-1;32613:2:1;32598:18;32591:34;32444:70;32138:493;-1:-1:-1;;;32138:493:1:o;33349:435::-;33402:3;33440:5;33434:12;33467:6;33462:3;33455:19;33493:4;33522:2;33517:3;33513:12;33506:19;;33559:2;33552:5;33548:14;33580:1;33590:169;33604:6;33601:1;33598:13;33590:169;;;33665:13;;33653:26;;33699:12;;;;33734:15;;;;33626:1;33619:9;33590:169;;;-1:-1:-1;33775:3:1;;33349:435;-1:-1:-1;;;;;33349:435:1:o;33789:422::-;34014:2;34003:9;33996:21;33977:4;34040:45;34081:2;34070:9;34066:18;34058:6;34040:45;:::i;:::-;34133:9;34125:6;34121:22;34116:2;34105:9;34101:18;34094:50;34161:44;34198:6;34190;34161:44;:::i;:::-;34153:52;33789:422;-1:-1:-1;;;;;33789:422:1:o;34216:642::-;34497:6;34485:19;;34467:38;;-1:-1:-1;;;;;34541:32:1;;34536:2;34521:18;;34514:60;34561:3;34605:2;34590:18;;34583:31;;;-1:-1:-1;;34637:46:1;;34663:19;;34655:6;34637:46;:::i;:::-;34733:6;34726:14;34719:22;34714:2;34703:9;34699:18;34692:50;34791:9;34783:6;34779:22;34773:3;34762:9;34758:19;34751:51;34819:33;34845:6;34837;34819:33;:::i;:::-;34811:41;34216:642;-1:-1:-1;;;;;;;;34216:642:1:o;34863:245::-;34942:6;34950;35003:2;34991:9;34982:7;34978:23;34974:32;34971:52;;;35019:1;35016;35009:12;34971:52;-1:-1:-1;;35042:16:1;;35098:2;35083:18;;;35077:25;35042:16;;35077:25;;-1:-1:-1;34863:245:1:o;35981:335::-;36060:6;36113:2;36101:9;36092:7;36088:23;36084:32;36081:52;;;36129:1;36126;36119:12;36081:52;36162:9;36156:16;-1:-1:-1;;;;;36187:6:1;36184:30;36181:50;;;36227:1;36224;36217:12;36181:50;36250:60;36302:7;36293:6;36282:9;36278:22;36250:60;:::i;36321:557::-;36578:6;36570;36566:19;36555:9;36548:38;36622:3;36617:2;36606:9;36602:18;36595:31;36529:4;36649:46;36690:3;36679:9;36675:19;36667:6;36649:46;:::i;:::-;-1:-1:-1;;;;;36735:6:1;36731:31;36726:2;36715:9;36711:18;36704:59;36811:9;36803:6;36799:22;36794:2;36783:9;36779:18;36772:50;36839:33;36865:6;36857;36839:33;:::i;38055:128::-;38095:3;38126:1;38122:6;38119:1;38116:13;38113:39;;;38132:18;;:::i;:::-;-1:-1:-1;38168:9:1;;38055:128::o;38955:168::-;38995:7;39061:1;39057;39053:6;39049:14;39046:1;39043:21;39038:1;39031:9;39024:17;39020:45;39017:71;;;39068:18;;:::i;:::-;-1:-1:-1;39108:9:1;;38955:168::o;39128:274::-;39257:3;39295:6;39289:13;39311:53;39357:6;39352:3;39345:4;39337:6;39333:17;39311:53;:::i;:::-;39380:16;;;;;39128:274;-1:-1:-1;;39128:274:1:o;39407:261::-;39586:2;39575:9;39568:21;39549:4;39606:56;39658:2;39647:9;39643:18;39635:6;39606:56;:::i;39673:289::-;39848:6;39837:9;39830:25;39891:2;39886;39875:9;39871:18;39864:30;39811:4;39911:45;39952:2;39941:9;39937:18;39929:6;39911:45;:::i;41010:414::-;41212:2;41194:21;;;41251:2;41231:18;;;41224:30;41290:34;41285:2;41270:18;;41263:62;-1:-1:-1;;;41356:2:1;41341:18;;41334:48;41414:3;41399:19;;41010:414::o;41429:719::-;41732:6;41724;41720:19;41709:9;41702:38;41776:3;41771:2;41760:9;41756:18;41749:31;41683:4;41803:46;41844:3;41833:9;41829:19;41821:6;41803:46;:::i;:::-;-1:-1:-1;;;;;41889:6:1;41885:31;41880:2;41869:9;41865:18;41858:59;41965:9;41957:6;41953:22;41948:2;41937:9;41933:18;41926:50;41999:33;42025:6;42017;41999:33;:::i;:::-;41985:47;;42081:9;42073:6;42069:22;42063:3;42052:9;42048:19;42041:51;42109:33;42135:6;42127;42109:33;:::i;42153:786::-;42564:25;42559:3;42552:38;42534:3;42619:6;42613:13;42635:62;42690:6;42685:2;42680:3;42676:12;42669:4;42661:6;42657:17;42635:62;:::i;:::-;-1:-1:-1;;;42756:2:1;42716:16;;;42748:11;;;42741:40;42806:13;;42828:63;42806:13;42877:2;42869:11;;42862:4;42850:17;;42828:63;:::i;:::-;42911:17;42930:2;42907:26;;42153:786;-1:-1:-1;;;;42153:786:1:o;44890:840::-;45239:6;45231;45227:19;45216:9;45209:38;45283:3;45278:2;45267:9;45263:18;45256:31;45190:4;45310:46;45351:3;45340:9;45336:19;45328:6;45310:46;:::i;:::-;45404:9;45396:6;45392:22;45387:2;45376:9;45372:18;45365:50;45438:33;45464:6;45456;45438:33;:::i;:::-;-1:-1:-1;;;;;45545:15:1;;;45540:2;45525:18;;45518:43;45598:15;;45592:3;45577:19;;45570:44;45651:22;;;45498:3;45630:19;;45623:51;45424:47;-1:-1:-1;45691:33:1;45424:47;45709:6;45691:33;:::i;:::-;45683:41;44890:840;-1:-1:-1;;;;;;;;;44890:840:1:o;45735:489::-;-1:-1:-1;;;;;46004:15:1;;;45986:34;;46056:15;;46051:2;46036:18;;46029:43;46103:2;46088:18;;46081:34;;;46151:3;46146:2;46131:18;;46124:31;;;45929:4;;46172:46;;46198:19;;46190:6;46172:46;:::i;:::-;46164:54;45735:489;-1:-1:-1;;;;;;45735:489:1:o;46229:249::-;46298:6;46351:2;46339:9;46330:7;46326:23;46322:32;46319:52;;;46367:1;46364;46357:12;46319:52;46399:9;46393:16;46418:30;46442:5;46418:30;:::i;46828:136::-;46867:3;46895:5;46885:39;;46904:18;;:::i;:::-;-1:-1:-1;;;46940:18:1;;46828:136::o;48766:127::-;48827:10;48822:3;48818:20;48815:1;48808:31;48858:4;48855:1;48848:15;48882:4;48879:1;48872:15

Swarm Source

ipfs://9bf4e74d33912aceb8133ff3eec9cd4434ae1623fda0887647cfe8e44a8d0cd9
Loading...
Loading
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.