ETH Price: $3,388.96 (-2.03%)
Gas: 6 Gwei

Token

Bye BanX (ByeBanX)
 

Overview

Max Total Supply

666 ByeBanX

Holders

244

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
5 ByeBanX
0x719015233301a3780de75e30814e8019e2c197df
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

ByeBanX (https://byebanx.art) is originally a collection of 100 genesis unique NFT art pieces that celebrate the crypto world & the evolution from cash & traditional banking to the world of cryptocurrency.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
ByeBanx

Compiler Version
v0.8.10+commit.fc410830

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-01-31
*/

// SPDX-License-Identifier: MIT

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


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

pragma solidity ^0.8.0;

/**
 * @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
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 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

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

// File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol


// OpenZeppelin Contracts v4.4.1 (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 `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

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


// 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: @openzeppelin/contracts/utils/introspection/ERC165.sol


// 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: @openzeppelin/contracts/token/ERC721/IERC721.sol


// OpenZeppelin Contracts v4.4.1 (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`, 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 be 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 Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

    /**
     * @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 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);

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

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol


// OpenZeppelin Contracts v4.4.1 (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 tokenId);

    /**
     * @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/IERC721Metadata.sol


// 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/security/ReentrancyGuard.sol


// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}

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


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

pragma solidity ^0.8.0;

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

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

// File: @openzeppelin/contracts/utils/cryptography/ECDSA.sol


// OpenZeppelin Contracts v4.4.1 (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;


/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        } else if (error == RecoverError.InvalidSignatureV) {
            revert("ECDSA: invalid signature 'v' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        // Check the signature length
        // - case 65: r,s,v signature (standard)
        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else if (signature.length == 64) {
            bytes32 r;
            bytes32 vs;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            assembly {
                r := mload(add(signature, 0x20))
                vs := mload(add(signature, 0x40))
            }
            return tryRecover(hash, r, vs);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s;
        uint8 v;
        assembly {
            s := and(vs, 0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff)
            v := add(shr(255, vs), 27)
        }
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }
        if (v != 27 && v != 28) {
            return (address(0), RecoverError.InvalidSignatureV);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}

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


// 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: contracts/ERC721A.sol



pragma solidity ^0.8.0;









/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata and Enumerable extension. Built to optimize for lower gas during batch mints.
 *
 * Assumes serials are sequentially minted starting at 0 (e.g. 0, 1, 2, 3..).
 *
 * Assumes the number of issuable tokens (collection size) is capped and fits in a uint128.
 *
 * Does not support burning tokens to address(0).
 */
contract ERC721A is
  Context,
  ERC165,
  IERC721,
  IERC721Metadata,
  IERC721Enumerable
{
  using Address for address;
  using Strings for uint256;

  struct TokenOwnership {
    address addr;
    uint64 startTimestamp;
  }

  struct AddressData {
    uint128 balance;
    uint128 numberMinted;
  }

  uint256 private currentIndex = 0;

  uint256 internal immutable collectionSize;
  uint256 internal immutable maxBatchSize;

  // Token name
  string private _name;

  // Token symbol
  string private _symbol;

  // Mapping from token ID to ownership details
  // An empty struct value does not necessarily mean the token is unowned. See ownershipOf implementation for details.
  mapping(uint256 => TokenOwnership) private _ownerships;

  // Mapping owner address to address data
  mapping(address => AddressData) private _addressData;

  // 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
   * `maxBatchSize` refers to how much a minter can mint at a time.
   * `collectionSize_` refers to how many tokens are in the collection.
   */
  constructor(
    string memory name_,
    string memory symbol_,
    uint256 maxBatchSize_,
    uint256 collectionSize_
  ) {
    require(
      collectionSize_ > 0,
      "ERC721A: collection must have a nonzero supply"
    );
    require(maxBatchSize_ > 0, "ERC721A: max batch size must be nonzero");
    _name = name_;
    _symbol = symbol_;
    maxBatchSize = maxBatchSize_;
    collectionSize = collectionSize_;
  }

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

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

  /**
   * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
   * This read function is O(collectionSize). If calling from a separate contract, be sure to test gas first.
   * It may also degrade with extremely large collection sizes (e.g >> 10000), test for your use case.
   */
  function tokenOfOwnerByIndex(address owner, uint256 index)
    public
    view
    override
    returns (uint256)
  {
    require(index < balanceOf(owner), "ERC721A: owner index out of bounds");
    uint256 numMintedSoFar = totalSupply();
    uint256 tokenIdsIdx = 0;
    address currOwnershipAddr = address(0);
    for (uint256 i = 0; i < numMintedSoFar; i++) {
      TokenOwnership memory ownership = _ownerships[i];
      if (ownership.addr != address(0)) {
        currOwnershipAddr = ownership.addr;
      }
      if (currOwnershipAddr == owner) {
        if (tokenIdsIdx == index) {
          return i;
        }
        tokenIdsIdx++;
      }
    }
    revert("ERC721A: unable to get token of owner by index");
  }

  /**
   * @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 ||
      interfaceId == type(IERC721Enumerable).interfaceId ||
      super.supportsInterface(interfaceId);
  }

  /**
   * @dev See {IERC721-balanceOf}.
   */
  function balanceOf(address owner) public view override returns (uint256) {
    require(owner != address(0), "ERC721A: balance query for the zero address");
    return uint256(_addressData[owner].balance);
  }

  function _numberMinted(address owner) internal view returns (uint256) {
    require(
      owner != address(0),
      "ERC721A: number minted query for the zero address"
    );
    return uint256(_addressData[owner].numberMinted);
  }

  function ownershipOf(uint256 tokenId)
    internal
    view
    returns (TokenOwnership memory)
  {
    require(_exists(tokenId), "ERC721A: owner query for nonexistent token");

    uint256 lowestTokenToCheck;
    if (tokenId >= maxBatchSize) {
      lowestTokenToCheck = tokenId - maxBatchSize + 1;
    }

    for (uint256 curr = tokenId; curr >= lowestTokenToCheck; curr--) {
      TokenOwnership memory ownership = _ownerships[curr];
      if (ownership.addr != address(0)) {
        return ownership;
      }
    }

    revert("ERC721A: unable to determine the owner of token");
  }

  /**
   * @dev See {IERC721-ownerOf}.
   */
  function ownerOf(uint256 tokenId) public view override returns (address) {
    return ownershipOf(tokenId).addr;
  }

  /**
   * @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)
  {
    require(
      _exists(tokenId),
      "ERC721Metadata: URI query for nonexistent token"
    );

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

  /**
   * @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 overriden in child contracts.
   */
  function _baseURI() internal view virtual returns (string memory) {
    return "";
  }

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

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

    _approve(to, tokenId, owner);
  }

  /**
   * @dev See {IERC721-getApproved}.
   */
  function getApproved(uint256 tokenId) public view override returns (address) {
    require(_exists(tokenId), "ERC721A: approved query for nonexistent token");

    return _tokenApprovals[tokenId];
  }

  /**
   * @dev See {IERC721-setApprovalForAll}.
   */
  function setApprovalForAll(address operator, bool approved) public override {
    require(operator != _msgSender(), "ERC721A: approve to caller");

    _operatorApprovals[_msgSender()][operator] = approved;
    emit ApprovalForAll(_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 override {
    _transfer(from, to, tokenId);
  }

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

  /**
   * @dev See {IERC721-safeTransferFrom}.
   */
  function safeTransferFrom(
    address from,
    address to,
    uint256 tokenId,
    bytes memory _data
  ) public override {
    _transfer(from, to, tokenId);
    require(
      _checkOnERC721Received(from, to, tokenId, _data),
      "ERC721A: 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`),
   */
  function _exists(uint256 tokenId) internal view returns (bool) {
    return tokenId < currentIndex;
  }

  function _safeMint(address to, uint256 quantity) internal {
    _safeMint(to, quantity, "");
  }

  /**
   * @dev Mints `quantity` tokens and transfers them to `to`.
   *
   * Requirements:
   *
   * - there must be `quantity` tokens remaining unminted in the total collection.
   * - `to` cannot be the zero address.
   * - `quantity` cannot be larger than the max batch size.
   *
   * Emits a {Transfer} event.
   */
  function _safeMint(
    address to,
    uint256 quantity,
    bytes memory _data
  ) internal {
    uint256 startTokenId = currentIndex;
    require(to != address(0), "ERC721A: mint to the zero address");
    // We know if the first token in the batch doesn't exist, the other ones don't as well, because of serial ordering.
    require(!_exists(startTokenId), "ERC721A: token already minted");
    require(quantity <= maxBatchSize, "ERC721A: quantity to mint too high");

    _beforeTokenTransfers(address(0), to, startTokenId, quantity);

    AddressData memory addressData = _addressData[to];
    _addressData[to] = AddressData(
      addressData.balance + uint128(quantity),
      addressData.numberMinted + uint128(quantity)
    );
    _ownerships[startTokenId] = TokenOwnership(to, uint64(block.timestamp));

    uint256 updatedIndex = startTokenId;

    for (uint256 i = 0; i < quantity; i++) {
      emit Transfer(address(0), to, updatedIndex);
      require(
        _checkOnERC721Received(address(0), to, updatedIndex, _data),
        "ERC721A: transfer to non ERC721Receiver implementer"
      );
      updatedIndex++;
    }

    currentIndex = updatedIndex;
    _afterTokenTransfers(address(0), to, startTokenId, quantity);
  }

  /**
   * @dev Transfers `tokenId` from `from` to `to`.
   *
   * 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
  ) private {
    TokenOwnership memory prevOwnership = ownershipOf(tokenId);

    bool isApprovedOrOwner = (_msgSender() == prevOwnership.addr ||
      getApproved(tokenId) == _msgSender() ||
      isApprovedForAll(prevOwnership.addr, _msgSender()));

    require(
      isApprovedOrOwner,
      "ERC721A: transfer caller is not owner nor approved"
    );

    require(
      prevOwnership.addr == from,
      "ERC721A: transfer from incorrect owner"
    );
    require(to != address(0), "ERC721A: transfer to the zero address");

    _beforeTokenTransfers(from, to, tokenId, 1);

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

    _addressData[from].balance -= 1;
    _addressData[to].balance += 1;
    _ownerships[tokenId] = TokenOwnership(to, uint64(block.timestamp));

    // If the ownership slot of tokenId+1 is not explicitly set, that means the transfer initiator owns it.
    // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
    uint256 nextTokenId = tokenId + 1;
    if (_ownerships[nextTokenId].addr == address(0)) {
      if (_exists(nextTokenId)) {
        _ownerships[nextTokenId] = TokenOwnership(
          prevOwnership.addr,
          prevOwnership.startTimestamp
        );
      }
    }

    emit Transfer(from, to, tokenId);
    _afterTokenTransfers(from, to, tokenId, 1);
  }

  /**
   * @dev Approve `to` to operate on `tokenId`
   *
   * Emits a {Approval} event.
   */
  function _approve(
    address to,
    uint256 tokenId,
    address owner
  ) private {
    _tokenApprovals[tokenId] = to;
    emit Approval(owner, to, tokenId);
  }

  uint256 public nextOwnerToExplicitlySet = 0;

  /**
   * @dev Explicitly set `owners` to eliminate loops in future calls of ownerOf().
   */
  function _setOwnersExplicit(uint256 quantity) internal {
    uint256 oldNextOwnerToSet = nextOwnerToExplicitlySet;
    require(quantity > 0, "quantity must be nonzero");
    uint256 endIndex = oldNextOwnerToSet + quantity - 1;
    if (endIndex > collectionSize - 1) {
      endIndex = collectionSize - 1;
    }
    // We know if the last one in the group exists, all in the group exist, due to serial ordering.
    require(_exists(endIndex), "not enough minted yet for this cleanup");
    for (uint256 i = oldNextOwnerToSet; i <= endIndex; i++) {
      if (_ownerships[i].addr == address(0)) {
        TokenOwnership memory ownership = ownershipOf(i);
        _ownerships[i] = TokenOwnership(
          ownership.addr,
          ownership.startTimestamp
        );
      }
    }
    nextOwnerToExplicitlySet = endIndex + 1;
  }

  /**
   * @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(to).onERC721Received.selector;
      } catch (bytes memory reason) {
        if (reason.length == 0) {
          revert("ERC721A: transfer to non ERC721Receiver implementer");
        } else {
          assembly {
            revert(add(32, reason), mload(reason))
          }
        }
      }
    } else {
      return true;
    }
  }

  /**
   * @dev Hook that is called before a set of serially-ordered token ids are about to be transferred. This includes minting.
   *
   * startTokenId - the first token id to be transferred
   * quantity - the amount to be transferred
   *
   * 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`.
   */
  function _beforeTokenTransfers(
    address from,
    address to,
    uint256 startTokenId,
    uint256 quantity
  ) internal virtual {}

  /**
   * @dev Hook that is called after a set of serially-ordered token ids have been transferred. This includes
   * minting.
   *
   * startTokenId - the first token id to be transferred
   * quantity - the amount to be transferred
   *
   * Calling conditions:
   *
   * - when `from` and `to` are both non-zero.
   * - `from` and `to` are never both zero.
   */
  function _afterTokenTransfers(
    address from,
    address to,
    uint256 startTokenId,
    uint256 quantity
  ) internal virtual {}
}
// File: @openzeppelin/contracts/access/Ownable.sol


// OpenZeppelin Contracts v4.4.1 (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 Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        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/ByeBanx.sol



pragma solidity ^0.8.0;





contract ByeBanx is Ownable, ERC721A, ReentrancyGuard {
    using Strings for uint256;
    using ECDSA for bytes32;

    string public baseURI = "ipfs://QmSAo4kt2N9mdgwTF5MREgSWHoF3CxwwmbhZV5M3u83SVg/";
    uint256 public cost = 0.1 ether;
    uint16 public maxSupply = 666;
    uint16 private privateMaxSupply = 660;
    uint public maxMintAmount = 2;
    bool public publicSale = false;
    bool public privateSale = false;
    address public signer1;
    address public signer2;
    address public signer3;
    address public signer4;


    constructor() ERC721A ("Bye BanX", "ByeBanX", 6, maxSupply){}

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

    function mint(uint _mintAmount) external payable {
        require(publicSale, "Minting currently on hold");
        require(_mintAmount <= maxMintAmount, "Maximum mint amount exceeded");
        require(totalSupply() + _mintAmount <= maxSupply, "Purchase would exceed max supply of NFT");
        mintX(_mintAmount);
    }

// TODO: edit to support second group whitelist to mint 4 
    function privateSaleMint(uint _mintAmount, bytes memory signature) external payable {
        require(privateSale, "Private sale is not currently running");
        uint8 group = 0;
        address recover = recoverSignerAddress(msg.sender, signature);
        if (recover == signer1) {
            group = 1;
        }else if (recover == signer2) {
            group = 2;
        }else if (recover == signer3) {
            group = 3;
        }else if (recover == signer4) {
            group = 4;
        }

        require(group > 0 && group <= 4, "Address not whitelisted for sale");
        require(totalSupply() + _mintAmount <= privateMaxSupply, "Purchase would exceed max supply of private sale");
        require(balanceOf(msg.sender) + _mintAmount <= group, "Minting would exceed max per wallet for presale");
        mintX(_mintAmount);
    }

    function mintX(uint _mintAmount) private {
        require(_mintAmount > 0, "Amount to mint can not be 0");
        if (msg.sender != owner()) {
            require(msg.value >= cost * _mintAmount, "Amount sent less than the cost of minting NFT(s)");
        }
        _safeMint(msg.sender, _mintAmount);
    }

    function walletOfOwner(address _owner) public view returns (uint256[] memory){
        uint256 ownerTokenCount = balanceOf(_owner);
        uint256[] memory tokenIds = new uint256[](ownerTokenCount);
        for (uint256 i; i < ownerTokenCount; i++) {
            tokenIds[i] = tokenOfOwnerByIndex(_owner, i);
        }
        return tokenIds;
    }

    function tokenURI(uint256 tokenId) public view virtual override returns (string memory){

        require(_exists(tokenId), "ERC721Metadata: tokenURI queried for nonexistent token");
        string memory currentBaseURI = _baseURI();
        return bytes(currentBaseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString(), ".json")) : "";
    }

    //
    function hashTransaction(address minter) private pure returns (bytes32) {
        bytes32 argsHash = keccak256(abi.encodePacked(minter));
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", argsHash));
    }

    function recoverSignerAddress(address minter, bytes memory signature) private pure returns (address) {
        bytes32 hash = hashTransaction(minter);
        return hash.recover(signature);
    }


    // Access control

    function devMint(uint _mintAmount) external onlyOwner() {
        require(totalSupply() + _mintAmount <= maxSupply, "Purchase would exceed max supply of NFT");
        mintX(_mintAmount);
    }

    function setSigner(address _signer) public onlyOwner() {
        signer1 = _signer;
    }

    function setSigner2(address _signer) public onlyOwner() {
        signer2 = _signer;
    }

    function setSigner3(address _signer) public onlyOwner() {
        signer3 = _signer;
    }

    function setSigner4(address _signer) public onlyOwner() {
        signer4 = _signer;
    }

    function setCost(uint256 _cost) public onlyOwner() {
        cost = _cost;
    }

    function setMaxMintAmount(uint256 _maxMintAmount) public onlyOwner() {
        maxMintAmount = _maxMintAmount;
    }

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

    function togglePublicSale() public onlyOwner() {
        publicSale = !publicSale;
    }

    function togglePrivateSale() public onlyOwner() {
        privateSale = !privateSale;
    }

    function configure(bool _publicSale, bool _privateSale, uint256 _maxMintAmount,
        address _signer1, address _signer2, address _signer3, address _signer4) public onlyOwner() {
        publicSale = _publicSale;
        privateSale = _privateSale;
        maxMintAmount = _maxMintAmount;
        signer1 = _signer1;
        signer2 = _signer2;
        signer3 = _signer3;
        signer4 = _signer4;
    }

    function withdraw() public payable onlyOwner() {
        (bool success,) = address(msg.sender).call{value : address(this).balance}("");
        require(success, "Unable to withdraw balance");
    }

}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"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":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"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":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"_publicSale","type":"bool"},{"internalType":"bool","name":"_privateSale","type":"bool"},{"internalType":"uint256","name":"_maxMintAmount","type":"uint256"},{"internalType":"address","name":"_signer1","type":"address"},{"internalType":"address","name":"_signer2","type":"address"},{"internalType":"address","name":"_signer3","type":"address"},{"internalType":"address","name":"_signer4","type":"address"}],"name":"configure","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"cost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"}],"name":"devMint","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":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMintAmount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextOwnerToExplicitlySet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"privateSale","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"privateSaleMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"publicSale","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","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":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cost","type":"uint256"}],"name":"setCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxMintAmount","type":"uint256"}],"name":"setMaxMintAmount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_signer","type":"address"}],"name":"setSigner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_signer","type":"address"}],"name":"setSigner2","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_signer","type":"address"}],"name":"setSigner3","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_signer","type":"address"}],"name":"setSigner4","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"signer1","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"signer2","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"signer3","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"signer4","outputs":[{"internalType":"address","name":"","type":"address"}],"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":[],"name":"togglePrivateSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"togglePublicSale","outputs":[],"stateMutability":"nonpayable","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":"address","name":"_owner","type":"address"}],"name":"walletOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"}]

60006001819055600855610120604052603660c081815290620033e560e03980516200003491600a9160209091019062000228565b5067016345785d8a0000600b55600c805463ffffffff1916630294029a1790556002600d55600e805461ffff191690553480156200007157600080fd5b506040805180820182526008815267084f2ca4084c2dcb60c31b60208083019190915282518084019093526007835266084f2ca84c2dcb60cb1b90830152600c5490919060069061ffff16620000c733620001d8565b60008111620001345760405162461bcd60e51b815260206004820152602e60248201527f455243373231413a20636f6c6c656374696f6e206d757374206861766520612060448201526d6e6f6e7a65726f20737570706c7960901b60648201526084015b60405180910390fd5b60008211620001965760405162461bcd60e51b815260206004820152602760248201527f455243373231413a206d61782062617463682073697a65206d757374206265206044820152666e6f6e7a65726f60c81b60648201526084016200012b565b8351620001ab90600290602087019062000228565b508251620001c190600390602086019062000228565b5060a091909152608052505060016009556200030b565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b8280546200023690620002ce565b90600052602060002090601f0160209004810192826200025a5760008555620002a5565b82601f106200027557805160ff1916838001178555620002a5565b82800160010185558215620002a5579182015b82811115620002a557825182559160200191906001019062000288565b50620002b3929150620002b7565b5090565b5b80821115620002b35760008155600101620002b8565b600181811c90821680620002e357607f821691505b602082108114156200030557634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a0516130a96200033c60003960008181611e0701528181611e31015261230f0152600050506130a96000f3fe6080604052600436106102725760003560e01c806355f804b31161014f578063a22cb465116100c1578063dfe5dd681161007a578063dfe5dd6814610732578063e222c7f914610747578063e985e9c51461075c578063f2fde38b146107a5578063f9c01ea1146107c5578063feebf001146107e557600080fd5b8063a22cb4651461066f578063b88d4fde1461068f578063ba1f879f146106af578063c87b56dd146106ce578063d5abeb01146106ee578063d7224ba01461071c57600080fd5b80636f86b0c8116101135780636f86b0c8146105e157806370a08231146105f4578063715018a6146106145780638da5cb5b1461062957806395d89b4114610647578063a0712d681461065c57600080fd5b806355f804b31461054c5780636352211e1461056c5780636c0360eb1461058c5780636c19e783146105a15780636f22a298146105c157600080fd5b80633326502f116101e85780633ccfd60b116101ac5780633ccfd60b146104975780633eeb92f61461049f57806342842e0e146104bf578063438b6300146104df57806344a0d68a1461050c5780634f6ccce71461052c57600080fd5b80633326502f146103f757806333bc1c5c146104175780633410728214610431578063375a069a1461045757806338c0ac5f1461047757600080fd5b806313faede61161023a57806313faede61461034857806318160ddd1461036c578063239c70ae1461038157806323b872dd14610397578063258878cd146103b75780632f745c59146103d757600080fd5b806301ffc9a71461027757806306fdde03146102ac578063081812fc146102ce578063088a4ed014610306578063095ea7b314610328575b600080fd5b34801561028357600080fd5b5061029761029236600461291a565b610805565b60405190151581526020015b60405180910390f35b3480156102b857600080fd5b506102c1610872565b6040516102a3919061298f565b3480156102da57600080fd5b506102ee6102e93660046129a2565b610904565b6040516001600160a01b0390911681526020016102a3565b34801561031257600080fd5b506103266103213660046129a2565b610994565b005b34801561033457600080fd5b506103266103433660046129d7565b6109c3565b34801561035457600080fd5b5061035e600b5481565b6040519081526020016102a3565b34801561037857600080fd5b5060015461035e565b34801561038d57600080fd5b5061035e600d5481565b3480156103a357600080fd5b506103266103b2366004612a01565b610adb565b3480156103c357600080fd5b506011546102ee906001600160a01b031681565b3480156103e357600080fd5b5061035e6103f23660046129d7565b610ae6565b34801561040357600080fd5b50610326610412366004612a4d565b610c5f565b34801561042357600080fd5b50600e546102979060ff1681565b34801561043d57600080fd5b50600e546102ee906201000090046001600160a01b031681565b34801561046357600080fd5b506103266104723660046129a2565b610d10565b34801561048357600080fd5b50600f546102ee906001600160a01b031681565b610326610dbf565b3480156104ab57600080fd5b506010546102ee906001600160a01b031681565b3480156104cb57600080fd5b506103266104da366004612a01565b610e81565b3480156104eb57600080fd5b506104ff6104fa366004612acc565b610e9c565b6040516102a39190612ae7565b34801561051857600080fd5b506103266105273660046129a2565b610f3e565b34801561053857600080fd5b5061035e6105473660046129a2565b610f6d565b34801561055857600080fd5b50610326610567366004612bb7565b610fd6565b34801561057857600080fd5b506102ee6105873660046129a2565b611017565b34801561059857600080fd5b506102c1611029565b3480156105ad57600080fd5b506103266105bc366004612acc565b6110b7565b3480156105cd57600080fd5b506103266105dc366004612acc565b61110b565b6103266105ef366004612c20565b611157565b34801561060057600080fd5b5061035e61060f366004612acc565b6113c3565b34801561062057600080fd5b50610326611454565b34801561063557600080fd5b506000546001600160a01b03166102ee565b34801561065357600080fd5b506102c161148a565b61032661066a3660046129a2565b611499565b34801561067b57600080fd5b5061032661068a366004612c67565b61153d565b34801561069b57600080fd5b506103266106aa366004612c9a565b611602565b3480156106bb57600080fd5b50600e5461029790610100900460ff1681565b3480156106da57600080fd5b506102c16106e93660046129a2565b611635565b3480156106fa57600080fd5b50600c546107099061ffff1681565b60405161ffff90911681526020016102a3565b34801561072857600080fd5b5061035e60085481565b34801561073e57600080fd5b5061032661170a565b34801561075357600080fd5b50610326611751565b34801561076857600080fd5b50610297610777366004612d02565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b3480156107b157600080fd5b506103266107c0366004612acc565b61178f565b3480156107d157600080fd5b506103266107e0366004612acc565b611827565b3480156107f157600080fd5b50610326610800366004612acc565b611873565b60006001600160e01b031982166380ac58cd60e01b148061083657506001600160e01b03198216635b5e139f60e01b145b8061085157506001600160e01b0319821663780e9d6360e01b145b8061086c57506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606002805461088190612d2c565b80601f01602080910402602001604051908101604052809291908181526020018280546108ad90612d2c565b80156108fa5780601f106108cf576101008083540402835291602001916108fa565b820191906000526020600020905b8154815290600101906020018083116108dd57829003601f168201915b5050505050905090565b6000610911826001541190565b6109785760405162461bcd60e51b815260206004820152602d60248201527f455243373231413a20617070726f76656420717565727920666f72206e6f6e6560448201526c3c34b9ba32b73a103a37b5b2b760991b60648201526084015b60405180910390fd5b506000908152600660205260409020546001600160a01b031690565b6000546001600160a01b031633146109be5760405162461bcd60e51b815260040161096f90612d67565b600d55565b60006109ce82611017565b9050806001600160a01b0316836001600160a01b03161415610a3d5760405162461bcd60e51b815260206004820152602260248201527f455243373231413a20617070726f76616c20746f2063757272656e74206f776e60448201526132b960f11b606482015260840161096f565b336001600160a01b0382161480610a595750610a598133610777565b610acb5760405162461bcd60e51b815260206004820152603960248201527f455243373231413a20617070726f76652063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656420666f7220616c6c00000000000000606482015260840161096f565b610ad68383836118bf565b505050565b610ad683838361191b565b6000610af1836113c3565b8210610b4a5760405162461bcd60e51b815260206004820152602260248201527f455243373231413a206f776e657220696e646578206f7574206f6620626f756e604482015261647360f01b606482015260840161096f565b6000610b5560015490565b905060008060005b83811015610bff576000818152600460209081526040918290208251808401909352546001600160a01b038116808452600160a01b90910467ffffffffffffffff169183019190915215610bb057805192505b876001600160a01b0316836001600160a01b03161415610bec5786841415610bde5750935061086c92505050565b83610be881612db2565b9450505b5080610bf781612db2565b915050610b5d565b5060405162461bcd60e51b815260206004820152602e60248201527f455243373231413a20756e61626c6520746f2067657420746f6b656e206f662060448201526d0deeedccae440c4f240d2dcc8caf60931b606482015260840161096f565b6000546001600160a01b03163314610c895760405162461bcd60e51b815260040161096f90612d67565b600e8054600d9690965561ffff1990951696151561ff00191696909617610100951515959095029490941762010000600160b01b031916620100006001600160a01b039384160217909255600f80546001600160a01b0319908116938316939093179055601080548316938216939093179092556011805490911692909116919091179055565b6000546001600160a01b03163314610d3a5760405162461bcd60e51b815260040161096f90612d67565b600c5461ffff1681610d4b60015490565b610d559190612dcd565b1115610db35760405162461bcd60e51b815260206004820152602760248201527f507572636861736520776f756c6420657863656564206d617820737570706c79604482015266081bd98813919560ca1b606482015260840161096f565b610dbc81611ca3565b50565b6000546001600160a01b03163314610de95760405162461bcd60e51b815260040161096f90612d67565b604051600090339047908381818185875af1925050503d8060008114610e2b576040519150601f19603f3d011682016040523d82523d6000602084013e610e30565b606091505b5050905080610dbc5760405162461bcd60e51b815260206004820152601a60248201527f556e61626c6520746f2077697468647261772062616c616e6365000000000000604482015260640161096f565b610ad683838360405180602001604052806000815250611602565b60606000610ea9836113c3565b905060008167ffffffffffffffff811115610ec657610ec6612b2b565b604051908082528060200260200182016040528015610eef578160200160208202803683370190505b50905060005b82811015610f3657610f078582610ae6565b828281518110610f1957610f19612de5565b602090810291909101015280610f2e81612db2565b915050610ef5565b509392505050565b6000546001600160a01b03163314610f685760405162461bcd60e51b815260040161096f90612d67565b600b55565b6000610f7860015490565b8210610fd25760405162461bcd60e51b815260206004820152602360248201527f455243373231413a20676c6f62616c20696e646578206f7574206f6620626f756044820152626e647360e81b606482015260840161096f565b5090565b6000546001600160a01b031633146110005760405162461bcd60e51b815260040161096f90612d67565b805161101390600a906020840190612874565b5050565b600061102282611d85565b5192915050565b600a805461103690612d2c565b80601f016020809104026020016040519081016040528092919081815260200182805461106290612d2c565b80156110af5780601f10611084576101008083540402835291602001916110af565b820191906000526020600020905b81548152906001019060200180831161109257829003601f168201915b505050505081565b6000546001600160a01b031633146110e15760405162461bcd60e51b815260040161096f90612d67565b600e80546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b6000546001600160a01b031633146111355760405162461bcd60e51b815260040161096f90612d67565b601080546001600160a01b0319166001600160a01b0392909216919091179055565b600e54610100900460ff166111bc5760405162461bcd60e51b815260206004820152602560248201527f507269766174652073616c65206973206e6f742063757272656e746c792072756044820152646e6e696e6760d81b606482015260840161096f565b6000806111c93384611f2f565b600e549091506001600160a01b03808316620100009092041614156111f1576001915061124a565b600f546001600160a01b0382811691161415611210576002915061124a565b6010546001600160a01b038281169116141561122f576003915061124a565b6011546001600160a01b038281169116141561124a57600491505b60008260ff16118015611261575060048260ff1611155b6112ad5760405162461bcd60e51b815260206004820181905260248201527f41646472657373206e6f742077686974656c697374656420666f722073616c65604482015260640161096f565b600c5461ffff6201000090910416846112c560015490565b6112cf9190612dcd565b11156113365760405162461bcd60e51b815260206004820152603060248201527f507572636861736520776f756c6420657863656564206d617820737570706c7960448201526f206f6620707269766174652073616c6560801b606482015260840161096f565b8160ff1684611344336113c3565b61134e9190612dcd565b11156113b45760405162461bcd60e51b815260206004820152602f60248201527f4d696e74696e6720776f756c6420657863656564206d6178207065722077616c60448201526e6c657420666f722070726573616c6560881b606482015260840161096f565b6113bd84611ca3565b50505050565b60006001600160a01b03821661142f5760405162461bcd60e51b815260206004820152602b60248201527f455243373231413a2062616c616e636520717565727920666f7220746865207a60448201526a65726f206164647265737360a81b606482015260840161096f565b506001600160a01b03166000908152600560205260409020546001600160801b031690565b6000546001600160a01b0316331461147e5760405162461bcd60e51b815260040161096f90612d67565b6114886000611fc1565b565b60606003805461088190612d2c565b600e5460ff166114eb5760405162461bcd60e51b815260206004820152601960248201527f4d696e74696e672063757272656e746c79206f6e20686f6c6400000000000000604482015260640161096f565b600d54811115610d3a5760405162461bcd60e51b815260206004820152601c60248201527f4d6178696d756d206d696e7420616d6f756e7420657863656564656400000000604482015260640161096f565b6001600160a01b0382163314156115965760405162461bcd60e51b815260206004820152601a60248201527f455243373231413a20617070726f766520746f2063616c6c6572000000000000604482015260640161096f565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b61160d84848461191b565b61161984848484612011565b6113bd5760405162461bcd60e51b815260040161096f90612dfb565b6060611642826001541190565b6116ad5760405162461bcd60e51b815260206004820152603660248201527f4552433732314d657461646174613a20746f6b656e5552492071756572696564604482015275103337b9103737b732bc34b9ba32b73a103a37b5b2b760511b606482015260840161096f565b60006116b761210f565b905060008151116116d75760405180602001604052806000815250611703565b600a6116e28461211e565b6040516020016116f3929190612e6a565b6040516020818303038152906040525b9392505050565b6000546001600160a01b031633146117345760405162461bcd60e51b815260040161096f90612d67565b600e805461ff001981166101009182900460ff1615909102179055565b6000546001600160a01b0316331461177b5760405162461bcd60e51b815260040161096f90612d67565b600e805460ff19811660ff90911615179055565b6000546001600160a01b031633146117b95760405162461bcd60e51b815260040161096f90612d67565b6001600160a01b03811661181e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161096f565b610dbc81611fc1565b6000546001600160a01b031633146118515760405162461bcd60e51b815260040161096f90612d67565b601180546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b0316331461189d5760405162461bcd60e51b815260040161096f90612d67565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b600061192682611d85565b80519091506000906001600160a01b0316336001600160a01b0316148061195d57503361195284610904565b6001600160a01b0316145b8061196f5750815161196f9033610777565b9050806119d95760405162461bcd60e51b815260206004820152603260248201527f455243373231413a207472616e736665722063616c6c6572206973206e6f74206044820152711bdddb995c881b9bdc88185c1c1c9bdd995960721b606482015260840161096f565b846001600160a01b031682600001516001600160a01b031614611a4d5760405162461bcd60e51b815260206004820152602660248201527f455243373231413a207472616e736665722066726f6d20696e636f72726563746044820152651037bbb732b960d11b606482015260840161096f565b6001600160a01b038416611ab15760405162461bcd60e51b815260206004820152602560248201527f455243373231413a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b606482015260840161096f565b611ac160008484600001516118bf565b6001600160a01b0385166000908152600560205260408120805460019290611af39084906001600160801b0316612f25565b82546101009290920a6001600160801b038181021990931691831602179091556001600160a01b03861660009081526005602052604081208054600194509092611b3f91859116612f4d565b82546001600160801b039182166101009390930a9283029190920219909116179055506040805180820182526001600160a01b03808716825267ffffffffffffffff428116602080850191825260008981526004909152948520935184549151909216600160a01b026001600160e01b03199091169190921617179055611bc7846001612dcd565b6000818152600460205260409020549091506001600160a01b0316611c5957611bf1816001541190565b15611c595760408051808201825284516001600160a01b03908116825260208087015167ffffffffffffffff9081168285019081526000878152600490935294909120925183549451909116600160a01b026001600160e01b03199094169116179190911790555b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b505050505050565b60008111611cf35760405162461bcd60e51b815260206004820152601b60248201527f416d6f756e7420746f206d696e742063616e206e6f7420626520300000000000604482015260640161096f565b6000546001600160a01b03163314611d7b5780600b54611d139190612f78565b341015611d7b5760405162461bcd60e51b815260206004820152603060248201527f416d6f756e742073656e74206c657373207468616e2074686520636f7374206f60448201526f66206d696e74696e67204e465428732960801b606482015260840161096f565b610dbc338261221c565b6040805180820190915260008082526020820152611da4826001541190565b611e035760405162461bcd60e51b815260206004820152602a60248201527f455243373231413a206f776e657220717565727920666f72206e6f6e657869736044820152693a32b73a103a37b5b2b760b11b606482015260840161096f565b60007f00000000000000000000000000000000000000000000000000000000000000008310611e6457611e567f000000000000000000000000000000000000000000000000000000000000000084612f97565b611e61906001612dcd565b90505b825b818110611ece576000818152600460209081526040918290208251808401909352546001600160a01b038116808452600160a01b90910467ffffffffffffffff169183019190915215611ebb57949350505050565b5080611ec681612fae565b915050611e66565b5060405162461bcd60e51b815260206004820152602f60248201527f455243373231413a20756e61626c6520746f2064657465726d696e652074686560448201526e1037bbb732b91037b3103a37b5b2b760891b606482015260840161096f565b604080516bffffffffffffffffffffffff19606085901b16602080830191909152825180830360140181526034830184528051908201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000060548401526070808401919091528351808403909101815260909092019092528051910120600090611fb98184612236565b949350505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006001600160a01b0384163b1561210457604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612055903390899088908890600401612fc5565b6020604051808303816000875af1925050508015612090575060408051601f3d908101601f1916820190925261208d91810190613002565b60015b6120ea573d8080156120be576040519150601f19603f3d011682016040523d82523d6000602084013e6120c3565b606091505b5080516120e25760405162461bcd60e51b815260040161096f90612dfb565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611fb9565b506001949350505050565b6060600a805461088190612d2c565b6060816121425750506040805180820190915260018152600360fc1b602082015290565b8160005b811561216c578061215681612db2565b91506121659050600a83613035565b9150612146565b60008167ffffffffffffffff81111561218757612187612b2b565b6040519080825280601f01601f1916602001820160405280156121b1576020820181803683370190505b5090505b8415611fb9576121c6600183612f97565b91506121d3600a86613049565b6121de906030612dcd565b60f81b8183815181106121f3576121f3612de5565b60200101906001600160f81b031916908160001a905350612215600a86613035565b94506121b5565b611013828260405180602001604052806000815250612252565b6000806000612245858561252d565b91509150610f368161259d565b6001546001600160a01b0384166122b55760405162461bcd60e51b815260206004820152602160248201527f455243373231413a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b606482015260840161096f565b6122c0816001541190565b1561230d5760405162461bcd60e51b815260206004820152601d60248201527f455243373231413a20746f6b656e20616c7265616479206d696e746564000000604482015260640161096f565b7f00000000000000000000000000000000000000000000000000000000000000008311156123885760405162461bcd60e51b815260206004820152602260248201527f455243373231413a207175616e7469747920746f206d696e7420746f6f2068696044820152610ced60f31b606482015260840161096f565b6001600160a01b0384166000908152600560209081526040918290208251808401845290546001600160801b038082168352600160801b90910416918101919091528151808301909252805190919081906123e4908790612f4d565b6001600160801b031681526020018583602001516124029190612f4d565b6001600160801b039081169091526001600160a01b0380881660008181526005602090815260408083208751978301518716600160801b0297909616969096179094558451808601865291825267ffffffffffffffff4281168386019081528883526004909552948120915182549451909516600160a01b026001600160e01b031990941694909216939093179190911790915582905b858110156125225760405182906001600160a01b038916906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a46124e66000888488612011565b6125025760405162461bcd60e51b815260040161096f90612dfb565b8161250c81612db2565b925050808061251a90612db2565b915050612499565b506001819055611c9b565b6000808251604114156125645760208301516040840151606085015160001a61255887828585612758565b94509450505050612596565b82516040141561258e5760208301516040840151612583868383612845565b935093505050612596565b506000905060025b9250929050565b60008160048111156125b1576125b161305d565b14156125ba5750565b60018160048111156125ce576125ce61305d565b141561261c5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161096f565b60028160048111156126305761263061305d565b141561267e5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161096f565b60038160048111156126925761269261305d565b14156126eb5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161096f565b60048160048111156126ff576126ff61305d565b1415610dbc5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b606482015260840161096f565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561278f575060009050600361283c565b8460ff16601b141580156127a757508460ff16601c14155b156127b8575060009050600461283c565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561280c573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166128355760006001925092505061283c565b9150600090505b94509492505050565b6000806001600160ff1b03831660ff84901c601b0161286687828885612758565b935093505050935093915050565b82805461288090612d2c565b90600052602060002090601f0160209004810192826128a257600085556128e8565b82601f106128bb57805160ff19168380011785556128e8565b828001600101855582156128e8579182015b828111156128e85782518255916020019190600101906128cd565b50610fd29291505b80821115610fd257600081556001016128f0565b6001600160e01b031981168114610dbc57600080fd5b60006020828403121561292c57600080fd5b813561170381612904565b60005b8381101561295257818101518382015260200161293a565b838111156113bd5750506000910152565b6000815180845261297b816020860160208601612937565b601f01601f19169290920160200192915050565b6020815260006117036020830184612963565b6000602082840312156129b457600080fd5b5035919050565b80356001600160a01b03811681146129d257600080fd5b919050565b600080604083850312156129ea57600080fd5b6129f3836129bb565b946020939093013593505050565b600080600060608486031215612a1657600080fd5b612a1f846129bb565b9250612a2d602085016129bb565b9150604084013590509250925092565b803580151581146129d257600080fd5b600080600080600080600060e0888a031215612a6857600080fd5b612a7188612a3d565b9650612a7f60208901612a3d565b955060408801359450612a94606089016129bb565b9350612aa2608089016129bb565b9250612ab060a089016129bb565b9150612abe60c089016129bb565b905092959891949750929550565b600060208284031215612ade57600080fd5b611703826129bb565b6020808252825182820181905260009190848201906040850190845b81811015612b1f57835183529284019291840191600101612b03565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff80841115612b5c57612b5c612b2b565b604051601f8501601f19908116603f01168101908282118183101715612b8457612b84612b2b565b81604052809350858152868686011115612b9d57600080fd5b858560208301376000602087830101525050509392505050565b600060208284031215612bc957600080fd5b813567ffffffffffffffff811115612be057600080fd5b8201601f81018413612bf157600080fd5b611fb984823560208401612b41565b600082601f830112612c1157600080fd5b61170383833560208501612b41565b60008060408385031215612c3357600080fd5b82359150602083013567ffffffffffffffff811115612c5157600080fd5b612c5d85828601612c00565b9150509250929050565b60008060408385031215612c7a57600080fd5b612c83836129bb565b9150612c9160208401612a3d565b90509250929050565b60008060008060808587031215612cb057600080fd5b612cb9856129bb565b9350612cc7602086016129bb565b925060408501359150606085013567ffffffffffffffff811115612cea57600080fd5b612cf687828801612c00565b91505092959194509250565b60008060408385031215612d1557600080fd5b612d1e836129bb565b9150612c91602084016129bb565b600181811c90821680612d4057607f821691505b60208210811415612d6157634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052601160045260246000fd5b6000600019821415612dc657612dc6612d9c565b5060010190565b60008219821115612de057612de0612d9c565b500190565b634e487b7160e01b600052603260045260246000fd5b60208082526033908201527f455243373231413a207472616e7366657220746f206e6f6e204552433732315260408201527232b1b2b4bb32b91034b6b83632b6b2b73a32b960691b606082015260800190565b60008151612e60818560208601612937565b9290920192915050565b600080845481600182811c915080831680612e8657607f831692505b6020808410821415612ea657634e487b7160e01b86526022600452602486fd5b818015612eba5760018114612ecb57612ef8565b60ff19861689528489019650612ef8565b60008b81526020902060005b86811015612ef05781548b820152908501908301612ed7565b505084890196505b505050505050612f1c612f0b8286612e4e565b64173539b7b760d91b815260050190565b95945050505050565b60006001600160801b0383811690831681811015612f4557612f45612d9c565b039392505050565b60006001600160801b03808316818516808303821115612f6f57612f6f612d9c565b01949350505050565b6000816000190483118215151615612f9257612f92612d9c565b500290565b600082821015612fa957612fa9612d9c565b500390565b600081612fbd57612fbd612d9c565b506000190190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612ff890830184612963565b9695505050505050565b60006020828403121561301457600080fd5b815161170381612904565b634e487b7160e01b600052601260045260246000fd5b6000826130445761304461301f565b500490565b6000826130585761305861301f565b500690565b634e487b7160e01b600052602160045260246000fdfea2646970667358221220051321bb2d344c9847c474f13fcac5981c1430003448f02644d8a592ea81ada164736f6c634300080a0033697066733a2f2f516d53416f346b74324e396d6467775446354d5245675357486f4633437877776d62685a56354d337538335356672f

Deployed Bytecode

0x6080604052600436106102725760003560e01c806355f804b31161014f578063a22cb465116100c1578063dfe5dd681161007a578063dfe5dd6814610732578063e222c7f914610747578063e985e9c51461075c578063f2fde38b146107a5578063f9c01ea1146107c5578063feebf001146107e557600080fd5b8063a22cb4651461066f578063b88d4fde1461068f578063ba1f879f146106af578063c87b56dd146106ce578063d5abeb01146106ee578063d7224ba01461071c57600080fd5b80636f86b0c8116101135780636f86b0c8146105e157806370a08231146105f4578063715018a6146106145780638da5cb5b1461062957806395d89b4114610647578063a0712d681461065c57600080fd5b806355f804b31461054c5780636352211e1461056c5780636c0360eb1461058c5780636c19e783146105a15780636f22a298146105c157600080fd5b80633326502f116101e85780633ccfd60b116101ac5780633ccfd60b146104975780633eeb92f61461049f57806342842e0e146104bf578063438b6300146104df57806344a0d68a1461050c5780634f6ccce71461052c57600080fd5b80633326502f146103f757806333bc1c5c146104175780633410728214610431578063375a069a1461045757806338c0ac5f1461047757600080fd5b806313faede61161023a57806313faede61461034857806318160ddd1461036c578063239c70ae1461038157806323b872dd14610397578063258878cd146103b75780632f745c59146103d757600080fd5b806301ffc9a71461027757806306fdde03146102ac578063081812fc146102ce578063088a4ed014610306578063095ea7b314610328575b600080fd5b34801561028357600080fd5b5061029761029236600461291a565b610805565b60405190151581526020015b60405180910390f35b3480156102b857600080fd5b506102c1610872565b6040516102a3919061298f565b3480156102da57600080fd5b506102ee6102e93660046129a2565b610904565b6040516001600160a01b0390911681526020016102a3565b34801561031257600080fd5b506103266103213660046129a2565b610994565b005b34801561033457600080fd5b506103266103433660046129d7565b6109c3565b34801561035457600080fd5b5061035e600b5481565b6040519081526020016102a3565b34801561037857600080fd5b5060015461035e565b34801561038d57600080fd5b5061035e600d5481565b3480156103a357600080fd5b506103266103b2366004612a01565b610adb565b3480156103c357600080fd5b506011546102ee906001600160a01b031681565b3480156103e357600080fd5b5061035e6103f23660046129d7565b610ae6565b34801561040357600080fd5b50610326610412366004612a4d565b610c5f565b34801561042357600080fd5b50600e546102979060ff1681565b34801561043d57600080fd5b50600e546102ee906201000090046001600160a01b031681565b34801561046357600080fd5b506103266104723660046129a2565b610d10565b34801561048357600080fd5b50600f546102ee906001600160a01b031681565b610326610dbf565b3480156104ab57600080fd5b506010546102ee906001600160a01b031681565b3480156104cb57600080fd5b506103266104da366004612a01565b610e81565b3480156104eb57600080fd5b506104ff6104fa366004612acc565b610e9c565b6040516102a39190612ae7565b34801561051857600080fd5b506103266105273660046129a2565b610f3e565b34801561053857600080fd5b5061035e6105473660046129a2565b610f6d565b34801561055857600080fd5b50610326610567366004612bb7565b610fd6565b34801561057857600080fd5b506102ee6105873660046129a2565b611017565b34801561059857600080fd5b506102c1611029565b3480156105ad57600080fd5b506103266105bc366004612acc565b6110b7565b3480156105cd57600080fd5b506103266105dc366004612acc565b61110b565b6103266105ef366004612c20565b611157565b34801561060057600080fd5b5061035e61060f366004612acc565b6113c3565b34801561062057600080fd5b50610326611454565b34801561063557600080fd5b506000546001600160a01b03166102ee565b34801561065357600080fd5b506102c161148a565b61032661066a3660046129a2565b611499565b34801561067b57600080fd5b5061032661068a366004612c67565b61153d565b34801561069b57600080fd5b506103266106aa366004612c9a565b611602565b3480156106bb57600080fd5b50600e5461029790610100900460ff1681565b3480156106da57600080fd5b506102c16106e93660046129a2565b611635565b3480156106fa57600080fd5b50600c546107099061ffff1681565b60405161ffff90911681526020016102a3565b34801561072857600080fd5b5061035e60085481565b34801561073e57600080fd5b5061032661170a565b34801561075357600080fd5b50610326611751565b34801561076857600080fd5b50610297610777366004612d02565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b3480156107b157600080fd5b506103266107c0366004612acc565b61178f565b3480156107d157600080fd5b506103266107e0366004612acc565b611827565b3480156107f157600080fd5b50610326610800366004612acc565b611873565b60006001600160e01b031982166380ac58cd60e01b148061083657506001600160e01b03198216635b5e139f60e01b145b8061085157506001600160e01b0319821663780e9d6360e01b145b8061086c57506301ffc9a760e01b6001600160e01b03198316145b92915050565b60606002805461088190612d2c565b80601f01602080910402602001604051908101604052809291908181526020018280546108ad90612d2c565b80156108fa5780601f106108cf576101008083540402835291602001916108fa565b820191906000526020600020905b8154815290600101906020018083116108dd57829003601f168201915b5050505050905090565b6000610911826001541190565b6109785760405162461bcd60e51b815260206004820152602d60248201527f455243373231413a20617070726f76656420717565727920666f72206e6f6e6560448201526c3c34b9ba32b73a103a37b5b2b760991b60648201526084015b60405180910390fd5b506000908152600660205260409020546001600160a01b031690565b6000546001600160a01b031633146109be5760405162461bcd60e51b815260040161096f90612d67565b600d55565b60006109ce82611017565b9050806001600160a01b0316836001600160a01b03161415610a3d5760405162461bcd60e51b815260206004820152602260248201527f455243373231413a20617070726f76616c20746f2063757272656e74206f776e60448201526132b960f11b606482015260840161096f565b336001600160a01b0382161480610a595750610a598133610777565b610acb5760405162461bcd60e51b815260206004820152603960248201527f455243373231413a20617070726f76652063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656420666f7220616c6c00000000000000606482015260840161096f565b610ad68383836118bf565b505050565b610ad683838361191b565b6000610af1836113c3565b8210610b4a5760405162461bcd60e51b815260206004820152602260248201527f455243373231413a206f776e657220696e646578206f7574206f6620626f756e604482015261647360f01b606482015260840161096f565b6000610b5560015490565b905060008060005b83811015610bff576000818152600460209081526040918290208251808401909352546001600160a01b038116808452600160a01b90910467ffffffffffffffff169183019190915215610bb057805192505b876001600160a01b0316836001600160a01b03161415610bec5786841415610bde5750935061086c92505050565b83610be881612db2565b9450505b5080610bf781612db2565b915050610b5d565b5060405162461bcd60e51b815260206004820152602e60248201527f455243373231413a20756e61626c6520746f2067657420746f6b656e206f662060448201526d0deeedccae440c4f240d2dcc8caf60931b606482015260840161096f565b6000546001600160a01b03163314610c895760405162461bcd60e51b815260040161096f90612d67565b600e8054600d9690965561ffff1990951696151561ff00191696909617610100951515959095029490941762010000600160b01b031916620100006001600160a01b039384160217909255600f80546001600160a01b0319908116938316939093179055601080548316938216939093179092556011805490911692909116919091179055565b6000546001600160a01b03163314610d3a5760405162461bcd60e51b815260040161096f90612d67565b600c5461ffff1681610d4b60015490565b610d559190612dcd565b1115610db35760405162461bcd60e51b815260206004820152602760248201527f507572636861736520776f756c6420657863656564206d617820737570706c79604482015266081bd98813919560ca1b606482015260840161096f565b610dbc81611ca3565b50565b6000546001600160a01b03163314610de95760405162461bcd60e51b815260040161096f90612d67565b604051600090339047908381818185875af1925050503d8060008114610e2b576040519150601f19603f3d011682016040523d82523d6000602084013e610e30565b606091505b5050905080610dbc5760405162461bcd60e51b815260206004820152601a60248201527f556e61626c6520746f2077697468647261772062616c616e6365000000000000604482015260640161096f565b610ad683838360405180602001604052806000815250611602565b60606000610ea9836113c3565b905060008167ffffffffffffffff811115610ec657610ec6612b2b565b604051908082528060200260200182016040528015610eef578160200160208202803683370190505b50905060005b82811015610f3657610f078582610ae6565b828281518110610f1957610f19612de5565b602090810291909101015280610f2e81612db2565b915050610ef5565b509392505050565b6000546001600160a01b03163314610f685760405162461bcd60e51b815260040161096f90612d67565b600b55565b6000610f7860015490565b8210610fd25760405162461bcd60e51b815260206004820152602360248201527f455243373231413a20676c6f62616c20696e646578206f7574206f6620626f756044820152626e647360e81b606482015260840161096f565b5090565b6000546001600160a01b031633146110005760405162461bcd60e51b815260040161096f90612d67565b805161101390600a906020840190612874565b5050565b600061102282611d85565b5192915050565b600a805461103690612d2c565b80601f016020809104026020016040519081016040528092919081815260200182805461106290612d2c565b80156110af5780601f10611084576101008083540402835291602001916110af565b820191906000526020600020905b81548152906001019060200180831161109257829003601f168201915b505050505081565b6000546001600160a01b031633146110e15760405162461bcd60e51b815260040161096f90612d67565b600e80546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b6000546001600160a01b031633146111355760405162461bcd60e51b815260040161096f90612d67565b601080546001600160a01b0319166001600160a01b0392909216919091179055565b600e54610100900460ff166111bc5760405162461bcd60e51b815260206004820152602560248201527f507269766174652073616c65206973206e6f742063757272656e746c792072756044820152646e6e696e6760d81b606482015260840161096f565b6000806111c93384611f2f565b600e549091506001600160a01b03808316620100009092041614156111f1576001915061124a565b600f546001600160a01b0382811691161415611210576002915061124a565b6010546001600160a01b038281169116141561122f576003915061124a565b6011546001600160a01b038281169116141561124a57600491505b60008260ff16118015611261575060048260ff1611155b6112ad5760405162461bcd60e51b815260206004820181905260248201527f41646472657373206e6f742077686974656c697374656420666f722073616c65604482015260640161096f565b600c5461ffff6201000090910416846112c560015490565b6112cf9190612dcd565b11156113365760405162461bcd60e51b815260206004820152603060248201527f507572636861736520776f756c6420657863656564206d617820737570706c7960448201526f206f6620707269766174652073616c6560801b606482015260840161096f565b8160ff1684611344336113c3565b61134e9190612dcd565b11156113b45760405162461bcd60e51b815260206004820152602f60248201527f4d696e74696e6720776f756c6420657863656564206d6178207065722077616c60448201526e6c657420666f722070726573616c6560881b606482015260840161096f565b6113bd84611ca3565b50505050565b60006001600160a01b03821661142f5760405162461bcd60e51b815260206004820152602b60248201527f455243373231413a2062616c616e636520717565727920666f7220746865207a60448201526a65726f206164647265737360a81b606482015260840161096f565b506001600160a01b03166000908152600560205260409020546001600160801b031690565b6000546001600160a01b0316331461147e5760405162461bcd60e51b815260040161096f90612d67565b6114886000611fc1565b565b60606003805461088190612d2c565b600e5460ff166114eb5760405162461bcd60e51b815260206004820152601960248201527f4d696e74696e672063757272656e746c79206f6e20686f6c6400000000000000604482015260640161096f565b600d54811115610d3a5760405162461bcd60e51b815260206004820152601c60248201527f4d6178696d756d206d696e7420616d6f756e7420657863656564656400000000604482015260640161096f565b6001600160a01b0382163314156115965760405162461bcd60e51b815260206004820152601a60248201527f455243373231413a20617070726f766520746f2063616c6c6572000000000000604482015260640161096f565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b61160d84848461191b565b61161984848484612011565b6113bd5760405162461bcd60e51b815260040161096f90612dfb565b6060611642826001541190565b6116ad5760405162461bcd60e51b815260206004820152603660248201527f4552433732314d657461646174613a20746f6b656e5552492071756572696564604482015275103337b9103737b732bc34b9ba32b73a103a37b5b2b760511b606482015260840161096f565b60006116b761210f565b905060008151116116d75760405180602001604052806000815250611703565b600a6116e28461211e565b6040516020016116f3929190612e6a565b6040516020818303038152906040525b9392505050565b6000546001600160a01b031633146117345760405162461bcd60e51b815260040161096f90612d67565b600e805461ff001981166101009182900460ff1615909102179055565b6000546001600160a01b0316331461177b5760405162461bcd60e51b815260040161096f90612d67565b600e805460ff19811660ff90911615179055565b6000546001600160a01b031633146117b95760405162461bcd60e51b815260040161096f90612d67565b6001600160a01b03811661181e5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161096f565b610dbc81611fc1565b6000546001600160a01b031633146118515760405162461bcd60e51b815260040161096f90612d67565b601180546001600160a01b0319166001600160a01b0392909216919091179055565b6000546001600160a01b0316331461189d5760405162461bcd60e51b815260040161096f90612d67565b600f80546001600160a01b0319166001600160a01b0392909216919091179055565b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b600061192682611d85565b80519091506000906001600160a01b0316336001600160a01b0316148061195d57503361195284610904565b6001600160a01b0316145b8061196f5750815161196f9033610777565b9050806119d95760405162461bcd60e51b815260206004820152603260248201527f455243373231413a207472616e736665722063616c6c6572206973206e6f74206044820152711bdddb995c881b9bdc88185c1c1c9bdd995960721b606482015260840161096f565b846001600160a01b031682600001516001600160a01b031614611a4d5760405162461bcd60e51b815260206004820152602660248201527f455243373231413a207472616e736665722066726f6d20696e636f72726563746044820152651037bbb732b960d11b606482015260840161096f565b6001600160a01b038416611ab15760405162461bcd60e51b815260206004820152602560248201527f455243373231413a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b606482015260840161096f565b611ac160008484600001516118bf565b6001600160a01b0385166000908152600560205260408120805460019290611af39084906001600160801b0316612f25565b82546101009290920a6001600160801b038181021990931691831602179091556001600160a01b03861660009081526005602052604081208054600194509092611b3f91859116612f4d565b82546001600160801b039182166101009390930a9283029190920219909116179055506040805180820182526001600160a01b03808716825267ffffffffffffffff428116602080850191825260008981526004909152948520935184549151909216600160a01b026001600160e01b03199091169190921617179055611bc7846001612dcd565b6000818152600460205260409020549091506001600160a01b0316611c5957611bf1816001541190565b15611c595760408051808201825284516001600160a01b03908116825260208087015167ffffffffffffffff9081168285019081526000878152600490935294909120925183549451909116600160a01b026001600160e01b03199094169116179190911790555b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b505050505050565b60008111611cf35760405162461bcd60e51b815260206004820152601b60248201527f416d6f756e7420746f206d696e742063616e206e6f7420626520300000000000604482015260640161096f565b6000546001600160a01b03163314611d7b5780600b54611d139190612f78565b341015611d7b5760405162461bcd60e51b815260206004820152603060248201527f416d6f756e742073656e74206c657373207468616e2074686520636f7374206f60448201526f66206d696e74696e67204e465428732960801b606482015260840161096f565b610dbc338261221c565b6040805180820190915260008082526020820152611da4826001541190565b611e035760405162461bcd60e51b815260206004820152602a60248201527f455243373231413a206f776e657220717565727920666f72206e6f6e657869736044820152693a32b73a103a37b5b2b760b11b606482015260840161096f565b60007f00000000000000000000000000000000000000000000000000000000000000068310611e6457611e567f000000000000000000000000000000000000000000000000000000000000000684612f97565b611e61906001612dcd565b90505b825b818110611ece576000818152600460209081526040918290208251808401909352546001600160a01b038116808452600160a01b90910467ffffffffffffffff169183019190915215611ebb57949350505050565b5080611ec681612fae565b915050611e66565b5060405162461bcd60e51b815260206004820152602f60248201527f455243373231413a20756e61626c6520746f2064657465726d696e652074686560448201526e1037bbb732b91037b3103a37b5b2b760891b606482015260840161096f565b604080516bffffffffffffffffffffffff19606085901b16602080830191909152825180830360140181526034830184528051908201207f19457468657265756d205369676e6564204d6573736167653a0a33320000000060548401526070808401919091528351808403909101815260909092019092528051910120600090611fb98184612236565b949350505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006001600160a01b0384163b1561210457604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612055903390899088908890600401612fc5565b6020604051808303816000875af1925050508015612090575060408051601f3d908101601f1916820190925261208d91810190613002565b60015b6120ea573d8080156120be576040519150601f19603f3d011682016040523d82523d6000602084013e6120c3565b606091505b5080516120e25760405162461bcd60e51b815260040161096f90612dfb565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611fb9565b506001949350505050565b6060600a805461088190612d2c565b6060816121425750506040805180820190915260018152600360fc1b602082015290565b8160005b811561216c578061215681612db2565b91506121659050600a83613035565b9150612146565b60008167ffffffffffffffff81111561218757612187612b2b565b6040519080825280601f01601f1916602001820160405280156121b1576020820181803683370190505b5090505b8415611fb9576121c6600183612f97565b91506121d3600a86613049565b6121de906030612dcd565b60f81b8183815181106121f3576121f3612de5565b60200101906001600160f81b031916908160001a905350612215600a86613035565b94506121b5565b611013828260405180602001604052806000815250612252565b6000806000612245858561252d565b91509150610f368161259d565b6001546001600160a01b0384166122b55760405162461bcd60e51b815260206004820152602160248201527f455243373231413a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b606482015260840161096f565b6122c0816001541190565b1561230d5760405162461bcd60e51b815260206004820152601d60248201527f455243373231413a20746f6b656e20616c7265616479206d696e746564000000604482015260640161096f565b7f00000000000000000000000000000000000000000000000000000000000000068311156123885760405162461bcd60e51b815260206004820152602260248201527f455243373231413a207175616e7469747920746f206d696e7420746f6f2068696044820152610ced60f31b606482015260840161096f565b6001600160a01b0384166000908152600560209081526040918290208251808401845290546001600160801b038082168352600160801b90910416918101919091528151808301909252805190919081906123e4908790612f4d565b6001600160801b031681526020018583602001516124029190612f4d565b6001600160801b039081169091526001600160a01b0380881660008181526005602090815260408083208751978301518716600160801b0297909616969096179094558451808601865291825267ffffffffffffffff4281168386019081528883526004909552948120915182549451909516600160a01b026001600160e01b031990941694909216939093179190911790915582905b858110156125225760405182906001600160a01b038916906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a46124e66000888488612011565b6125025760405162461bcd60e51b815260040161096f90612dfb565b8161250c81612db2565b925050808061251a90612db2565b915050612499565b506001819055611c9b565b6000808251604114156125645760208301516040840151606085015160001a61255887828585612758565b94509450505050612596565b82516040141561258e5760208301516040840151612583868383612845565b935093505050612596565b506000905060025b9250929050565b60008160048111156125b1576125b161305d565b14156125ba5750565b60018160048111156125ce576125ce61305d565b141561261c5760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604482015260640161096f565b60028160048111156126305761263061305d565b141561267e5760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e67746800604482015260640161096f565b60038160048111156126925761269261305d565b14156126eb5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b606482015260840161096f565b60048160048111156126ff576126ff61305d565b1415610dbc5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b606482015260840161096f565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a083111561278f575060009050600361283c565b8460ff16601b141580156127a757508460ff16601c14155b156127b8575060009050600461283c565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa15801561280c573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166128355760006001925092505061283c565b9150600090505b94509492505050565b6000806001600160ff1b03831660ff84901c601b0161286687828885612758565b935093505050935093915050565b82805461288090612d2c565b90600052602060002090601f0160209004810192826128a257600085556128e8565b82601f106128bb57805160ff19168380011785556128e8565b828001600101855582156128e8579182015b828111156128e85782518255916020019190600101906128cd565b50610fd29291505b80821115610fd257600081556001016128f0565b6001600160e01b031981168114610dbc57600080fd5b60006020828403121561292c57600080fd5b813561170381612904565b60005b8381101561295257818101518382015260200161293a565b838111156113bd5750506000910152565b6000815180845261297b816020860160208601612937565b601f01601f19169290920160200192915050565b6020815260006117036020830184612963565b6000602082840312156129b457600080fd5b5035919050565b80356001600160a01b03811681146129d257600080fd5b919050565b600080604083850312156129ea57600080fd5b6129f3836129bb565b946020939093013593505050565b600080600060608486031215612a1657600080fd5b612a1f846129bb565b9250612a2d602085016129bb565b9150604084013590509250925092565b803580151581146129d257600080fd5b600080600080600080600060e0888a031215612a6857600080fd5b612a7188612a3d565b9650612a7f60208901612a3d565b955060408801359450612a94606089016129bb565b9350612aa2608089016129bb565b9250612ab060a089016129bb565b9150612abe60c089016129bb565b905092959891949750929550565b600060208284031215612ade57600080fd5b611703826129bb565b6020808252825182820181905260009190848201906040850190845b81811015612b1f57835183529284019291840191600101612b03565b50909695505050505050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff80841115612b5c57612b5c612b2b565b604051601f8501601f19908116603f01168101908282118183101715612b8457612b84612b2b565b81604052809350858152868686011115612b9d57600080fd5b858560208301376000602087830101525050509392505050565b600060208284031215612bc957600080fd5b813567ffffffffffffffff811115612be057600080fd5b8201601f81018413612bf157600080fd5b611fb984823560208401612b41565b600082601f830112612c1157600080fd5b61170383833560208501612b41565b60008060408385031215612c3357600080fd5b82359150602083013567ffffffffffffffff811115612c5157600080fd5b612c5d85828601612c00565b9150509250929050565b60008060408385031215612c7a57600080fd5b612c83836129bb565b9150612c9160208401612a3d565b90509250929050565b60008060008060808587031215612cb057600080fd5b612cb9856129bb565b9350612cc7602086016129bb565b925060408501359150606085013567ffffffffffffffff811115612cea57600080fd5b612cf687828801612c00565b91505092959194509250565b60008060408385031215612d1557600080fd5b612d1e836129bb565b9150612c91602084016129bb565b600181811c90821680612d4057607f821691505b60208210811415612d6157634e487b7160e01b600052602260045260246000fd5b50919050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b634e487b7160e01b600052601160045260246000fd5b6000600019821415612dc657612dc6612d9c565b5060010190565b60008219821115612de057612de0612d9c565b500190565b634e487b7160e01b600052603260045260246000fd5b60208082526033908201527f455243373231413a207472616e7366657220746f206e6f6e204552433732315260408201527232b1b2b4bb32b91034b6b83632b6b2b73a32b960691b606082015260800190565b60008151612e60818560208601612937565b9290920192915050565b600080845481600182811c915080831680612e8657607f831692505b6020808410821415612ea657634e487b7160e01b86526022600452602486fd5b818015612eba5760018114612ecb57612ef8565b60ff19861689528489019650612ef8565b60008b81526020902060005b86811015612ef05781548b820152908501908301612ed7565b505084890196505b505050505050612f1c612f0b8286612e4e565b64173539b7b760d91b815260050190565b95945050505050565b60006001600160801b0383811690831681811015612f4557612f45612d9c565b039392505050565b60006001600160801b03808316818516808303821115612f6f57612f6f612d9c565b01949350505050565b6000816000190483118215151615612f9257612f92612d9c565b500290565b600082821015612fa957612fa9612d9c565b500390565b600081612fbd57612fbd612d9c565b506000190190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612ff890830184612963565b9695505050505050565b60006020828403121561301457600080fd5b815161170381612904565b634e487b7160e01b600052601260045260246000fd5b6000826130445761304461301f565b500490565b6000826130585761305861301f565b500690565b634e487b7160e01b600052602160045260246000fdfea2646970667358221220051321bb2d344c9847c474f13fcac5981c1430003448f02644d8a592ea81ada164736f6c634300080a0033

Deployed Bytecode Sourcemap

51913:5328:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37008:370;;;;;;;;;;-1:-1:-1;37008:370:0;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;37008:370:0;;;;;;;;38734:94;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;40259:204::-;;;;;;;;;;-1:-1:-1;40259:204:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1714:32:1;;;1696:51;;1684:2;1669:18;40259:204:0;1550:203:1;56172:118:0;;;;;;;;;;-1:-1:-1;56172:118:0;;;;;:::i;:::-;;:::i;:::-;;39822:379;;;;;;;;;;-1:-1:-1;39822:379:0;;;;;:::i;:::-;;:::i;52125:31::-;;;;;;;;;;;;;;;;;;;2341:25:1;;;2329:2;2314:18;52125:31:0;2195:177:1;35569:94:0;;;;;;;;;;-1:-1:-1;35645:12:0;;35569:94;;52243:29;;;;;;;;;;;;;;;;41109:142;;;;;;;;;;-1:-1:-1;41109:142:0;;;;;:::i;:::-;;:::i;52441:22::-;;;;;;;;;;-1:-1:-1;52441:22:0;;;;-1:-1:-1;;;;;52441:22:0;;;36200:744;;;;;;;;;;-1:-1:-1;36200:744:0;;;;;:::i;:::-;;:::i;56611:417::-;;;;;;;;;;-1:-1:-1;56611:417:0;;;;;:::i;:::-;;:::i;52279:30::-;;;;;;;;;;-1:-1:-1;52279:30:0;;;;;;;;52354:22;;;;;;;;;;-1:-1:-1;52354:22:0;;;;;;;-1:-1:-1;;;;;52354:22:0;;;55479:196;;;;;;;;;;-1:-1:-1;55479:196:0;;;;;:::i;:::-;;:::i;52383:22::-;;;;;;;;;;-1:-1:-1;52383:22:0;;;;-1:-1:-1;;;;;52383:22:0;;;57036:200;;;:::i;52412:22::-;;;;;;;;;;-1:-1:-1;52412:22:0;;;;-1:-1:-1;;;;;52412:22:0;;;41314:157;;;;;;;;;;-1:-1:-1;41314:157:0;;;;;:::i;:::-;;:::i;54257:357::-;;;;;;;;;;-1:-1:-1;54257:357:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;56082:82::-;;;;;;;;;;-1:-1:-1;56082:82:0;;;;;:::i;:::-;;:::i;35732:177::-;;;;;;;;;;-1:-1:-1;35732:177:0;;;;;:::i;:::-;;:::i;56298:106::-;;;;;;;;;;-1:-1:-1;56298:106:0;;;;;:::i;:::-;;:::i;38557:118::-;;;;;;;;;;-1:-1:-1;38557:118:0;;;;;:::i;:::-;;:::i;52038:80::-;;;;;;;;;;;;;:::i;55683:91::-;;;;;;;;;;-1:-1:-1;55683:91:0;;;;;:::i;:::-;;:::i;55882:92::-;;;;;;;;;;-1:-1:-1;55882:92:0;;;;;:::i;:::-;;:::i;53054:871::-;;;;;;:::i;:::-;;:::i;37434:211::-;;;;;;;;;;-1:-1:-1;37434:211:0;;;;;:::i;:::-;;:::i;51023:103::-;;;;;;;;;;;;;:::i;50372:87::-;;;;;;;;;;-1:-1:-1;50418:7:0;50445:6;-1:-1:-1;;;;;50445:6:0;50372:87;;38889:98;;;;;;;;;;;;;:::i;52658:328::-;;;;;;:::i;:::-;;:::i;40527:274::-;;;;;;;;;;-1:-1:-1;40527:274:0;;;;;:::i;:::-;;:::i;41534:311::-;;;;;;;;;;-1:-1:-1;41534:311:0;;;;;:::i;:::-;;:::i;52316:31::-;;;;;;;;;;-1:-1:-1;52316:31:0;;;;;;;;;;;54622:363;;;;;;;;;;-1:-1:-1;54622:363:0;;;;;:::i;:::-;;:::i;52163:29::-;;;;;;;;;;-1:-1:-1;52163:29:0;;;;;;;;;;;7143:6:1;7131:19;;;7113:38;;7101:2;7086:18;52163:29:0;6969:188:1;45949:43:0;;;;;;;;;;;;;;;;56510:93;;;;;;;;;;;;;:::i;56412:90::-;;;;;;;;;;;;;:::i;40864:186::-;;;;;;;;;;-1:-1:-1;40864:186:0;;;;;:::i;:::-;-1:-1:-1;;;;;41009:25:0;;;40986:4;41009:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;40864:186;51281:201;;;;;;;;;;-1:-1:-1;51281:201:0;;;;;:::i;:::-;;:::i;55982:92::-;;;;;;;;;;-1:-1:-1;55982:92:0;;;;;:::i;:::-;;:::i;55782:::-;;;;;;;;;;-1:-1:-1;55782:92:0;;;;;:::i;:::-;;:::i;37008:370::-;37135:4;-1:-1:-1;;;;;;37165:40:0;;-1:-1:-1;;;37165:40:0;;:99;;-1:-1:-1;;;;;;;37216:48:0;;-1:-1:-1;;;37216:48:0;37165:99;:160;;;-1:-1:-1;;;;;;;37275:50:0;;-1:-1:-1;;;37275:50:0;37165:160;:207;;;-1:-1:-1;;;;;;;;;;11108:40:0;;;37336:36;37151:221;37008:370;-1:-1:-1;;37008:370:0:o;38734:94::-;38788:13;38817:5;38810:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38734:94;:::o;40259:204::-;40327:7;40351:16;40359:7;42171:12;;-1:-1:-1;42161:22:0;42084:105;40351:16;40343:74;;;;-1:-1:-1;;;40343:74:0;;8014:2:1;40343:74:0;;;7996:21:1;8053:2;8033:18;;;8026:30;8092:34;8072:18;;;8065:62;-1:-1:-1;;;8143:18:1;;;8136:43;8196:19;;40343:74:0;;;;;;;;;-1:-1:-1;40433:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;40433:24:0;;40259:204::o;56172:118::-;50418:7;50445:6;-1:-1:-1;;;;;50445:6:0;33119:10;50592:23;50584:68;;;;-1:-1:-1;;;50584:68:0;;;;;;;:::i;:::-;56252:13:::1;:30:::0;56172:118::o;39822:379::-;39891:13;39907:24;39923:7;39907:15;:24::i;:::-;39891:40;;39952:5;-1:-1:-1;;;;;39946:11:0;:2;-1:-1:-1;;;;;39946:11:0;;;39938:58;;;;-1:-1:-1;;;39938:58:0;;8789:2:1;39938:58:0;;;8771:21:1;8828:2;8808:18;;;8801:30;8867:34;8847:18;;;8840:62;-1:-1:-1;;;8918:18:1;;;8911:32;8960:19;;39938:58:0;8587:398:1;39938:58:0;33119:10;-1:-1:-1;;;;;40021:21:0;;;;:62;;-1:-1:-1;40046:37:0;40063:5;33119:10;40864:186;:::i;40046:37::-;40005:153;;;;-1:-1:-1;;;40005:153:0;;9192:2:1;40005:153:0;;;9174:21:1;9231:2;9211:18;;;9204:30;9270:34;9250:18;;;9243:62;9341:27;9321:18;;;9314:55;9386:19;;40005:153:0;8990:421:1;40005:153:0;40167:28;40176:2;40180:7;40189:5;40167:8;:28::i;:::-;39884:317;39822:379;;:::o;41109:142::-;41217:28;41227:4;41233:2;41237:7;41217:9;:28::i;36200:744::-;36309:7;36344:16;36354:5;36344:9;:16::i;:::-;36336:5;:24;36328:71;;;;-1:-1:-1;;;36328:71:0;;9618:2:1;36328:71:0;;;9600:21:1;9657:2;9637:18;;;9630:30;9696:34;9676:18;;;9669:62;-1:-1:-1;;;9747:18:1;;;9740:32;9789:19;;36328:71:0;9416:398:1;36328:71:0;36406:22;36431:13;35645:12;;;35569:94;36431:13;36406:38;;36451:19;36481:25;36531:9;36526:350;36550:14;36546:1;:18;36526:350;;;36580:31;36614:14;;;:11;:14;;;;;;;;;36580:48;;;;;;;;;-1:-1:-1;;;;;36580:48:0;;;;;-1:-1:-1;;;36580:48:0;;;;;;;;;;;;36641:28;36637:89;;36702:14;;;-1:-1:-1;36637:89:0;36759:5;-1:-1:-1;;;;;36738:26:0;:17;-1:-1:-1;;;;;36738:26:0;;36734:135;;;36796:5;36781:11;:20;36777:59;;;-1:-1:-1;36823:1:0;-1:-1:-1;36816:8:0;;-1:-1:-1;;;36816:8:0;36777:59;36846:13;;;;:::i;:::-;;;;36734:135;-1:-1:-1;36566:3:0;;;;:::i;:::-;;;;36526:350;;;-1:-1:-1;36882:56:0;;-1:-1:-1;;;36882:56:0;;10293:2:1;36882:56:0;;;10275:21:1;10332:2;10312:18;;;10305:30;10371:34;10351:18;;;10344:62;-1:-1:-1;;;10422:18:1;;;10415:44;10476:19;;36882:56:0;10091:410:1;56611:417:0;50418:7;50445:6;-1:-1:-1;;;;;50445:6:0;33119:10;50592:23;50584:68;;;;-1:-1:-1;;;50584:68:0;;;;;;;:::i;:::-;56802:10:::1;:24:::0;;56874:13:::1;:30:::0;;;;-1:-1:-1;;56837:26:0;;;56802:24;::::1;;-1:-1:-1::0;;56837:26:0;;;;;56802:24:::1;56837:26:::0;::::1;;::::0;;;::::1;::::0;;;::::1;-1:-1:-1::0;;;;;;56915:18:0::1;::::0;-1:-1:-1;;;;;56915:18:0;;::::1;;;::::0;;;56944:7:::1;:18:::0;;-1:-1:-1;;;;;;56944:18:0;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;56973:7:::1;:18:::0;;;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;57002:7:::1;:18:::0;;;;::::1;::::0;;;::::1;::::0;;;::::1;::::0;;56611:417::o;55479:196::-;50418:7;50445:6;-1:-1:-1;;;;;50445:6:0;33119:10;50592:23;50584:68;;;;-1:-1:-1;;;50584:68:0;;;;;;;:::i;:::-;55585:9:::1;::::0;::::1;;55570:11:::0;55554:13:::1;35645:12:::0;;;35569:94;55554:13:::1;:27;;;;:::i;:::-;:40;;55546:92;;;::::0;-1:-1:-1;;;55546:92:0;;10841:2:1;55546:92:0::1;::::0;::::1;10823:21:1::0;10880:2;10860:18;;;10853:30;10919:34;10899:18;;;10892:62;-1:-1:-1;;;10970:18:1;;;10963:37;11017:19;;55546:92:0::1;10639:403:1::0;55546:92:0::1;55649:18;55655:11;55649:5;:18::i;:::-;55479:196:::0;:::o;57036:200::-;50418:7;50445:6;-1:-1:-1;;;;;50445:6:0;33119:10;50592:23;50584:68;;;;-1:-1:-1;;;50584:68:0;;;;;;;:::i;:::-;57112:59:::1;::::0;57095:12:::1;::::0;57120:10:::1;::::0;57145:21:::1;::::0;57095:12;57112:59;57095:12;57112:59;57145:21;57120:10;57112:59:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57094:77;;;57190:7;57182:46;;;::::0;-1:-1:-1;;;57182:46:0;;11459:2:1;57182:46:0::1;::::0;::::1;11441:21:1::0;11498:2;11478:18;;;11471:30;11537:28;11517:18;;;11510:56;11583:18;;57182:46:0::1;11257:350:1::0;41314:157:0;41426:39;41443:4;41449:2;41453:7;41426:39;;;;;;;;;;;;:16;:39::i;54257:357::-;54317:16;54345:23;54371:17;54381:6;54371:9;:17::i;:::-;54345:43;;54399:25;54441:15;54427:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;54427:30:0;;54399:58;;54473:9;54468:113;54488:15;54484:1;:19;54468:113;;;54539:30;54559:6;54567:1;54539:19;:30::i;:::-;54525:8;54534:1;54525:11;;;;;;;;:::i;:::-;;;;;;;;;;:44;54505:3;;;;:::i;:::-;;;;54468:113;;;-1:-1:-1;54598:8:0;54257:357;-1:-1:-1;;;54257:357:0:o;56082:82::-;50418:7;50445:6;-1:-1:-1;;;;;50445:6:0;33119:10;50592:23;50584:68;;;;-1:-1:-1;;;50584:68:0;;;;;;;:::i;:::-;56144:4:::1;:12:::0;56082:82::o;35732:177::-;35799:7;35831:13;35645:12;;;35569:94;35831:13;35823:5;:21;35815:69;;;;-1:-1:-1;;;35815:69:0;;11946:2:1;35815:69:0;;;11928:21:1;11985:2;11965:18;;;11958:30;12024:34;12004:18;;;11997:62;-1:-1:-1;;;12075:18:1;;;12068:33;12118:19;;35815:69:0;11744:399:1;35815:69:0;-1:-1:-1;35898:5:0;35732:177::o;56298:106::-;50418:7;50445:6;-1:-1:-1;;;;;50445:6:0;33119:10;50592:23;50584:68;;;;-1:-1:-1;;;50584:68:0;;;;;;;:::i;:::-;56375:21;;::::1;::::0;:7:::1;::::0;:21:::1;::::0;::::1;::::0;::::1;:::i;:::-;;56298:106:::0;:::o;38557:118::-;38621:7;38644:20;38656:7;38644:11;:20::i;:::-;:25;;38557:118;-1:-1:-1;;38557:118:0:o;52038:80::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;55683:91::-;50418:7;50445:6;-1:-1:-1;;;;;50445:6:0;33119:10;50592:23;50584:68;;;;-1:-1:-1;;;50584:68:0;;;;;;;:::i;:::-;55749:7:::1;:17:::0;;-1:-1:-1;;;;;55749:17:0;;::::1;::::0;::::1;-1:-1:-1::0;;;;;;55749:17:0;;::::1;::::0;;;::::1;::::0;;55683:91::o;55882:92::-;50418:7;50445:6;-1:-1:-1;;;;;50445:6:0;33119:10;50592:23;50584:68;;;;-1:-1:-1;;;50584:68:0;;;;;;;:::i;:::-;55949:7:::1;:17:::0;;-1:-1:-1;;;;;;55949:17:0::1;-1:-1:-1::0;;;;;55949:17:0;;;::::1;::::0;;;::::1;::::0;;55882:92::o;53054:871::-;53157:11;;;;;;;53149:61;;;;-1:-1:-1;;;53149:61:0;;12350:2:1;53149:61:0;;;12332:21:1;12389:2;12369:18;;;12362:30;12428:34;12408:18;;;12401:62;-1:-1:-1;;;12479:18:1;;;12472:35;12524:19;;53149:61:0;12148:401:1;53149:61:0;53221:11;53247:15;53265:43;53286:10;53298:9;53265:20;:43::i;:::-;53334:7;;53247:61;;-1:-1:-1;;;;;;53323:18:0;;;53334:7;;;;;53323:18;53319:255;;;53366:1;53358:9;;53319:255;;;53399:7;;-1:-1:-1;;;;;53388:18:0;;;53399:7;;53388:18;53384:190;;;53431:1;53423:9;;53384:190;;;53464:7;;-1:-1:-1;;;;;53453:18:0;;;53464:7;;53453:18;53449:125;;;53496:1;53488:9;;53449:125;;;53529:7;;-1:-1:-1;;;;;53518:18:0;;;53529:7;;53518:18;53514:60;;;53561:1;53553:9;;53514:60;53602:1;53594:5;:9;;;:23;;;;;53616:1;53607:5;:10;;;;53594:23;53586:68;;;;-1:-1:-1;;;53586:68:0;;12756:2:1;53586:68:0;;;12738:21:1;;;12775:18;;;12768:30;12834:34;12814:18;;;12807:62;12886:18;;53586:68:0;12554:356:1;53586:68:0;53704:16;;;;;;;;53689:11;53673:13;35645:12;;;35569:94;53673:13;:27;;;;:::i;:::-;:47;;53665:108;;;;-1:-1:-1;;;53665:108:0;;13117:2:1;53665:108:0;;;13099:21:1;13156:2;13136:18;;;13129:30;13195:34;13175:18;;;13168:62;-1:-1:-1;;;13246:18:1;;;13239:46;13302:19;;53665:108:0;12915:412:1;53665:108:0;53831:5;53792:44;;53816:11;53792:21;53802:10;53792:9;:21::i;:::-;:35;;;;:::i;:::-;:44;;53784:104;;;;-1:-1:-1;;;53784:104:0;;13534:2:1;53784:104:0;;;13516:21:1;13573:2;13553:18;;;13546:30;13612:34;13592:18;;;13585:62;-1:-1:-1;;;13663:18:1;;;13656:45;13718:19;;53784:104:0;13332:411:1;53784:104:0;53899:18;53905:11;53899:5;:18::i;:::-;53138:787;;53054:871;;:::o;37434:211::-;37498:7;-1:-1:-1;;;;;37522:19:0;;37514:75;;;;-1:-1:-1;;;37514:75:0;;13950:2:1;37514:75:0;;;13932:21:1;13989:2;13969:18;;;13962:30;14028:34;14008:18;;;14001:62;-1:-1:-1;;;14079:18:1;;;14072:41;14130:19;;37514:75:0;13748:407:1;37514:75:0;-1:-1:-1;;;;;;37611:19:0;;;;;:12;:19;;;;;:27;-1:-1:-1;;;;;37611:27:0;;37434:211::o;51023:103::-;50418:7;50445:6;-1:-1:-1;;;;;50445:6:0;33119:10;50592:23;50584:68;;;;-1:-1:-1;;;50584:68:0;;;;;;;:::i;:::-;51088:30:::1;51115:1;51088:18;:30::i;:::-;51023:103::o:0;38889:98::-;38945:13;38974:7;38967:14;;;;;:::i;52658:328::-;52726:10;;;;52718:48;;;;-1:-1:-1;;;52718:48:0;;14362:2:1;52718:48:0;;;14344:21:1;14401:2;14381:18;;;14374:30;14440:27;14420:18;;;14413:55;14485:18;;52718:48:0;14160:349:1;52718:48:0;52800:13;;52785:11;:28;;52777:69;;;;-1:-1:-1;;;52777:69:0;;14716:2:1;52777:69:0;;;14698:21:1;14755:2;14735:18;;;14728:30;14794;14774:18;;;14767:58;14842:18;;52777:69:0;14514:352:1;40527:274:0;-1:-1:-1;;;;;40618:24:0;;33119:10;40618:24;;40610:63;;;;-1:-1:-1;;;40610:63:0;;15073:2:1;40610:63:0;;;15055:21:1;15112:2;15092:18;;;15085:30;15151:28;15131:18;;;15124:56;15197:18;;40610:63:0;14871:350:1;40610:63:0;33119:10;40682:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;40682:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;40682:53:0;;;;;;;;;;40747:48;;540:41:1;;;40682:42:0;;33119:10;40747:48;;513:18:1;40747:48:0;;;;;;;40527:274;;:::o;41534:311::-;41671:28;41681:4;41687:2;41691:7;41671:9;:28::i;:::-;41722:48;41745:4;41751:2;41755:7;41764:5;41722:22;:48::i;:::-;41706:133;;;;-1:-1:-1;;;41706:133:0;;;;;;;:::i;54622:363::-;54695:13;54730:16;54738:7;42171:12;;-1:-1:-1;42161:22:0;42084:105;54730:16;54722:83;;;;-1:-1:-1;;;54722:83:0;;15848:2:1;54722:83:0;;;15830:21:1;15887:2;15867:18;;;15860:30;15926:34;15906:18;;;15899:62;-1:-1:-1;;;15977:18:1;;;15970:52;16039:19;;54722:83:0;15646:418:1;54722:83:0;54816:28;54847:10;:8;:10::i;:::-;54816:41;;54906:1;54881:14;54875:28;:32;:102;;;;;;;;;;;;;;;;;54934:7;54943:18;:7;:16;:18::i;:::-;54917:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;54875:102;54868:109;54622:363;-1:-1:-1;;;54622:363:0:o;56510:93::-;50418:7;50445:6;-1:-1:-1;;;;;50445:6:0;33119:10;50592:23;50584:68;;;;-1:-1:-1;;;50584:68:0;;;;;;;:::i;:::-;56584:11:::1;::::0;;-1:-1:-1;;56569:26:0;::::1;56584:11;::::0;;;::::1;;;56583:12;56569:26:::0;;::::1;;::::0;;56510:93::o;56412:90::-;50418:7;50445:6;-1:-1:-1;;;;;50445:6:0;33119:10;50592:23;50584:68;;;;-1:-1:-1;;;50584:68:0;;;;;;;:::i;:::-;56484:10:::1;::::0;;-1:-1:-1;;56470:24:0;::::1;56484:10;::::0;;::::1;56483:11;56470:24;::::0;;56412:90::o;51281:201::-;50418:7;50445:6;-1:-1:-1;;;;;50445:6:0;33119:10;50592:23;50584:68;;;;-1:-1:-1;;;50584:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;51370:22:0;::::1;51362:73;;;::::0;-1:-1:-1;;;51362:73:0;;18011:2:1;51362:73:0::1;::::0;::::1;17993:21:1::0;18050:2;18030:18;;;18023:30;18089:34;18069:18;;;18062:62;-1:-1:-1;;;18140:18:1;;;18133:36;18186:19;;51362:73:0::1;17809:402:1::0;51362:73:0::1;51446:28;51465:8;51446:18;:28::i;55982:92::-:0;50418:7;50445:6;-1:-1:-1;;;;;50445:6:0;33119:10;50592:23;50584:68;;;;-1:-1:-1;;;50584:68:0;;;;;;;:::i;:::-;56049:7:::1;:17:::0;;-1:-1:-1;;;;;;56049:17:0::1;-1:-1:-1::0;;;;;56049:17:0;;;::::1;::::0;;;::::1;::::0;;55982:92::o;55782:::-;50418:7;50445:6;-1:-1:-1;;;;;50445:6:0;33119:10;50592:23;50584:68;;;;-1:-1:-1;;;50584:68:0;;;;;;;:::i;:::-;55849:7:::1;:17:::0;;-1:-1:-1;;;;;;55849:17:0::1;-1:-1:-1::0;;;;;55849:17:0;;;::::1;::::0;;;::::1;::::0;;55782:92::o;45771:172::-;45868:24;;;;:15;:24;;;;;;:29;;-1:-1:-1;;;;;;45868:29:0;-1:-1:-1;;;;;45868:29:0;;;;;;;;;45909:28;;45868:24;;45909:28;;;;;;;45771:172;;;:::o;44136:1529::-;44233:35;44271:20;44283:7;44271:11;:20::i;:::-;44342:18;;44233:58;;-1:-1:-1;44300:22:0;;-1:-1:-1;;;;;44326:34:0;33119:10;-1:-1:-1;;;;;44326:34:0;;:81;;;-1:-1:-1;33119:10:0;44371:20;44383:7;44371:11;:20::i;:::-;-1:-1:-1;;;;;44371:36:0;;44326:81;:142;;;-1:-1:-1;44435:18:0;;44418:50;;33119:10;40864:186;:::i;44418:50::-;44300:169;;44494:17;44478:101;;;;-1:-1:-1;;;44478:101:0;;18418:2:1;44478:101:0;;;18400:21:1;18457:2;18437:18;;;18430:30;18496:34;18476:18;;;18469:62;-1:-1:-1;;;18547:18:1;;;18540:48;18605:19;;44478:101:0;18216:414:1;44478:101:0;44626:4;-1:-1:-1;;;;;44604:26:0;:13;:18;;;-1:-1:-1;;;;;44604:26:0;;44588:98;;;;-1:-1:-1;;;44588:98:0;;18837:2:1;44588:98:0;;;18819:21:1;18876:2;18856:18;;;18849:30;18915:34;18895:18;;;18888:62;-1:-1:-1;;;18966:18:1;;;18959:36;19012:19;;44588:98:0;18635:402:1;44588:98:0;-1:-1:-1;;;;;44701:16:0;;44693:66;;;;-1:-1:-1;;;44693:66:0;;19244:2:1;44693:66:0;;;19226:21:1;19283:2;19263:18;;;19256:30;19322:34;19302:18;;;19295:62;-1:-1:-1;;;19373:18:1;;;19366:35;19418:19;;44693:66:0;19042:401:1;44693:66:0;44868:49;44885:1;44889:7;44898:13;:18;;;44868:8;:49::i;:::-;-1:-1:-1;;;;;44926:18:0;;;;;;:12;:18;;;;;:31;;44956:1;;44926:18;:31;;44956:1;;-1:-1:-1;;;;;44926:31:0;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;44926:31:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;44964:16:0;;-1:-1:-1;44964:16:0;;;:12;:16;;;;;:29;;-1:-1:-1;;;44964:16:0;;:29;;-1:-1:-1;;44964:29:0;;:::i;:::-;;;-1:-1:-1;;;;;44964:29:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;45023:43:0;;;;;;;;-1:-1:-1;;;;;45023:43:0;;;;;;45049:15;45023:43;;;;;;;;;-1:-1:-1;45000:20:0;;;:11;:20;;;;;;:66;;;;;;;;;-1:-1:-1;;;45000:66:0;-1:-1:-1;;;;;;45000:66:0;;;;;;;;;;;45316:11;45012:7;-1:-1:-1;45316:11:0;:::i;:::-;45379:1;45338:24;;;:11;:24;;;;;:29;45294:33;;-1:-1:-1;;;;;;45338:29:0;45334:236;;45396:20;45404:11;42171:12;;-1:-1:-1;42161:22:0;42084:105;45396:20;45392:171;;;45456:97;;;;;;;;45483:18;;-1:-1:-1;;;;;45456:97:0;;;;;;45514:28;;;;45456:97;;;;;;;;;;-1:-1:-1;45429:24:0;;;:11;:24;;;;;;;:124;;;;;;;;;-1:-1:-1;;;45429:124:0;-1:-1:-1;;;;;;45429:124:0;;;;;;;;;;;;45392:171;45602:7;45598:2;-1:-1:-1;;;;;45583:27:0;45592:4;-1:-1:-1;;;;;45583:27:0;;;;;;;;;;;45617:42;44226:1439;;;44136:1529;;;:::o;53933:316::-;54007:1;53993:11;:15;53985:55;;;;-1:-1:-1;;;53985:55:0;;20159:2:1;53985:55:0;;;20141:21:1;20198:2;20178:18;;;20171:30;20237:29;20217:18;;;20210:57;20284:18;;53985:55:0;19957:351:1;53985:55:0;50418:7;50445:6;-1:-1:-1;;;;;50445:6:0;54055:10;:21;54051:146;;54121:11;54114:4;;:18;;;;:::i;:::-;54101:9;:31;;54093:92;;;;-1:-1:-1;;;54093:92:0;;20688:2:1;54093:92:0;;;20670:21:1;20727:2;20707:18;;;20700:30;20766:34;20746:18;;;20739:62;-1:-1:-1;;;20817:18:1;;;20810:46;20873:19;;54093:92:0;20486:412:1;54093:92:0;54207:34;54217:10;54229:11;54207:9;:34::i;37897:606::-;-1:-1:-1;;;;;;;;;;;;;;;;;38014:16:0;38022:7;42171:12;;-1:-1:-1;42161:22:0;42084:105;38014:16;38006:71;;;;-1:-1:-1;;;38006:71:0;;21105:2:1;38006:71:0;;;21087:21:1;21144:2;21124:18;;;21117:30;21183:34;21163:18;;;21156:62;-1:-1:-1;;;21234:18:1;;;21227:40;21284:19;;38006:71:0;20903:406:1;38006:71:0;38086:26;38134:12;38123:7;:23;38119:93;;38178:22;38188:12;38178:7;:22;:::i;:::-;:26;;38203:1;38178:26;:::i;:::-;38157:47;;38119:93;38240:7;38220:212;38257:18;38249:4;:26;38220:212;;38294:31;38328:17;;;:11;:17;;;;;;;;;38294:51;;;;;;;;;-1:-1:-1;;;;;38294:51:0;;;;;-1:-1:-1;;;38294:51:0;;;;;;;;;;;;38358:28;38354:71;;38406:9;37897:606;-1:-1:-1;;;;37897:606:0:o;38354:71::-;-1:-1:-1;38277:6:0;;;;:::i;:::-;;;;38220:212;;;-1:-1:-1;38440:57:0;;-1:-1:-1;;;38440:57:0;;21787:2:1;38440:57:0;;;21769:21:1;21826:2;21806:18;;;21799:30;21865:34;21845:18;;;21838:62;-1:-1:-1;;;21916:18:1;;;21909:45;21971:19;;38440:57:0;21585:411:1;55245:199:0;55113:24;;;-1:-1:-1;;23283:2:1;23279:15;;;23275:53;55113:24:0;;;;23263:66:1;;;;55113:24:0;;;;;;;;;23345:12:1;;;55113:24:0;;55103:35;;;;;;23610:66:1;55166:62:0;;;23598:79:1;23693:12;;;;23686:28;;;;55166:62:0;;;;;;;;;;23730:12:1;;;;55166:62:0;;;55156:73;;;;;55337:7;;55413:23;55357:38;55426:9;55413:12;:23::i;:::-;55406:30;55245:199;-1:-1:-1;;;;55245:199:0:o;51642:191::-;51716:16;51735:6;;-1:-1:-1;;;;;51752:17:0;;;-1:-1:-1;;;;;;51752:17:0;;;;;;51785:40;;51735:6;;;;;;;51785:40;;51716:16;51785:40;51705:128;51642:191;:::o;47486:690::-;47623:4;-1:-1:-1;;;;;47640:13:0;;1178:20;1226:8;47636:535;;47679:72;;-1:-1:-1;;;47679:72:0;;-1:-1:-1;;;;;47679:36:0;;;;;:72;;33119:10;;47730:4;;47736:7;;47745:5;;47679:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;47679:72:0;;;;;;;;-1:-1:-1;;47679:72:0;;;;;;;;;;;;:::i;:::-;;;47666:464;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;47910:13:0;;47906:215;;47943:61;;-1:-1:-1;;;47943:61:0;;;;;;;:::i;47906:215::-;48089:6;48083:13;48074:6;48070:2;48066:15;48059:38;47666:464;-1:-1:-1;;;;;;47801:55:0;-1:-1:-1;;;47801:55:0;;-1:-1:-1;47794:62:0;;47636:535;-1:-1:-1;48159:4:0;47486:690;;;;;;:::o;52543:107::-;52603:13;52635:7;52628:14;;;;;:::i;21035:723::-;21091:13;21312:10;21308:53;;-1:-1:-1;;21339:10:0;;;;;;;;;;;;-1:-1:-1;;;21339:10:0;;;;;21035:723::o;21308:53::-;21386:5;21371:12;21427:78;21434:9;;21427:78;;21460:8;;;;:::i;:::-;;-1:-1:-1;21483:10:0;;-1:-1:-1;21491:2:0;21483:10;;:::i;:::-;;;21427:78;;;21515:19;21547:6;21537:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21537:17:0;;21515:39;;21565:154;21572:10;;21565:154;;21599:11;21609:1;21599:11;;:::i;:::-;;-1:-1:-1;21668:10:0;21676:2;21668:5;:10;:::i;:::-;21655:24;;:2;:24;:::i;:::-;21642:39;;21625:6;21632;21625:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;21625:56:0;;;;;;;;-1:-1:-1;21696:11:0;21705:2;21696:11;;:::i;:::-;;;21565:154;;42195:98;42260:27;42270:2;42274:8;42260:27;;;;;;;;;;;;:9;:27::i;27196:231::-;27274:7;27295:17;27314:18;27336:27;27347:4;27353:9;27336:10;:27::i;:::-;27294:69;;;;27374:18;27386:5;27374:11;:18::i;42632:1272::-;42760:12;;-1:-1:-1;;;;;42787:16:0;;42779:62;;;;-1:-1:-1;;;42779:62:0;;23955:2:1;42779:62:0;;;23937:21:1;23994:2;23974:18;;;23967:30;24033:34;24013:18;;;24006:62;-1:-1:-1;;;24084:18:1;;;24077:31;24125:19;;42779:62:0;23753:397:1;42779:62:0;42978:21;42986:12;42171;;-1:-1:-1;42161:22:0;42084:105;42978:21;42977:22;42969:64;;;;-1:-1:-1;;;42969:64:0;;24357:2:1;42969:64:0;;;24339:21:1;24396:2;24376:18;;;24369:30;24435:31;24415:18;;;24408:59;24484:18;;42969:64:0;24155:353:1;42969:64:0;43060:12;43048:8;:24;;43040:71;;;;-1:-1:-1;;;43040:71:0;;24715:2:1;43040:71:0;;;24697:21:1;24754:2;24734:18;;;24727:30;24793:34;24773:18;;;24766:62;-1:-1:-1;;;24844:18:1;;;24837:32;24886:19;;43040:71:0;24513:398:1;43040:71:0;-1:-1:-1;;;;;43223:16:0;;43190:30;43223:16;;;:12;:16;;;;;;;;;43190:49;;;;;;;;;-1:-1:-1;;;;;43190:49:0;;;;;-1:-1:-1;;;43190:49:0;;;;;;;;;;;43265:119;;;;;;;;43285:19;;43190:49;;43265:119;;;43285:39;;43315:8;;43285:39;:::i;:::-;-1:-1:-1;;;;;43265:119:0;;;;;43368:8;43333:11;:24;;;:44;;;;:::i;:::-;-1:-1:-1;;;;;43265:119:0;;;;;;-1:-1:-1;;;;;43246:16:0;;;;;;;:12;:16;;;;;;;;:138;;;;;;;;-1:-1:-1;;;43246:138:0;;;;;;;;;;;;43419:43;;;;;;;;;;;43445:15;43419:43;;;;;;;;43391:25;;;:11;:25;;;;;;:71;;;;;;;;;-1:-1:-1;;;43391:71:0;-1:-1:-1;;;;;;43391:71:0;;;;;;;;;;;;;;;;;;43403:12;;43515:281;43539:8;43535:1;:12;43515:281;;;43568:38;;43593:12;;-1:-1:-1;;;;;43568:38:0;;;43585:1;;43568:38;;43585:1;;43568:38;43633:59;43664:1;43668:2;43672:12;43686:5;43633:22;:59::i;:::-;43615:150;;;;-1:-1:-1;;;43615:150:0;;;;;;;:::i;:::-;43774:14;;;;:::i;:::-;;;;43549:3;;;;;:::i;:::-;;;;43515:281;;;-1:-1:-1;43804:12:0;:27;;;43838:60;53054:871;25086:1308;25167:7;25176:12;25401:9;:16;25421:2;25401:22;25397:990;;;25697:4;25682:20;;25676:27;25747:4;25732:20;;25726:27;25805:4;25790:20;;25784:27;25440:9;25776:36;25848:25;25859:4;25776:36;25676:27;25726;25848:10;:25::i;:::-;25841:32;;;;;;;;;25397:990;25895:9;:16;25915:2;25895:22;25891:496;;;26170:4;26155:20;;26149:27;26221:4;26206:20;;26200:27;26263:23;26274:4;26149:27;26200;26263:10;:23::i;:::-;26256:30;;;;;;;;25891:496;-1:-1:-1;26335:1:0;;-1:-1:-1;26339:35:0;25891:496;25086:1308;;;;;:::o;23357:643::-;23435:20;23426:5;:29;;;;;;;;:::i;:::-;;23422:571;;;23357:643;:::o;23422:571::-;23533:29;23524:5;:38;;;;;;;;:::i;:::-;;23520:473;;;23579:34;;-1:-1:-1;;;23579:34:0;;25250:2:1;23579:34:0;;;25232:21:1;25289:2;25269:18;;;25262:30;25328:26;25308:18;;;25301:54;25372:18;;23579:34:0;25048:348:1;23520:473:0;23644:35;23635:5;:44;;;;;;;;:::i;:::-;;23631:362;;;23696:41;;-1:-1:-1;;;23696:41:0;;25603:2:1;23696:41:0;;;25585:21:1;25642:2;25622:18;;;25615:30;25681:33;25661:18;;;25654:61;25732:18;;23696:41:0;25401:355:1;23631:362:0;23768:30;23759:5;:39;;;;;;;;:::i;:::-;;23755:238;;;23815:44;;-1:-1:-1;;;23815:44:0;;25963:2:1;23815:44:0;;;25945:21:1;26002:2;25982:18;;;25975:30;26041:34;26021:18;;;26014:62;-1:-1:-1;;;26092:18:1;;;26085:32;26134:19;;23815:44:0;25761:398:1;23755:238:0;23890:30;23881:5;:39;;;;;;;;:::i;:::-;;23877:116;;;23937:44;;-1:-1:-1;;;23937:44:0;;26366:2:1;23937:44:0;;;26348:21:1;26405:2;26385:18;;;26378:30;26444:34;26424:18;;;26417:62;-1:-1:-1;;;26495:18:1;;;26488:32;26537:19;;23937:44:0;26164:398:1;28695:1632:0;28826:7;;29760:66;29747:79;;29743:163;;;-1:-1:-1;29859:1:0;;-1:-1:-1;29863:30:0;29843:51;;29743:163;29920:1;:7;;29925:2;29920:7;;:18;;;;;29931:1;:7;;29936:2;29931:7;;29920:18;29916:102;;;-1:-1:-1;29971:1:0;;-1:-1:-1;29975:30:0;29955:51;;29916:102;30132:24;;;30115:14;30132:24;;;;;;;;;26794:25:1;;;26867:4;26855:17;;26835:18;;;26828:45;;;;26889:18;;;26882:34;;;26932:18;;;26925:34;;;30132:24:0;;26766:19:1;;30132:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;30132:24:0;;-1:-1:-1;;30132:24:0;;;-1:-1:-1;;;;;;;30171:20:0;;30167:103;;30224:1;30228:29;30208:50;;;;;;;30167:103;30290:6;-1:-1:-1;30298:20:0;;-1:-1:-1;28695:1632:0;;;;;;;;:::o;27690:391::-;27804:7;;-1:-1:-1;;;;;27905:75:0;;28007:3;28003:12;;;28017:2;27999:21;28048:25;28059:4;27999:21;28068:1;27905:75;28048:10;:25::i;:::-;28041:32;;;;;;27690:391;;;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:131:1;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:258::-;664:1;674:113;688:6;685:1;682:13;674:113;;;764:11;;;758:18;745:11;;;738:39;710:2;703:10;674:113;;;805:6;802:1;799:13;796:48;;;-1:-1:-1;;840:1:1;822:16;;815:27;592:258::o;855:269::-;908:3;946:5;940:12;973:6;968:3;961:19;989:63;1045:6;1038:4;1033:3;1029:14;1022:4;1015:5;1011:16;989:63;:::i;:::-;1106:2;1085:15;-1:-1:-1;;1081:29:1;1072:39;;;;1113:4;1068:50;;855:269;-1:-1:-1;;855:269:1:o;1129:231::-;1278:2;1267:9;1260:21;1241:4;1298:56;1350:2;1339:9;1335:18;1327:6;1298:56;:::i;1365:180::-;1424:6;1477:2;1465:9;1456:7;1452:23;1448:32;1445:52;;;1493:1;1490;1483:12;1445:52;-1:-1:-1;1516:23:1;;1365:180;-1:-1:-1;1365:180:1:o;1758:173::-;1826:20;;-1:-1:-1;;;;;1875:31:1;;1865:42;;1855:70;;1921:1;1918;1911:12;1855:70;1758:173;;;:::o;1936:254::-;2004:6;2012;2065:2;2053:9;2044:7;2040:23;2036:32;2033:52;;;2081:1;2078;2071:12;2033:52;2104:29;2123:9;2104:29;:::i;:::-;2094:39;2180:2;2165:18;;;;2152:32;;-1:-1:-1;;;1936:254:1:o;2377:328::-;2454:6;2462;2470;2523:2;2511:9;2502:7;2498:23;2494:32;2491:52;;;2539:1;2536;2529:12;2491:52;2562:29;2581:9;2562:29;:::i;:::-;2552:39;;2610:38;2644:2;2633:9;2629:18;2610:38;:::i;:::-;2600:48;;2695:2;2684:9;2680:18;2667:32;2657:42;;2377:328;;;;;:::o;2710:160::-;2775:20;;2831:13;;2824:21;2814:32;;2804:60;;2860:1;2857;2850:12;2875:616;2982:6;2990;2998;3006;3014;3022;3030;3083:3;3071:9;3062:7;3058:23;3054:33;3051:53;;;3100:1;3097;3090:12;3051:53;3123:26;3139:9;3123:26;:::i;:::-;3113:36;;3168:35;3199:2;3188:9;3184:18;3168:35;:::i;:::-;3158:45;;3250:2;3239:9;3235:18;3222:32;3212:42;;3273:38;3307:2;3296:9;3292:18;3273:38;:::i;:::-;3263:48;;3330:39;3364:3;3353:9;3349:19;3330:39;:::i;:::-;3320:49;;3388:39;3422:3;3411:9;3407:19;3388:39;:::i;:::-;3378:49;;3446:39;3480:3;3469:9;3465:19;3446:39;:::i;:::-;3436:49;;2875:616;;;;;;;;;;:::o;3496:186::-;3555:6;3608:2;3596:9;3587:7;3583:23;3579:32;3576:52;;;3624:1;3621;3614:12;3576:52;3647:29;3666:9;3647:29;:::i;3687:632::-;3858:2;3910:21;;;3980:13;;3883:18;;;4002:22;;;3829:4;;3858:2;4081:15;;;;4055:2;4040:18;;;3829:4;4124:169;4138:6;4135:1;4132:13;4124:169;;;4199:13;;4187:26;;4268:15;;;;4233:12;;;;4160:1;4153:9;4124:169;;;-1:-1:-1;4310:3:1;;3687:632;-1:-1:-1;;;;;;3687:632:1:o;4324:127::-;4385:10;4380:3;4376:20;4373:1;4366:31;4416:4;4413:1;4406:15;4440:4;4437:1;4430:15;4456:632;4521:5;4551:18;4592:2;4584:6;4581:14;4578:40;;;4598:18;;:::i;:::-;4673:2;4667:9;4641:2;4727:15;;-1:-1:-1;;4723:24:1;;;4749:2;4719:33;4715:42;4703:55;;;4773:18;;;4793:22;;;4770:46;4767:72;;;4819:18;;:::i;:::-;4859:10;4855:2;4848:22;4888:6;4879:15;;4918:6;4910;4903:22;4958:3;4949:6;4944:3;4940:16;4937:25;4934:45;;;4975:1;4972;4965:12;4934:45;5025:6;5020:3;5013:4;5005:6;5001:17;4988:44;5080:1;5073:4;5064:6;5056;5052:19;5048:30;5041:41;;;;4456:632;;;;;:::o;5093:451::-;5162:6;5215:2;5203:9;5194:7;5190:23;5186:32;5183:52;;;5231:1;5228;5221:12;5183:52;5271:9;5258:23;5304:18;5296:6;5293:30;5290:50;;;5336:1;5333;5326:12;5290:50;5359:22;;5412:4;5404:13;;5400:27;-1:-1:-1;5390:55:1;;5441:1;5438;5431:12;5390:55;5464:74;5530:7;5525:2;5512:16;5507:2;5503;5499:11;5464:74;:::i;5549:221::-;5591:5;5644:3;5637:4;5629:6;5625:17;5621:27;5611:55;;5662:1;5659;5652:12;5611:55;5684:80;5760:3;5751:6;5738:20;5731:4;5723:6;5719:17;5684:80;:::i;5775:388::-;5852:6;5860;5913:2;5901:9;5892:7;5888:23;5884:32;5881:52;;;5929:1;5926;5919:12;5881:52;5965:9;5952:23;5942:33;;6026:2;6015:9;6011:18;5998:32;6053:18;6045:6;6042:30;6039:50;;;6085:1;6082;6075:12;6039:50;6108:49;6149:7;6140:6;6129:9;6125:22;6108:49;:::i;:::-;6098:59;;;5775:388;;;;;:::o;6168:254::-;6233:6;6241;6294:2;6282:9;6273:7;6269:23;6265:32;6262:52;;;6310:1;6307;6300:12;6262:52;6333:29;6352:9;6333:29;:::i;:::-;6323:39;;6381:35;6412:2;6401:9;6397:18;6381:35;:::i;:::-;6371:45;;6168:254;;;;;:::o;6427:537::-;6522:6;6530;6538;6546;6599:3;6587:9;6578:7;6574:23;6570:33;6567:53;;;6616:1;6613;6606:12;6567:53;6639:29;6658:9;6639:29;:::i;:::-;6629:39;;6687:38;6721:2;6710:9;6706:18;6687:38;:::i;:::-;6677:48;;6772:2;6761:9;6757:18;6744:32;6734:42;;6827:2;6816:9;6812:18;6799:32;6854:18;6846:6;6843:30;6840:50;;;6886:1;6883;6876:12;6840:50;6909:49;6950:7;6941:6;6930:9;6926:22;6909:49;:::i;:::-;6899:59;;;6427:537;;;;;;;:::o;7162:260::-;7230:6;7238;7291:2;7279:9;7270:7;7266:23;7262:32;7259:52;;;7307:1;7304;7297:12;7259:52;7330:29;7349:9;7330:29;:::i;:::-;7320:39;;7378:38;7412:2;7401:9;7397:18;7378:38;:::i;7427:380::-;7506:1;7502:12;;;;7549;;;7570:61;;7624:4;7616:6;7612:17;7602:27;;7570:61;7677:2;7669:6;7666:14;7646:18;7643:38;7640:161;;;7723:10;7718:3;7714:20;7711:1;7704:31;7758:4;7755:1;7748:15;7786:4;7783:1;7776:15;7640:161;;7427:380;;;:::o;8226:356::-;8428:2;8410:21;;;8447:18;;;8440:30;8506:34;8501:2;8486:18;;8479:62;8573:2;8558:18;;8226:356::o;9819:127::-;9880:10;9875:3;9871:20;9868:1;9861:31;9911:4;9908:1;9901:15;9935:4;9932:1;9925:15;9951:135;9990:3;-1:-1:-1;;10011:17:1;;10008:43;;;10031:18;;:::i;:::-;-1:-1:-1;10078:1:1;10067:13;;9951:135::o;10506:128::-;10546:3;10577:1;10573:6;10570:1;10567:13;10564:39;;;10583:18;;:::i;:::-;-1:-1:-1;10619:9:1;;10506:128::o;11612:127::-;11673:10;11668:3;11664:20;11661:1;11654:31;11704:4;11701:1;11694:15;11728:4;11725:1;11718:15;15226:415;15428:2;15410:21;;;15467:2;15447:18;;;15440:30;15506:34;15501:2;15486:18;;15479:62;-1:-1:-1;;;15572:2:1;15557:18;;15550:49;15631:3;15616:19;;15226:415::o;16195:185::-;16237:3;16275:5;16269:12;16290:52;16335:6;16330:3;16323:4;16316:5;16312:16;16290:52;:::i;:::-;16358:16;;;;;16195:185;-1:-1:-1;;16195:185:1:o;16503:1301::-;16780:3;16809:1;16842:6;16836:13;16872:3;16894:1;16922:9;16918:2;16914:18;16904:28;;16982:2;16971:9;16967:18;17004;16994:61;;17048:4;17040:6;17036:17;17026:27;;16994:61;17074:2;17122;17114:6;17111:14;17091:18;17088:38;17085:165;;;-1:-1:-1;;;17149:33:1;;17205:4;17202:1;17195:15;17235:4;17156:3;17223:17;17085:165;17266:18;17293:104;;;;17411:1;17406:320;;;;17259:467;;17293:104;-1:-1:-1;;17326:24:1;;17314:37;;17371:16;;;;-1:-1:-1;17293:104:1;;17406:320;16142:1;16135:14;;;16179:4;16166:18;;17501:1;17515:165;17529:6;17526:1;17523:13;17515:165;;;17607:14;;17594:11;;;17587:35;17650:16;;;;17544:10;;17515:165;;;17519:3;;17709:6;17704:3;17700:16;17693:23;;17259:467;;;;;;;17742:56;17767:30;17793:3;17785:6;17767:30;:::i;:::-;-1:-1:-1;;;16445:20:1;;16490:1;16481:11;;16385:113;17742:56;17735:63;16503:1301;-1:-1:-1;;;;;16503:1301:1:o;19448:246::-;19488:4;-1:-1:-1;;;;;19601:10:1;;;;19571;;19623:12;;;19620:38;;;19638:18;;:::i;:::-;19675:13;;19448:246;-1:-1:-1;;;19448:246:1:o;19699:253::-;19739:3;-1:-1:-1;;;;;19828:2:1;19825:1;19821:10;19858:2;19855:1;19851:10;19889:3;19885:2;19881:12;19876:3;19873:21;19870:47;;;19897:18;;:::i;:::-;19933:13;;19699:253;-1:-1:-1;;;;19699:253:1:o;20313:168::-;20353:7;20419:1;20415;20411:6;20407:14;20404:1;20401:21;20396:1;20389:9;20382:17;20378:45;20375:71;;;20426:18;;:::i;:::-;-1:-1:-1;20466:9:1;;20313:168::o;21314:125::-;21354:4;21382:1;21379;21376:8;21373:34;;;21387:18;;:::i;:::-;-1:-1:-1;21424:9:1;;21314:125::o;21444:136::-;21483:3;21511:5;21501:39;;21520:18;;:::i;:::-;-1:-1:-1;;;21556:18:1;;21444:136::o;22001:500::-;-1:-1:-1;;;;;22270:15:1;;;22252:34;;22322:15;;22317:2;22302:18;;22295:43;22369:2;22354:18;;22347:34;;;22417:3;22412:2;22397:18;;22390:31;;;22195:4;;22438:57;;22475:19;;22467:6;22438:57;:::i;:::-;22430:65;22001:500;-1:-1:-1;;;;;;22001:500:1:o;22506:249::-;22575:6;22628:2;22616:9;22607:7;22603:23;22599:32;22596:52;;;22644:1;22641;22634:12;22596:52;22676:9;22670:16;22695:30;22719:5;22695:30;:::i;22760:127::-;22821:10;22816:3;22812:20;22809:1;22802:31;22852:4;22849:1;22842:15;22876:4;22873:1;22866:15;22892:120;22932:1;22958;22948:35;;22963:18;;:::i;:::-;-1:-1:-1;22997:9:1;;22892:120::o;23017:112::-;23049:1;23075;23065:35;;23080:18;;:::i;:::-;-1:-1:-1;23114:9:1;;23017:112::o;24916:127::-;24977:10;24972:3;24968:20;24965:1;24958:31;25008:4;25005:1;24998:15;25032:4;25029:1;25022:15

Swarm Source

ipfs://051321bb2d344c9847c474f13fcac5981c1430003448f02644d8a592ea81ada1
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.