ETH Price: $3,479.68 (+0.89%)

Token

BraveMoreWant (BMW)
 

Overview

Max Total Supply

200 BMW

Holders

123

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Filtered by Token Holder
daaab.eth
Balance
2 BMW
0x12a0E25E62C1dBD32E505446062B26AECB65F028
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
BMW

Compiler Version
v0.8.7+commit.e28d00a7

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-06
*/

// SPDX-License-Identifier: MIT

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 GSN meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes memory) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

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



pragma solidity ^0.8.0;


/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts may inherit from this and call {_registerInterface} to declare
 * their support of an interface.
 */
abstract contract ERC165 is IERC165 {
    /*
     * bytes4(keccak256('supportsInterface(bytes4)')) == 0x01ffc9a7
     */
    bytes4 private constant _INTERFACE_ID_ERC165 = 0x01ffc9a7;

    /**
     * @dev Mapping of interface ids to whether or not it's supported.
     */
    mapping(bytes4 => bool) private _supportedInterfaces;

    constructor () {
        // Derived contracts need only register support for their own interfaces,
        // we register support for ERC165 itself here
        _registerInterface(_INTERFACE_ID_ERC165);
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     *
     * Time complexity O(1), guaranteed to always use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return _supportedInterfaces[interfaceId];
    }

    /**
     * @dev Registers the contract as an implementer of the interface defined by
     * `interfaceId`. Support of the actual ERC165 interface is automatic and
     * registering its interface id is not required.
     *
     * See {IERC165-supportsInterface}.
     *
     * Requirements:
     *
     * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
     */
    function _registerInterface(bytes4 interfaceId) internal virtual {
        require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
        _supportedInterfaces[interfaceId] = true;
    }
}

// File: @openzeppelin/contracts/math/SafeMath.sol



pragma solidity ^0.8.0;

/**
 * @dev Wrappers over Solidity's arithmetic operations with added overflow
 * checks.
 *
 * Arithmetic operations in Solidity wrap on overflow. This can easily result
 * in bugs, because programmers usually assume that an overflow raises an
 * error, which is the standard behavior in high level programming languages.
 * `SafeMath` restores this intuition by reverting the transaction when an
 * operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        uint256 c = a + b;
        if (c < a) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the substraction of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b > a) return (false, 0);
        return (true, a - b);
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
        // benefit is lost if 'b' is also tested.
        // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
        if (a == 0) return (true, 0);
        uint256 c = a * b;
        if (c / a != b) return (false, 0);
        return (true, c);
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a / b);
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     *
     * _Available since v3.4._
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        if (b == 0) return (false, 0);
        return (true, a % b);
    }

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        uint256 c = a + b;
        require(c >= a, "SafeMath: addition overflow");
        return c;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b <= a, "SafeMath: subtraction overflow");
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        if (a == 0) return 0;
        uint256 c = a * b;
        require(c / a == b, "SafeMath: multiplication overflow");
        return c;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: division by zero");
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        require(b > 0, "SafeMath: modulo by zero");
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b <= a, errorMessage);
        return a - b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryDiv}.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b, string memory errorMessage) internal pure returns (uint256) {
        require(b > 0, errorMessage);
        return a % b;
    }
}

// File: @openzeppelin/contracts/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;
        // solhint-disable-next-line no-inline-assembly
        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");

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (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");

        // solhint-disable-next-line avoid-low-level-calls
        (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");

        // solhint-disable-next-line avoid-low-level-calls
        (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");

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private 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

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

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



pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;

        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping (bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) { // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.

            bytes32 lastvalue = set._values[lastIndex];

            // Move the last value to the index where the value to delete is
            set._values[toDeleteIndex] = lastvalue;
            // Update the index for the moved value
            set._indexes[lastvalue] = toDeleteIndex + 1; // All indexes are 1-based

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        require(set._values.length > index, "EnumerableSet: index out of bounds");
        return set._values[index];
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }


    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }
}

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



pragma solidity ^0.8.0;

/**
 * @dev Library for managing an enumerable variant of Solidity's
 * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]
 * type.
 *
 * Maps have the following properties:
 *
 * - Entries are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Entries are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableMap for EnumerableMap.UintToAddressMap;
 *
 *     // Declare a set state variable
 *     EnumerableMap.UintToAddressMap private myMap;
 * }
 * ```
 *
 * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are
 * supported.
 */
library EnumerableMap {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Map type with
    // bytes32 keys and values.
    // The Map implementation uses private functions, and user-facing
    // implementations (such as Uint256ToAddressMap) are just wrappers around
    // the underlying Map.
    // This means that we can only create new EnumerableMaps for types that fit
    // in bytes32.

    struct MapEntry {
        bytes32 _key;
        bytes32 _value;
    }

    struct Map {
        // Storage of map keys and values
        MapEntry[] _entries;

        // Position of the entry defined by a key in the `entries` array, plus 1
        // because index 0 means a key is not in the map.
        mapping (bytes32 => uint256) _indexes;
    }

    /**
     * @dev Adds a key-value pair to a map, or updates the value for an existing
     * key. O(1).
     *
     * Returns true if the key was added to the map, that is if it was not
     * already present.
     */
    function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {
        // We read and store the key's index to prevent multiple reads from the same storage slot
        uint256 keyIndex = map._indexes[key];

        if (keyIndex == 0) { // Equivalent to !contains(map, key)
            map._entries.push(MapEntry({ _key: key, _value: value }));
            // The entry is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            map._indexes[key] = map._entries.length;
            return true;
        } else {
            map._entries[keyIndex - 1]._value = value;
            return false;
        }
    }

    /**
     * @dev Removes a key-value pair from a map. O(1).
     *
     * Returns true if the key was removed from the map, that is if it was present.
     */
    function _remove(Map storage map, bytes32 key) private returns (bool) {
        // We read and store the key's index to prevent multiple reads from the same storage slot
        uint256 keyIndex = map._indexes[key];

        if (keyIndex != 0) { // Equivalent to contains(map, key)
            // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one
            // in the array, and then remove the last entry (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = keyIndex - 1;
            uint256 lastIndex = map._entries.length - 1;

            // When the entry to delete is the last one, the swap operation is unnecessary. However, since this occurs
            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.

            MapEntry storage lastEntry = map._entries[lastIndex];

            // Move the last entry to the index where the entry to delete is
            map._entries[toDeleteIndex] = lastEntry;
            // Update the index for the moved entry
            map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based

            // Delete the slot where the moved entry was stored
            map._entries.pop();

            // Delete the index for the deleted slot
            delete map._indexes[key];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the key is in the map. O(1).
     */
    function _contains(Map storage map, bytes32 key) private view returns (bool) {
        return map._indexes[key] != 0;
    }

    /**
     * @dev Returns the number of key-value pairs in the map. O(1).
     */
    function _length(Map storage map) private view returns (uint256) {
        return map._entries.length;
    }

   /**
    * @dev Returns the key-value pair stored at position `index` in the map. O(1).
    *
    * Note that there are no guarantees on the ordering of entries inside the
    * array, and it may change when more entries are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {
        require(map._entries.length > index, "EnumerableMap: index out of bounds");

        MapEntry storage entry = map._entries[index];
        return (entry._key, entry._value);
    }

    /**
     * @dev Tries to returns the value associated with `key`.  O(1).
     * Does not revert if `key` is not in the map.
     */
    function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {
        uint256 keyIndex = map._indexes[key];
        if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)
        return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based
    }

    /**
     * @dev Returns the value associated with `key`.  O(1).
     *
     * Requirements:
     *
     * - `key` must be in the map.
     */
    function _get(Map storage map, bytes32 key) private view returns (bytes32) {
        uint256 keyIndex = map._indexes[key];
        require(keyIndex != 0, "EnumerableMap: nonexistent key"); // Equivalent to contains(map, key)
        return map._entries[keyIndex - 1]._value; // All indexes are 1-based
    }

    /**
     * @dev Same as {_get}, with a custom error message when `key` is not in the map.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {_tryGet}.
     */
    function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {
        uint256 keyIndex = map._indexes[key];
        require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)
        return map._entries[keyIndex - 1]._value; // All indexes are 1-based
    }

    // UintToAddressMap

    struct UintToAddressMap {
        Map _inner;
    }

    /**
     * @dev Adds a key-value pair to a map, or updates the value for an existing
     * key. O(1).
     *
     * Returns true if the key was added to the map, that is if it was not
     * already present.
     */
    function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {
        return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the key was removed from the map, that is if it was present.
     */
    function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {
        return _remove(map._inner, bytes32(key));
    }

    /**
     * @dev Returns true if the key is in the map. O(1).
     */
    function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {
        return _contains(map._inner, bytes32(key));
    }

    /**
     * @dev Returns the number of elements in the map. O(1).
     */
    function length(UintToAddressMap storage map) internal view returns (uint256) {
        return _length(map._inner);
    }

   /**
    * @dev Returns the element stored at position `index` in the set. O(1).
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {
        (bytes32 key, bytes32 value) = _at(map._inner, index);
        return (uint256(key), address(uint160(uint256(value))));
    }

    /**
     * @dev Tries to returns the value associated with `key`.  O(1).
     * Does not revert if `key` is not in the map.
     *
     * _Available since v3.4._
     */
    function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {
        (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));
        return (success, address(uint160(uint256(value))));
    }

    /**
     * @dev Returns the value associated with `key`.  O(1).
     *
     * Requirements:
     *
     * - `key` must be in the map.
     */
    function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {
        return address(uint160(uint256(_get(map._inner, bytes32(key)))));
    }

    /**
     * @dev Same as {get}, with a custom error message when `key` is not in the map.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryGet}.
     */
    function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {
        return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));
    }
}

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



pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    /**
     * @dev Converts a `uint256` to its ASCII `string` 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);
    }
}

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



pragma solidity ^0.8.0;












/**
 * @title ERC721 Non-Fungible Token Standard basic implementation
 * @dev see https://eips.ethereum.org/EIPS/eip-721
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {
    using SafeMath for uint256;
    using Address for address;
    using EnumerableSet for EnumerableSet.UintSet;
    using EnumerableMap for EnumerableMap.UintToAddressMap;
    using Strings for uint256;

    // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
    // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`
    bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;

    // Mapping from holder address to their (enumerable) set of owned tokens
    mapping (address => EnumerableSet.UintSet) private _holderTokens;

    // Enumerable mapping from token ids to their owners
    EnumerableMap.UintToAddressMap private _tokenOwners;

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Optional mapping for token URIs
    mapping (uint256 => string) private _tokenURIs;

    // Base URI
    string private _baseURI;

    /*
     *     bytes4(keccak256('balanceOf(address)')) == 0x70a08231
     *     bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e
     *     bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3
     *     bytes4(keccak256('getApproved(uint256)')) == 0x081812fc
     *     bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
     *     bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
     *     bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde
     *
     *     => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^
     *        0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd
     */
    bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;

    /*
     *     bytes4(keccak256('name()')) == 0x06fdde03
     *     bytes4(keccak256('symbol()')) == 0x95d89b41
     *     bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd
     *
     *     => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f
     */
    bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;

    /*
     *     bytes4(keccak256('totalSupply()')) == 0x18160ddd
     *     bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59
     *     bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7
     *
     *     => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63
     */
    bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;

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

        // register the supported interfaces to conform to ERC721 via ERC165
        _registerInterface(_INTERFACE_ID_ERC721);
        _registerInterface(_INTERFACE_ID_ERC721_METADATA);
        _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);
    }

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

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        return _tokenOwners.get(tokenId, "ERC721: owner query for nonexistent token");
    }

    /**
     * @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 _tokenURI = _tokenURIs[tokenId];
        string memory base = baseURI();

        // If there is no base URI, return the token URI.
        if (bytes(base).length == 0) {
            return _tokenURI;
        }
        // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
        if (bytes(_tokenURI).length > 0) {
            return string(abi.encodePacked(base, _tokenURI));
        }
        // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
        return string(abi.encodePacked(base, tokenId.toString()));
    }

    /**
    * @dev Returns the base URI set via {_setBaseURI}. This will be
    * automatically added as a prefix in {tokenURI} to each token's URI, or
    * to the token ID if no specific URI is set for that token ID.
    */
    function baseURI() public view virtual returns (string memory) {
        return _baseURI;
    }

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        return _holderTokens[owner].at(index);
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds
        return _tokenOwners.length();
    }

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        (uint256 tokenId, ) = _tokenOwners.at(index);
        return tokenId;
    }

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        require(operator != _msgSender(), "ERC721: 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 virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

        _holderTokens[to].add(tokenId);

        _tokenOwners.set(tokenId, to);

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

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

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

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

        // Clear metadata (if any)
        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }

        _holderTokens[owner].remove(tokenId);

        _tokenOwners.remove(tokenId);

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

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

        _beforeTokenTransfer(from, to, tokenId);

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

        _holderTokens[from].remove(tokenId);
        _holderTokens[to].add(tokenId);

        _tokenOwners.set(tokenId, to);

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
        require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
        _tokenURIs[tokenId] = _tokenURI;
    }

    /**
     * @dev Internal function to set the base URI for all token IDs. It is
     * automatically added as a prefix to the value returned in {tokenURI},
     * or to the token ID if {tokenURI} is empty.
     */
    function _setBaseURI(string memory baseURI_) internal virtual {
        _baseURI = baseURI_;
    }

    /**
     * @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()) {
            return true;
        }
        bytes memory returndata = to.functionCall(abi.encodeWithSelector(
            IERC721Receiver(to).onERC721Received.selector,
            _msgSender(),
            from,
            tokenId,
            _data
        ), "ERC721: transfer to non ERC721Receiver implementer");
        bytes4 retval = abi.decode(returndata, (bytes4));
        return (retval == _ERC721_RECEIVED);
    }

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

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

// File: @openzeppelin/contracts/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 () {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), 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 {
        emit OwnershipTransferred(_owner, address(0));
        _owner = address(0);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

library MerkleProof {
    
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            bytes32 proofElement = proof[i];
            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
            }
        }
        return computedHash;
    }
}

pragma solidity ^0.8.0;

/**
 * @title NFT
 * @dev Extends ERC721 Non-Fungible Token Standard basic implementation
 */
contract BMW is ERC721, Ownable {
    using SafeMath for uint256;
    using Strings for uint256;

    uint256 public constant NFTPrice = 0.1e18; //0.1 ETH
    uint public constant maxNFTPurchase = 2;
    uint256 public immutable MAX_NFT;
    uint256 public immutable airdropSupply;
    uint256 public immutable presaleSupply;
    uint256 public immutable lastSupply;
    uint256 public nowTokenId; // tokenId start from 1
    // different starting index on three phases0po
    uint256 public startingIndexForAirdrop;
    uint256 public startingIndexForPresale;
    uint256 public startingIndexForLast;

    mapping(address => uint256) public presaleListPurchases;
    mapping(address => uint256) public listPurchases;

    bool public SaleIsActive = false;
    bool public PresaleIsActive = false;
    bool public ForAllIsActive = false;

    address payable public treasury;

    bytes32 public root = 0x7f5ac2647a6c170233be86651caf417afbe3be9cc9ad9c75ede39c465aa45fe0;
    bytes32 public presaleRoot = 0x7f5ac2647a6c170233be86651caf417afbe3be9cc9ad9c75ede39c465aa45fe0;

    constructor(uint256 maxNFTSupply, uint256 _airdropSupply, uint256 _presaleSupply, address payable fundReceiver) ERC721("BraveMoreWant", "BMW") {
        MAX_NFT = maxNFTSupply;
        airdropSupply = _airdropSupply;
        presaleSupply = _presaleSupply;
        lastSupply = maxNFTSupply - _airdropSupply - _presaleSupply;
        treasury = fundReceiver;
    }

    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        string memory base = baseURI();
        string memory unRevealURI = "ipfs://QmXCi2Cc77iWjfastf4dznogShdoc4Eti6t1Lc7n7eYBrg";
        uint256 _onPresaleTotalSupply = airdropSupply + presaleSupply;

        // when airdrop start index has been revealed
        if (startingIndexForAirdrop != 0 && tokenId <= airdropSupply) {
            uint256 _id = tokenId + startingIndexForAirdrop;
            if (_id > airdropSupply) {
                _id -= airdropSupply;
            }
            return string(abi.encodePacked(base, _id.toString()));
        }

        // when first phase start index has been revealed
        if (startingIndexForPresale !=0 && tokenId <= _onPresaleTotalSupply) {
            uint256 _id = tokenId + startingIndexForPresale;
            if (_id > _onPresaleTotalSupply) {
                _id -= presaleSupply;
            }
            return string(abi.encodePacked(base, _id.toString()));
        }

        // when second phase start index has been revealed
        if (startingIndexForLast != 0) {
            uint256 _id = tokenId + startingIndexForLast;
            if (_id > MAX_NFT) {
                _id -= lastSupply;
            }
            return string(abi.encodePacked(base, _id.toString()));
        }

        // when not revealed yet, give the same image
        return unRevealURI;
    }

    /**
    * Mints NFT On First Phase
    */
    function mint(address to, uint numberOfTokens, bytes32[] memory proof) public payable {
        // Gas optimization
        uint256 _nowTokenId = nowTokenId;
        // address operator = _msgSender();

        require(SaleIsActive, "Sale must be active to mint NFT");
        require(_nowTokenId + numberOfTokens <= MAX_NFT, "Purchase would exceed max NFT supply");
        require(NFTPrice.mul(numberOfTokens) <= msg.value, "Ether value sent is not correct");
        if (!ForAllIsActive) {
            require(numberOfTokens <= maxNFTPurchase, "Can only mint 2 tokens at a time");
            require(listPurchases[to] + numberOfTokens <= maxNFTPurchase, 'Error: Error: Each person can mint only 2 in one phase');
            require(MerkleProof.verify(proof, root, keccak256(abi.encodePacked(to))), "You are not allowed to mint");
        }

        // The contract never holds any Ether. Everything gets redirected to treasury directly.
        treasury.transfer(msg.value);
        
        for(uint i = 1; i <= numberOfTokens; i++) {
            listPurchases[to]++;
            _safeMint(to, _nowTokenId + i);
        }
        nowTokenId += numberOfTokens;
    }

    // 如果沒賣完

    function presaleMint(address to, uint numberOfTokens, bytes32[] memory proof) public payable {
        // Gas optimization
        uint256 _nowTokenId = nowTokenId;
        // address operator = _msgSender();

        require(PresaleIsActive, "Presale must be active to mint NFT");
        require(numberOfTokens <= maxNFTPurchase, "Can only mint 2 tokens at a time");
        require((_nowTokenId + numberOfTokens) <= (airdropSupply + presaleSupply), "Purchase would exceed max supply of presale");
        require(NFTPrice.mul(numberOfTokens) <= msg.value, "Ether value sent is not correct");
        require(presaleListPurchases[to] + numberOfTokens <= maxNFTPurchase, 'Error: Each person can mint only 2 tokens in one phase');
        require(MerkleProof.verify(proof, presaleRoot, keccak256(abi.encodePacked(to))), "You are not allowed to mint during presale");

        // The contract never holds any Ether. Everything gets redirected to treasury directly.
        treasury.transfer(msg.value);
        
        for(uint i = 1; i <= numberOfTokens; i++) {
            presaleListPurchases[to]++;
            _safeMint(to, _nowTokenId + i);
        }
        nowTokenId += numberOfTokens;
    }

    /**
     * Set some BraveSeries aside
     */
    function reserve(uint numberOfTokens) public onlyOwner {
        require(numberOfTokens + nowTokenId <= airdropSupply, "reserve would excced max airdrop supply");

        for(uint i = 1; i <= numberOfTokens; i++) {
            _safeMint(msg.sender, nowTokenId + i);
        }
        nowTokenId += numberOfTokens;
    }

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

    // RNG for each phase after fully minted
    function setStartingIndexForAirdrop() public onlyOwner {
        require(startingIndexForAirdrop == 0, "Starting index is already set");
        
        startingIndexForAirdrop = uint(blockhash(block.number - 1)) % airdropSupply;
    }

    function setStartingIndexForPresale() public onlyOwner {
        require(startingIndexForPresale == 0, "Starting index is already set");
        
        startingIndexForPresale = uint(blockhash(block.number - 1)) % presaleSupply;
    }

    function setStartingIndexForLast() public onlyOwner {
        require(startingIndexForLast == 0, "Starting index is already set");
        
        startingIndexForLast = uint(blockhash(block.number - 1)) % lastSupply;
    }

    function setRoot(bytes32 _root) public onlyOwner {
        root = _root;
    }

    function setPresaleRoot(bytes32 _presaleRoot) public onlyOwner {
        presaleRoot = _presaleRoot;
    }

    /*
    * Pause sale if active, make active if paused
    */
    function flipForAllSaleState() public onlyOwner {
        ForAllIsActive = !ForAllIsActive;
    }

    function flipSaleState() public onlyOwner {
        SaleIsActive = !SaleIsActive;
    }

        
    function flipPresaleState() public onlyOwner{
        PresaleIsActive = !PresaleIsActive;
    }

    // burn it down!!!!
    function burn(uint256 tokenId) external {
        require(_isApprovedOrOwner(msg.sender, tokenId), "NFT: burn caller is not owner nor approved");
        _burn(tokenId);
    }
    
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"uint256","name":"maxNFTSupply","type":"uint256"},{"internalType":"uint256","name":"_airdropSupply","type":"uint256"},{"internalType":"uint256","name":"_presaleSupply","type":"uint256"},{"internalType":"address payable","name":"fundReceiver","type":"address"}],"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":[],"name":"ForAllIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_NFT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NFTPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PresaleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SaleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"airdropSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flipForAllSaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flipPresaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flipSaleState","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":"lastSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"listPurchases","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxNFTPurchase","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"numberOfTokens","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nowTokenId","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":[{"internalType":"address","name":"","type":"address"}],"name":"presaleListPurchases","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"numberOfTokens","type":"uint256"},{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"presaleMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"presaleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"presaleSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"}],"name":"reserve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"root","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","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":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_presaleRoot","type":"bytes32"}],"name":"setPresaleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_root","type":"bytes32"}],"name":"setRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setStartingIndexForAirdrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setStartingIndexForLast","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setStartingIndexForPresale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startingIndexForAirdrop","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startingIndexForLast","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startingIndexForPresale","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

6101006040526011805462ffffff191690557f7f5ac2647a6c170233be86651caf417afbe3be9cc9ad9c75ede39c465aa45fe060128190556013553480156200004757600080fd5b506040516200385b3803806200385b8339810160408190526200006a91620002eb565b604080518082018252600d81526c109c985d99535bdc9955d85b9d609a1b60208083019190915282518084019093526003835262424d5760e81b9083015290620000bb6301ffc9a760e01b620001c1565b8151620000d090600690602085019062000245565b508051620000e690600790602084019062000245565b50620000f96380ac58cd60e01b620001c1565b6200010b635b5e139f60e01b620001c1565b6200011d63780e9d6360e01b620001c1565b5050600a80546001600160a01b0319163390811790915560405181906000907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a350608084905260a083905260c0829052816200017e84866200033c565b6200018a91906200033c565b60e052601180546001600160a01b039092166301000000026301000000600160b81b0319909216919091179055506200039f915050565b6001600160e01b03198082161415620002205760405162461bcd60e51b815260206004820152601c60248201527f4552433136353a20696e76616c696420696e7465726661636520696400000000604482015260640160405180910390fd5b6001600160e01b0319166000908152602081905260409020805460ff19166001179055565b828054620002539062000362565b90600052602060002090601f016020900481019282620002775760008555620002c2565b82601f106200029257805160ff1916838001178555620002c2565b82800160010185558215620002c2579182015b82811115620002c2578251825591602001919060010190620002a5565b50620002d0929150620002d4565b5090565b5b80821115620002d05760008155600101620002d5565b600080600080608085870312156200030257600080fd5b845160208601516040870151606088015192965090945092506001600160a01b03811681146200033157600080fd5b939692955090935050565b6000828210156200035d57634e487b7160e01b600052601160045260246000fd5b500390565b600181811c908216806200037757607f821691505b602082108114156200039957634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05160c05160e05161341962000442600039600081816108f50152818161146b0152611bbf015260008181610768015281816111e50152818161156001528181611a030152611b5301526000818161093e01528181610d650152818161134b0152818161158101528181611a2401528181611a5a01528181611a960152611ac10152600081816105e801528181610e670152611b9401526134196000f3fe6080604052600436106102e45760003560e01c8063702a327c11610190578063b3a196e9116100dc578063e60ad04111610095578063f2fde38b1161006f578063f2fde38b146108c3578063f75b8c5f146108e3578063f81227d414610917578063fb3ed5c71461092c57600080fd5b8063e60ad04114610837578063e985e9c514610864578063ebf0c717146108ad57600080fd5b8063b3a196e914610756578063b658b60f1461078a578063b88d4fde146107aa578063c87b56dd146107ca578063d46d35ad146107ea578063dab5f3401461081757600080fd5b80638951764e11610149578063954dc3e311610123578063954dc3e3146106f257806395d89b4114610705578063a22cb4651461071a578063a38bffda1461073a57600080fd5b80638951764e146106a95780638cd7868d146106be5780638da5cb5b146106d457600080fd5b8063702a327c1461060a57806370a082311461061f578063715018a61461063f578063819b25ba14610654578063854496971461067457806386ed1a541461068a57600080fd5b806334918dfd1161024f57806355f804b311610208578063641ce140116101e2578063641ce140146105985780636c0360eb146105ab5780636f79d35a146105c05780636fdaddf1146105d657600080fd5b806355f804b31461053157806361d027b3146105515780636352211e1461057857600080fd5b806334918dfd1461049157806342842e0e146104a657806342966c68146104c65780634b529d86146104e65780634f6ccce7146104fb5780634f8f0a041461051b57600080fd5b80631e386ed3116102a15780631e386ed3146103ec5780632114cc99146104065780632204ae2a1461042657806323b872dd1461043c5780632ba383421461045c5780632f745c591461047157600080fd5b806301ffc9a7146102e957806306fdde0314610338578063081812fc1461035a578063095ea7b31461039257806318160ddd146103b4578063189f92bd146103d7575b600080fd5b3480156102f557600080fd5b50610323610304366004612f4d565b6001600160e01b03191660009081526020819052604090205460ff1690565b60405190151581526020015b60405180910390f35b34801561034457600080fd5b5061034d610960565b60405161032f9190613084565b34801561036657600080fd5b5061037a610375366004612f34565b6109f2565b6040516001600160a01b03909116815260200161032f565b34801561039e57600080fd5b506103b26103ad366004612e41565b610a7f565b005b3480156103c057600080fd5b506103c9610b95565b60405190815260200161032f565b3480156103e357600080fd5b506103c9600281565b3480156103f857600080fd5b506011546103239060ff1681565b34801561041257600080fd5b506011546103239062010000900460ff1681565b34801561043257600080fd5b506103c9600d5481565b34801561044857600080fd5b506103b2610457366004612d4d565b610ba6565b34801561046857600080fd5b506103b2610bd7565b34801561047d57600080fd5b506103c961048c366004612e41565b610c20565b34801561049d57600080fd5b506103b2610c4b565b3480156104b257600080fd5b506103b26104c1366004612d4d565b610c89565b3480156104d257600080fd5b506103b26104e1366004612f34565b610ca4565b3480156104f257600080fd5b506103b2610d19565b34801561050757600080fd5b506103c9610516366004612f34565b610d9f565b34801561052757600080fd5b506103c9600b5481565b34801561053d57600080fd5b506103b261054c366004612f87565b610db5565b34801561055d57600080fd5b5060115461037a90630100000090046001600160a01b031681565b34801561058457600080fd5b5061037a610593366004612f34565b610de8565b6103b26105a6366004612e6b565b610e10565b3480156105b757600080fd5b5061034d61118a565b3480156105cc57600080fd5b506103c9600e5481565b3480156105e257600080fd5b506103c97f000000000000000000000000000000000000000000000000000000000000000081565b34801561061657600080fd5b506103b2611199565b34801561062b57600080fd5b506103c961063a366004612cff565b61121f565b34801561064b57600080fd5b506103b26112ab565b34801561066057600080fd5b506103b261066f366004612f34565b61131f565b34801561068057600080fd5b506103c960135481565b34801561069657600080fd5b5060115461032390610100900460ff1681565b3480156106b557600080fd5b506103b261141f565b3480156106ca57600080fd5b506103c9600c5481565b3480156106e057600080fd5b50600a546001600160a01b031661037a565b6103b2610700366004612e6b565b6114a5565b34801561071157600080fd5b5061034d611829565b34801561072657600080fd5b506103b2610735366004612e05565b611838565b34801561074657600080fd5b506103c967016345785d8a000081565b34801561076257600080fd5b506103c97f000000000000000000000000000000000000000000000000000000000000000081565b34801561079657600080fd5b506103b26107a5366004612f34565b6118fd565b3480156107b657600080fd5b506103b26107c5366004612d89565b61192c565b3480156107d657600080fd5b5061034d6107e5366004612f34565b611964565b3480156107f657600080fd5b506103c9610805366004612cff565b600f6020526000908152604090205481565b34801561082357600080fd5b506103b2610832366004612f34565b611be4565b34801561084357600080fd5b506103c9610852366004612cff565b60106020526000908152604090205481565b34801561087057600080fd5b5061032361087f366004612d1a565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b3480156108b957600080fd5b506103c960125481565b3480156108cf57600080fd5b506103b26108de366004612cff565b611c13565b3480156108ef57600080fd5b506103c97f000000000000000000000000000000000000000000000000000000000000000081565b34801561092357600080fd5b506103b2611cfe565b34801561093857600080fd5b506103c97f000000000000000000000000000000000000000000000000000000000000000081565b60606006805461096f90613265565b80601f016020809104026020016040519081016040528092919081815260200182805461099b90613265565b80156109e85780601f106109bd576101008083540402835291602001916109e8565b820191906000526020600020905b8154815290600101906020018083116109cb57829003601f168201915b5050505050905090565b60006109fd82611d45565b610a635760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b6000610a8a82610de8565b9050806001600160a01b0316836001600160a01b03161415610af85760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610a5a565b336001600160a01b0382161480610b145750610b14813361087f565b610b865760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610a5a565b610b908383611d52565b505050565b6000610ba16002611dc0565b905090565b610bb03382611dca565b610bcc5760405162461bcd60e51b8152600401610a5a90613155565b610b90838383611eb4565b600a546001600160a01b03163314610c015760405162461bcd60e51b8152600401610a5a90613120565b6011805462ff0000198116620100009182900460ff1615909102179055565b6001600160a01b0382166000908152600160205260408120610c429083612035565b90505b92915050565b600a546001600160a01b03163314610c755760405162461bcd60e51b8152600401610a5a90613120565b6011805460ff19811660ff90911615179055565b610b908383836040518060200160405280600081525061192c565b610cae3382611dca565b610d0d5760405162461bcd60e51b815260206004820152602a60248201527f4e46543a206275726e2063616c6c6572206973206e6f74206f776e6572206e6f6044820152691c88185c1c1c9bdd995960b21b6064820152608401610a5a565b610d1681612041565b50565b600a546001600160a01b03163314610d435760405162461bcd60e51b8152600401610a5a90613120565b600c5415610d635760405162461bcd60e51b8152600401610a5a906130e9565b7f0000000000000000000000000000000000000000000000000000000000000000610d8f600143613222565b610d9a9190406132bb565b600c55565b600080610dad6002846120fb565b509392505050565b600a546001600160a01b03163314610ddf5760405162461bcd60e51b8152600401610a5a90613120565b610d1681612117565b6000610c4582604051806060016040528060298152602001613386602991396002919061212e565b600b5460115460ff16610e655760405162461bcd60e51b815260206004820152601f60248201527f53616c65206d7573742062652061637469766520746f206d696e74204e4654006044820152606401610a5a565b7f0000000000000000000000000000000000000000000000000000000000000000610e9084836131d7565b1115610eea5760405162461bcd60e51b8152602060048201526024808201527f507572636861736520776f756c6420657863656564206d6178204e465420737560448201526370706c7960e01b6064820152608401610a5a565b34610efd67016345785d8a000085612145565b1115610f4b5760405162461bcd60e51b815260206004820152601f60248201527f45746865722076616c75652073656e74206973206e6f7420636f7272656374006044820152606401610a5a565b60115462010000900460ff166110d0576002831115610fac5760405162461bcd60e51b815260206004820181905260248201527f43616e206f6e6c79206d696e74203220746f6b656e7320617420612074696d656044820152606401610a5a565b6001600160a01b038416600090815260106020526040902054600290610fd39085906131d7565b11156110405760405162461bcd60e51b815260206004820152603660248201527f4572726f723a204572726f723a204561636820706572736f6e2063616e206d696044820152756e74206f6e6c79203220696e206f6e6520706861736560501b6064820152608401610a5a565b6012546040516bffffffffffffffffffffffff19606087901b1660208201526110849184916034015b604051602081830303815290604052805190602001206121c4565b6110d05760405162461bcd60e51b815260206004820152601b60248201527f596f7520617265206e6f7420616c6c6f77656420746f206d696e7400000000006044820152606401610a5a565b6011546040516001600160a01b03630100000090920491909116903480156108fc02916000818181858888f19350505050158015611112573d6000803e3d6000fd5b5060015b83811161116c576001600160a01b0385166000908152601060205260408120805491611141836132a0565b9091555061115a90508561115583856131d7565b6121da565b80611164816132a0565b915050611116565b5082600b600082825461117f91906131d7565b909155505050505050565b60606009805461096f90613265565b600a546001600160a01b031633146111c35760405162461bcd60e51b8152600401610a5a90613120565b600d54156111e35760405162461bcd60e51b8152600401610a5a906130e9565b7f000000000000000000000000000000000000000000000000000000000000000061120f600143613222565b61121a9190406132bb565b600d55565b60006001600160a01b03821661128a5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610a5a565b6001600160a01b0382166000908152600160205260409020610c4590611dc0565b600a546001600160a01b031633146112d55760405162461bcd60e51b8152600401610a5a90613120565b600a546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600a80546001600160a01b0319169055565b600a546001600160a01b031633146113495760405162461bcd60e51b8152600401610a5a90613120565b7f0000000000000000000000000000000000000000000000000000000000000000600b548261137891906131d7565b11156113d65760405162461bcd60e51b815260206004820152602760248201527f7265736572766520776f756c6420657863636564206d61782061697264726f7060448201526620737570706c7960c81b6064820152608401610a5a565b60015b818111611404576113f23382600b5461115591906131d7565b806113fc816132a0565b9150506113d9565b5080600b600082825461141791906131d7565b909155505050565b600a546001600160a01b031633146114495760405162461bcd60e51b8152600401610a5a90613120565b600e54156114695760405162461bcd60e51b8152600401610a5a906130e9565b7f0000000000000000000000000000000000000000000000000000000000000000611495600143613222565b6114a09190406132bb565b600e55565b600b54601154610100900460ff1661150a5760405162461bcd60e51b815260206004820152602260248201527f50726573616c65206d7573742062652061637469766520746f206d696e74204e604482015261119560f21b6064820152608401610a5a565b600283111561155b5760405162461bcd60e51b815260206004820181905260248201527f43616e206f6e6c79206d696e74203220746f6b656e7320617420612074696d656044820152606401610a5a565b6115a57f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006131d7565b6115af84836131d7565b11156116115760405162461bcd60e51b815260206004820152602b60248201527f507572636861736520776f756c6420657863656564206d617820737570706c7960448201526a206f662070726573616c6560a81b6064820152608401610a5a565b3461162467016345785d8a000085612145565b11156116725760405162461bcd60e51b815260206004820152601f60248201527f45746865722076616c75652073656e74206973206e6f7420636f7272656374006044820152606401610a5a565b6001600160a01b0384166000908152600f60205260409020546002906116999085906131d7565b11156117065760405162461bcd60e51b815260206004820152603660248201527f4572726f723a204561636820706572736f6e2063616e206d696e74206f6e6c79604482015275203220746f6b656e7320696e206f6e6520706861736560501b6064820152608401610a5a565b6013546040516bffffffffffffffffffffffff19606087901b166020820152611733918491603401611069565b6117925760405162461bcd60e51b815260206004820152602a60248201527f596f7520617265206e6f7420616c6c6f77656420746f206d696e7420647572696044820152696e672070726573616c6560b01b6064820152608401610a5a565b6011546040516001600160a01b03630100000090920491909116903480156108fc02916000818181858888f193505050501580156117d4573d6000803e3d6000fd5b5060015b83811161116c576001600160a01b0385166000908152600f60205260408120805491611803836132a0565b9091555061181790508561115583856131d7565b80611821816132a0565b9150506117d8565b60606007805461096f90613265565b6001600160a01b0382163314156118915760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610a5a565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600a546001600160a01b031633146119275760405162461bcd60e51b8152600401610a5a90613120565b601355565b6119363383611dca565b6119525760405162461bcd60e51b8152600401610a5a90613155565b61195e848484846121f4565b50505050565b606061196f82611d45565b6119d35760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610a5a565b60006119dd61118a565b905060006040518060600160405280603581526020016133af6035913990506000611a487f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000006131d7565b9050600c54600014158015611a7d57507f00000000000000000000000000000000000000000000000000000000000000008511155b15611b1e576000600c5486611a9291906131d7565b90507f0000000000000000000000000000000000000000000000000000000000000000811115611ae957611ae67f000000000000000000000000000000000000000000000000000000000000000082613222565b90505b83611af382612227565b604051602001611b04929190613018565b604051602081830303815290604052945050505050919050565b600d5415801590611b2f5750808511155b15611b78576000600d5486611b4491906131d7565b905081811115611ae957611ae67f000000000000000000000000000000000000000000000000000000000000000082613222565b600e5415610dad576000600e5486611b9091906131d7565b90507f0000000000000000000000000000000000000000000000000000000000000000811115611ae957611ae67f000000000000000000000000000000000000000000000000000000000000000082613222565b600a546001600160a01b03163314611c0e5760405162461bcd60e51b8152600401610a5a90613120565b601255565b600a546001600160a01b03163314611c3d5760405162461bcd60e51b8152600401610a5a90613120565b6001600160a01b038116611ca25760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a5a565b600a546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600a80546001600160a01b0319166001600160a01b0392909216919091179055565b600a546001600160a01b03163314611d285760405162461bcd60e51b8152600401610a5a90613120565b6011805461ff001981166101009182900460ff1615909102179055565b6000610c45600283612325565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611d8782610de8565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000610c45825490565b6000611dd582611d45565b611e365760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610a5a565b6000611e4183610de8565b9050806001600160a01b0316846001600160a01b03161480611e7c5750836001600160a01b0316611e71846109f2565b6001600160a01b0316145b80611eac57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316611ec782610de8565b6001600160a01b031614611f2f5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610a5a565b6001600160a01b038216611f915760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610a5a565b611f9c600082611d52565b6001600160a01b0383166000908152600160205260409020611fbe908261233d565b506001600160a01b0382166000908152600160205260409020611fe19082612349565b50611fee60028284612355565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000610c42838361236b565b600061204c82610de8565b9050612059600083611d52565b6000828152600860205260409020805461207290613265565b15905061209057600082815260086020526040812061209091612bb8565b6001600160a01b03811660009081526001602052604090206120b2908361233d565b506120be6002836123f1565b5060405182906000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b600080808061210a86866123fd565b9097909650945050505050565b805161212a906009906020840190612bf2565b5050565b600061213b84848461249a565b90505b9392505050565b60008261215457506000610c45565b60006121608385613203565b90508261216d85836131ef565b14610c425760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b6064820152608401610a5a565b6000826121d18584612503565b14949350505050565b61212a8282604051806020016040528060008152506125a7565b6121ff848484611eb4565b61220b848484846125da565b61195e5760405162461bcd60e51b8152600401610a5a90613097565b60608161224b5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612275578061225f816132a0565b915061226e9050600a836131ef565b915061224f565b60008167ffffffffffffffff81111561229057612290613327565b6040519080825280601f01601f1916602001820160405280156122ba576020820181803683370190505b5090505b8415611eac576122cf600183613222565b91506122dc600a866132bb565b6122e79060306131d7565b60f81b8183815181106122fc576122fc613311565b60200101906001600160f81b031916908160001a90535061231e600a866131ef565b94506122be565b60008181526001830160205260408120541515610c42565b6000610c4283836126ab565b6000610c42838361279e565b600061213b84846001600160a01b0385166127ed565b815460009082106123c95760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610a5a565b8260000182815481106123de576123de613311565b9060005260206000200154905092915050565b6000610c42838361288e565b81546000908190831061245d5760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610a5a565b600084600001848154811061247457612474613311565b906000526020600020906002020190508060000154816001015492509250509250929050565b600082815260018401602052604081205482816124ca5760405162461bcd60e51b8152600401610a5a9190613084565b50846124d7600183613222565b815481106124e7576124e7613311565b9060005260206000209060020201600101549150509392505050565b600081815b8451811015610dad57600085828151811061252557612525613311565b60200260200101519050808311612567576040805160208101859052908101829052606001604051602081830303815290604052805190602001209250612594565b60408051602081018390529081018490526060016040516020818303038152906040528051906020012092505b508061259f816132a0565b915050612508565b6125b18383612995565b6125be60008484846125da565b610b905760405162461bcd60e51b8152600401610a5a90613097565b60006001600160a01b0384163b6125f357506001611eac565b6000612674630a85bd0160e11b338887876040516024016126179493929190613047565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050604051806060016040528060328152602001613354603291396001600160a01b0388169190612aad565b905060008180602001905181019061268c9190612f6a565b6001600160e01b031916630a85bd0160e11b1492505050949350505050565b600081815260018301602052604081205480156127945760006126cf600183613222565b85549091506000906126e390600190613222565b905060008660000182815481106126fc576126fc613311565b906000526020600020015490508087600001848154811061271f5761271f613311565b6000918252602090912001556127368360016131d7565b60008281526001890160205260409020558654879080612758576127586132fb565b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610c45565b6000915050610c45565b60008181526001830160205260408120546127e557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610c45565b506000610c45565b60008281526001840160205260408120548061285257505060408051808201825283815260208082018481528654600181810189556000898152848120955160029093029095019182559151908201558654868452818801909252929091205561213e565b828561285f600184613222565b8154811061286f5761286f613311565b906000526020600020906002020160010181905550600091505061213e565b600081815260018301602052604081205480156127945760006128b2600183613222565b85549091506000906128c690600190613222565b905060008660000182815481106128df576128df613311565b906000526020600020906002020190508087600001848154811061290557612905613311565b6000918252602090912082546002909202019081556001918201549082015561292f9084906131d7565b815460009081526001890160205260409020558654879080612953576129536132fb565b6000828152602080822060026000199094019384020182815560019081018390559290935588815289820190925260408220919091559450610c459350505050565b6001600160a01b0382166129eb5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610a5a565b6129f481611d45565b15612a415760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610a5a565b6001600160a01b0382166000908152600160205260409020612a639082612349565b50612a7060028284612355565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b606061213b848460008585843b612b065760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a5a565b600080866001600160a01b03168587604051612b229190612ffc565b60006040518083038185875af1925050503d8060008114612b5f576040519150601f19603f3d011682016040523d82523d6000602084013e612b64565b606091505b5091509150612b74828286612b7f565b979650505050505050565b60608315612b8e57508161213e565b825115612b9e5782518084602001fd5b8160405162461bcd60e51b8152600401610a5a9190613084565b508054612bc490613265565b6000825580601f10612bd4575050565b601f016020900490600052602060002090810190610d169190612c76565b828054612bfe90613265565b90600052602060002090601f016020900481019282612c205760008555612c66565b82601f10612c3957805160ff1916838001178555612c66565b82800160010185558215612c66579182015b82811115612c66578251825591602001919060010190612c4b565b50612c72929150612c76565b5090565b5b80821115612c725760008155600101612c77565b600067ffffffffffffffff831115612ca557612ca5613327565b612cb8601f8401601f19166020016131a6565b9050828152838383011115612ccc57600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b0381168114612cfa57600080fd5b919050565b600060208284031215612d1157600080fd5b610c4282612ce3565b60008060408385031215612d2d57600080fd5b612d3683612ce3565b9150612d4460208401612ce3565b90509250929050565b600080600060608486031215612d6257600080fd5b612d6b84612ce3565b9250612d7960208501612ce3565b9150604084013590509250925092565b60008060008060808587031215612d9f57600080fd5b612da885612ce3565b9350612db660208601612ce3565b925060408501359150606085013567ffffffffffffffff811115612dd957600080fd5b8501601f81018713612dea57600080fd5b612df987823560208401612c8b565b91505092959194509250565b60008060408385031215612e1857600080fd5b612e2183612ce3565b915060208301358015158114612e3657600080fd5b809150509250929050565b60008060408385031215612e5457600080fd5b612e5d83612ce3565b946020939093013593505050565b600080600060608486031215612e8057600080fd5b612e8984612ce3565b92506020808501359250604085013567ffffffffffffffff80821115612eae57600080fd5b818701915087601f830112612ec257600080fd5b813581811115612ed457612ed4613327565b8060051b9150612ee58483016131a6565b8181528481019084860184860187018c1015612f0057600080fd5b600095505b83861015612f23578035835260019590950194918601918601612f05565b508096505050505050509250925092565b600060208284031215612f4657600080fd5b5035919050565b600060208284031215612f5f57600080fd5b8135610c428161333d565b600060208284031215612f7c57600080fd5b8151610c428161333d565b600060208284031215612f9957600080fd5b813567ffffffffffffffff811115612fb057600080fd5b8201601f81018413612fc157600080fd5b611eac84823560208401612c8b565b60008151808452612fe8816020860160208601613239565b601f01601f19169290920160200192915050565b6000825161300e818460208701613239565b9190910192915050565b6000835161302a818460208801613239565b83519083019061303e818360208801613239565b01949350505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061307a90830184612fd0565b9695505050505050565b602081526000610c426020830184612fd0565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252601d908201527f5374617274696e6720696e64657820697320616c726561647920736574000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b604051601f8201601f1916810167ffffffffffffffff811182821017156131cf576131cf613327565b604052919050565b600082198211156131ea576131ea6132cf565b500190565b6000826131fe576131fe6132e5565b500490565b600081600019048311821515161561321d5761321d6132cf565b500290565b600082821015613234576132346132cf565b500390565b60005b8381101561325457818101518382015260200161323c565b8381111561195e5750506000910152565b600181811c9082168061327957607f821691505b6020821081141561329a57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156132b4576132b46132cf565b5060010190565b6000826132ca576132ca6132e5565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114610d1657600080fdfe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e697066733a2f2f516d584369324363373769576a666173746634647a6e6f675368646f63344574693674314c63376e376559427267a26469706673582212208ab3885420cedffd586d53f18ed32f6e711792642e1775ecf112939a30ee329a64736f6c6343000807003300000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000320000000000000000000000002f1daaabe3463ba5224386dcefb2c9d9024a9b3b

Deployed Bytecode

0x6080604052600436106102e45760003560e01c8063702a327c11610190578063b3a196e9116100dc578063e60ad04111610095578063f2fde38b1161006f578063f2fde38b146108c3578063f75b8c5f146108e3578063f81227d414610917578063fb3ed5c71461092c57600080fd5b8063e60ad04114610837578063e985e9c514610864578063ebf0c717146108ad57600080fd5b8063b3a196e914610756578063b658b60f1461078a578063b88d4fde146107aa578063c87b56dd146107ca578063d46d35ad146107ea578063dab5f3401461081757600080fd5b80638951764e11610149578063954dc3e311610123578063954dc3e3146106f257806395d89b4114610705578063a22cb4651461071a578063a38bffda1461073a57600080fd5b80638951764e146106a95780638cd7868d146106be5780638da5cb5b146106d457600080fd5b8063702a327c1461060a57806370a082311461061f578063715018a61461063f578063819b25ba14610654578063854496971461067457806386ed1a541461068a57600080fd5b806334918dfd1161024f57806355f804b311610208578063641ce140116101e2578063641ce140146105985780636c0360eb146105ab5780636f79d35a146105c05780636fdaddf1146105d657600080fd5b806355f804b31461053157806361d027b3146105515780636352211e1461057857600080fd5b806334918dfd1461049157806342842e0e146104a657806342966c68146104c65780634b529d86146104e65780634f6ccce7146104fb5780634f8f0a041461051b57600080fd5b80631e386ed3116102a15780631e386ed3146103ec5780632114cc99146104065780632204ae2a1461042657806323b872dd1461043c5780632ba383421461045c5780632f745c591461047157600080fd5b806301ffc9a7146102e957806306fdde0314610338578063081812fc1461035a578063095ea7b31461039257806318160ddd146103b4578063189f92bd146103d7575b600080fd5b3480156102f557600080fd5b50610323610304366004612f4d565b6001600160e01b03191660009081526020819052604090205460ff1690565b60405190151581526020015b60405180910390f35b34801561034457600080fd5b5061034d610960565b60405161032f9190613084565b34801561036657600080fd5b5061037a610375366004612f34565b6109f2565b6040516001600160a01b03909116815260200161032f565b34801561039e57600080fd5b506103b26103ad366004612e41565b610a7f565b005b3480156103c057600080fd5b506103c9610b95565b60405190815260200161032f565b3480156103e357600080fd5b506103c9600281565b3480156103f857600080fd5b506011546103239060ff1681565b34801561041257600080fd5b506011546103239062010000900460ff1681565b34801561043257600080fd5b506103c9600d5481565b34801561044857600080fd5b506103b2610457366004612d4d565b610ba6565b34801561046857600080fd5b506103b2610bd7565b34801561047d57600080fd5b506103c961048c366004612e41565b610c20565b34801561049d57600080fd5b506103b2610c4b565b3480156104b257600080fd5b506103b26104c1366004612d4d565b610c89565b3480156104d257600080fd5b506103b26104e1366004612f34565b610ca4565b3480156104f257600080fd5b506103b2610d19565b34801561050757600080fd5b506103c9610516366004612f34565b610d9f565b34801561052757600080fd5b506103c9600b5481565b34801561053d57600080fd5b506103b261054c366004612f87565b610db5565b34801561055d57600080fd5b5060115461037a90630100000090046001600160a01b031681565b34801561058457600080fd5b5061037a610593366004612f34565b610de8565b6103b26105a6366004612e6b565b610e10565b3480156105b757600080fd5b5061034d61118a565b3480156105cc57600080fd5b506103c9600e5481565b3480156105e257600080fd5b506103c97f00000000000000000000000000000000000000000000000000000000000000c881565b34801561061657600080fd5b506103b2611199565b34801561062b57600080fd5b506103c961063a366004612cff565b61121f565b34801561064b57600080fd5b506103b26112ab565b34801561066057600080fd5b506103b261066f366004612f34565b61131f565b34801561068057600080fd5b506103c960135481565b34801561069657600080fd5b5060115461032390610100900460ff1681565b3480156106b557600080fd5b506103b261141f565b3480156106ca57600080fd5b506103c9600c5481565b3480156106e057600080fd5b50600a546001600160a01b031661037a565b6103b2610700366004612e6b565b6114a5565b34801561071157600080fd5b5061034d611829565b34801561072657600080fd5b506103b2610735366004612e05565b611838565b34801561074657600080fd5b506103c967016345785d8a000081565b34801561076257600080fd5b506103c97f000000000000000000000000000000000000000000000000000000000000003281565b34801561079657600080fd5b506103b26107a5366004612f34565b6118fd565b3480156107b657600080fd5b506103b26107c5366004612d89565b61192c565b3480156107d657600080fd5b5061034d6107e5366004612f34565b611964565b3480156107f657600080fd5b506103c9610805366004612cff565b600f6020526000908152604090205481565b34801561082357600080fd5b506103b2610832366004612f34565b611be4565b34801561084357600080fd5b506103c9610852366004612cff565b60106020526000908152604090205481565b34801561087057600080fd5b5061032361087f366004612d1a565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b3480156108b957600080fd5b506103c960125481565b3480156108cf57600080fd5b506103b26108de366004612cff565b611c13565b3480156108ef57600080fd5b506103c97f000000000000000000000000000000000000000000000000000000000000006481565b34801561092357600080fd5b506103b2611cfe565b34801561093857600080fd5b506103c97f000000000000000000000000000000000000000000000000000000000000003281565b60606006805461096f90613265565b80601f016020809104026020016040519081016040528092919081815260200182805461099b90613265565b80156109e85780601f106109bd576101008083540402835291602001916109e8565b820191906000526020600020905b8154815290600101906020018083116109cb57829003601f168201915b5050505050905090565b60006109fd82611d45565b610a635760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b6000610a8a82610de8565b9050806001600160a01b0316836001600160a01b03161415610af85760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610a5a565b336001600160a01b0382161480610b145750610b14813361087f565b610b865760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610a5a565b610b908383611d52565b505050565b6000610ba16002611dc0565b905090565b610bb03382611dca565b610bcc5760405162461bcd60e51b8152600401610a5a90613155565b610b90838383611eb4565b600a546001600160a01b03163314610c015760405162461bcd60e51b8152600401610a5a90613120565b6011805462ff0000198116620100009182900460ff1615909102179055565b6001600160a01b0382166000908152600160205260408120610c429083612035565b90505b92915050565b600a546001600160a01b03163314610c755760405162461bcd60e51b8152600401610a5a90613120565b6011805460ff19811660ff90911615179055565b610b908383836040518060200160405280600081525061192c565b610cae3382611dca565b610d0d5760405162461bcd60e51b815260206004820152602a60248201527f4e46543a206275726e2063616c6c6572206973206e6f74206f776e6572206e6f6044820152691c88185c1c1c9bdd995960b21b6064820152608401610a5a565b610d1681612041565b50565b600a546001600160a01b03163314610d435760405162461bcd60e51b8152600401610a5a90613120565b600c5415610d635760405162461bcd60e51b8152600401610a5a906130e9565b7f0000000000000000000000000000000000000000000000000000000000000032610d8f600143613222565b610d9a9190406132bb565b600c55565b600080610dad6002846120fb565b509392505050565b600a546001600160a01b03163314610ddf5760405162461bcd60e51b8152600401610a5a90613120565b610d1681612117565b6000610c4582604051806060016040528060298152602001613386602991396002919061212e565b600b5460115460ff16610e655760405162461bcd60e51b815260206004820152601f60248201527f53616c65206d7573742062652061637469766520746f206d696e74204e4654006044820152606401610a5a565b7f00000000000000000000000000000000000000000000000000000000000000c8610e9084836131d7565b1115610eea5760405162461bcd60e51b8152602060048201526024808201527f507572636861736520776f756c6420657863656564206d6178204e465420737560448201526370706c7960e01b6064820152608401610a5a565b34610efd67016345785d8a000085612145565b1115610f4b5760405162461bcd60e51b815260206004820152601f60248201527f45746865722076616c75652073656e74206973206e6f7420636f7272656374006044820152606401610a5a565b60115462010000900460ff166110d0576002831115610fac5760405162461bcd60e51b815260206004820181905260248201527f43616e206f6e6c79206d696e74203220746f6b656e7320617420612074696d656044820152606401610a5a565b6001600160a01b038416600090815260106020526040902054600290610fd39085906131d7565b11156110405760405162461bcd60e51b815260206004820152603660248201527f4572726f723a204572726f723a204561636820706572736f6e2063616e206d696044820152756e74206f6e6c79203220696e206f6e6520706861736560501b6064820152608401610a5a565b6012546040516bffffffffffffffffffffffff19606087901b1660208201526110849184916034015b604051602081830303815290604052805190602001206121c4565b6110d05760405162461bcd60e51b815260206004820152601b60248201527f596f7520617265206e6f7420616c6c6f77656420746f206d696e7400000000006044820152606401610a5a565b6011546040516001600160a01b03630100000090920491909116903480156108fc02916000818181858888f19350505050158015611112573d6000803e3d6000fd5b5060015b83811161116c576001600160a01b0385166000908152601060205260408120805491611141836132a0565b9091555061115a90508561115583856131d7565b6121da565b80611164816132a0565b915050611116565b5082600b600082825461117f91906131d7565b909155505050505050565b60606009805461096f90613265565b600a546001600160a01b031633146111c35760405162461bcd60e51b8152600401610a5a90613120565b600d54156111e35760405162461bcd60e51b8152600401610a5a906130e9565b7f000000000000000000000000000000000000000000000000000000000000003261120f600143613222565b61121a9190406132bb565b600d55565b60006001600160a01b03821661128a5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610a5a565b6001600160a01b0382166000908152600160205260409020610c4590611dc0565b600a546001600160a01b031633146112d55760405162461bcd60e51b8152600401610a5a90613120565b600a546040516000916001600160a01b0316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3600a80546001600160a01b0319169055565b600a546001600160a01b031633146113495760405162461bcd60e51b8152600401610a5a90613120565b7f0000000000000000000000000000000000000000000000000000000000000032600b548261137891906131d7565b11156113d65760405162461bcd60e51b815260206004820152602760248201527f7265736572766520776f756c6420657863636564206d61782061697264726f7060448201526620737570706c7960c81b6064820152608401610a5a565b60015b818111611404576113f23382600b5461115591906131d7565b806113fc816132a0565b9150506113d9565b5080600b600082825461141791906131d7565b909155505050565b600a546001600160a01b031633146114495760405162461bcd60e51b8152600401610a5a90613120565b600e54156114695760405162461bcd60e51b8152600401610a5a906130e9565b7f0000000000000000000000000000000000000000000000000000000000000064611495600143613222565b6114a09190406132bb565b600e55565b600b54601154610100900460ff1661150a5760405162461bcd60e51b815260206004820152602260248201527f50726573616c65206d7573742062652061637469766520746f206d696e74204e604482015261119560f21b6064820152608401610a5a565b600283111561155b5760405162461bcd60e51b815260206004820181905260248201527f43616e206f6e6c79206d696e74203220746f6b656e7320617420612074696d656044820152606401610a5a565b6115a57f00000000000000000000000000000000000000000000000000000000000000327f00000000000000000000000000000000000000000000000000000000000000326131d7565b6115af84836131d7565b11156116115760405162461bcd60e51b815260206004820152602b60248201527f507572636861736520776f756c6420657863656564206d617820737570706c7960448201526a206f662070726573616c6560a81b6064820152608401610a5a565b3461162467016345785d8a000085612145565b11156116725760405162461bcd60e51b815260206004820152601f60248201527f45746865722076616c75652073656e74206973206e6f7420636f7272656374006044820152606401610a5a565b6001600160a01b0384166000908152600f60205260409020546002906116999085906131d7565b11156117065760405162461bcd60e51b815260206004820152603660248201527f4572726f723a204561636820706572736f6e2063616e206d696e74206f6e6c79604482015275203220746f6b656e7320696e206f6e6520706861736560501b6064820152608401610a5a565b6013546040516bffffffffffffffffffffffff19606087901b166020820152611733918491603401611069565b6117925760405162461bcd60e51b815260206004820152602a60248201527f596f7520617265206e6f7420616c6c6f77656420746f206d696e7420647572696044820152696e672070726573616c6560b01b6064820152608401610a5a565b6011546040516001600160a01b03630100000090920491909116903480156108fc02916000818181858888f193505050501580156117d4573d6000803e3d6000fd5b5060015b83811161116c576001600160a01b0385166000908152600f60205260408120805491611803836132a0565b9091555061181790508561115583856131d7565b80611821816132a0565b9150506117d8565b60606007805461096f90613265565b6001600160a01b0382163314156118915760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610a5a565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600a546001600160a01b031633146119275760405162461bcd60e51b8152600401610a5a90613120565b601355565b6119363383611dca565b6119525760405162461bcd60e51b8152600401610a5a90613155565b61195e848484846121f4565b50505050565b606061196f82611d45565b6119d35760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610a5a565b60006119dd61118a565b905060006040518060600160405280603581526020016133af6035913990506000611a487f00000000000000000000000000000000000000000000000000000000000000327f00000000000000000000000000000000000000000000000000000000000000326131d7565b9050600c54600014158015611a7d57507f00000000000000000000000000000000000000000000000000000000000000328511155b15611b1e576000600c5486611a9291906131d7565b90507f0000000000000000000000000000000000000000000000000000000000000032811115611ae957611ae67f000000000000000000000000000000000000000000000000000000000000003282613222565b90505b83611af382612227565b604051602001611b04929190613018565b604051602081830303815290604052945050505050919050565b600d5415801590611b2f5750808511155b15611b78576000600d5486611b4491906131d7565b905081811115611ae957611ae67f000000000000000000000000000000000000000000000000000000000000003282613222565b600e5415610dad576000600e5486611b9091906131d7565b90507f00000000000000000000000000000000000000000000000000000000000000c8811115611ae957611ae67f000000000000000000000000000000000000000000000000000000000000006482613222565b600a546001600160a01b03163314611c0e5760405162461bcd60e51b8152600401610a5a90613120565b601255565b600a546001600160a01b03163314611c3d5760405162461bcd60e51b8152600401610a5a90613120565b6001600160a01b038116611ca25760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a5a565b600a546040516001600160a01b038084169216907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a3600a80546001600160a01b0319166001600160a01b0392909216919091179055565b600a546001600160a01b03163314611d285760405162461bcd60e51b8152600401610a5a90613120565b6011805461ff001981166101009182900460ff1615909102179055565b6000610c45600283612325565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611d8782610de8565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000610c45825490565b6000611dd582611d45565b611e365760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610a5a565b6000611e4183610de8565b9050806001600160a01b0316846001600160a01b03161480611e7c5750836001600160a01b0316611e71846109f2565b6001600160a01b0316145b80611eac57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316611ec782610de8565b6001600160a01b031614611f2f5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610a5a565b6001600160a01b038216611f915760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610a5a565b611f9c600082611d52565b6001600160a01b0383166000908152600160205260409020611fbe908261233d565b506001600160a01b0382166000908152600160205260409020611fe19082612349565b50611fee60028284612355565b5080826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b6000610c42838361236b565b600061204c82610de8565b9050612059600083611d52565b6000828152600860205260409020805461207290613265565b15905061209057600082815260086020526040812061209091612bb8565b6001600160a01b03811660009081526001602052604090206120b2908361233d565b506120be6002836123f1565b5060405182906000906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b600080808061210a86866123fd565b9097909650945050505050565b805161212a906009906020840190612bf2565b5050565b600061213b84848461249a565b90505b9392505050565b60008261215457506000610c45565b60006121608385613203565b90508261216d85836131ef565b14610c425760405162461bcd60e51b815260206004820152602160248201527f536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f6044820152607760f81b6064820152608401610a5a565b6000826121d18584612503565b14949350505050565b61212a8282604051806020016040528060008152506125a7565b6121ff848484611eb4565b61220b848484846125da565b61195e5760405162461bcd60e51b8152600401610a5a90613097565b60608161224b5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612275578061225f816132a0565b915061226e9050600a836131ef565b915061224f565b60008167ffffffffffffffff81111561229057612290613327565b6040519080825280601f01601f1916602001820160405280156122ba576020820181803683370190505b5090505b8415611eac576122cf600183613222565b91506122dc600a866132bb565b6122e79060306131d7565b60f81b8183815181106122fc576122fc613311565b60200101906001600160f81b031916908160001a90535061231e600a866131ef565b94506122be565b60008181526001830160205260408120541515610c42565b6000610c4283836126ab565b6000610c42838361279e565b600061213b84846001600160a01b0385166127ed565b815460009082106123c95760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610a5a565b8260000182815481106123de576123de613311565b9060005260206000200154905092915050565b6000610c42838361288e565b81546000908190831061245d5760405162461bcd60e51b815260206004820152602260248201527f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610a5a565b600084600001848154811061247457612474613311565b906000526020600020906002020190508060000154816001015492509250509250929050565b600082815260018401602052604081205482816124ca5760405162461bcd60e51b8152600401610a5a9190613084565b50846124d7600183613222565b815481106124e7576124e7613311565b9060005260206000209060020201600101549150509392505050565b600081815b8451811015610dad57600085828151811061252557612525613311565b60200260200101519050808311612567576040805160208101859052908101829052606001604051602081830303815290604052805190602001209250612594565b60408051602081018390529081018490526060016040516020818303038152906040528051906020012092505b508061259f816132a0565b915050612508565b6125b18383612995565b6125be60008484846125da565b610b905760405162461bcd60e51b8152600401610a5a90613097565b60006001600160a01b0384163b6125f357506001611eac565b6000612674630a85bd0160e11b338887876040516024016126179493929190613047565b604051602081830303815290604052906001600160e01b0319166020820180516001600160e01b038381831617835250505050604051806060016040528060328152602001613354603291396001600160a01b0388169190612aad565b905060008180602001905181019061268c9190612f6a565b6001600160e01b031916630a85bd0160e11b1492505050949350505050565b600081815260018301602052604081205480156127945760006126cf600183613222565b85549091506000906126e390600190613222565b905060008660000182815481106126fc576126fc613311565b906000526020600020015490508087600001848154811061271f5761271f613311565b6000918252602090912001556127368360016131d7565b60008281526001890160205260409020558654879080612758576127586132fb565b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050610c45565b6000915050610c45565b60008181526001830160205260408120546127e557508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610c45565b506000610c45565b60008281526001840160205260408120548061285257505060408051808201825283815260208082018481528654600181810189556000898152848120955160029093029095019182559151908201558654868452818801909252929091205561213e565b828561285f600184613222565b8154811061286f5761286f613311565b906000526020600020906002020160010181905550600091505061213e565b600081815260018301602052604081205480156127945760006128b2600183613222565b85549091506000906128c690600190613222565b905060008660000182815481106128df576128df613311565b906000526020600020906002020190508087600001848154811061290557612905613311565b6000918252602090912082546002909202019081556001918201549082015561292f9084906131d7565b815460009081526001890160205260409020558654879080612953576129536132fb565b6000828152602080822060026000199094019384020182815560019081018390559290935588815289820190925260408220919091559450610c459350505050565b6001600160a01b0382166129eb5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610a5a565b6129f481611d45565b15612a415760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610a5a565b6001600160a01b0382166000908152600160205260409020612a639082612349565b50612a7060028284612355565b5060405181906001600160a01b038416906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b606061213b848460008585843b612b065760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610a5a565b600080866001600160a01b03168587604051612b229190612ffc565b60006040518083038185875af1925050503d8060008114612b5f576040519150601f19603f3d011682016040523d82523d6000602084013e612b64565b606091505b5091509150612b74828286612b7f565b979650505050505050565b60608315612b8e57508161213e565b825115612b9e5782518084602001fd5b8160405162461bcd60e51b8152600401610a5a9190613084565b508054612bc490613265565b6000825580601f10612bd4575050565b601f016020900490600052602060002090810190610d169190612c76565b828054612bfe90613265565b90600052602060002090601f016020900481019282612c205760008555612c66565b82601f10612c3957805160ff1916838001178555612c66565b82800160010185558215612c66579182015b82811115612c66578251825591602001919060010190612c4b565b50612c72929150612c76565b5090565b5b80821115612c725760008155600101612c77565b600067ffffffffffffffff831115612ca557612ca5613327565b612cb8601f8401601f19166020016131a6565b9050828152838383011115612ccc57600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b0381168114612cfa57600080fd5b919050565b600060208284031215612d1157600080fd5b610c4282612ce3565b60008060408385031215612d2d57600080fd5b612d3683612ce3565b9150612d4460208401612ce3565b90509250929050565b600080600060608486031215612d6257600080fd5b612d6b84612ce3565b9250612d7960208501612ce3565b9150604084013590509250925092565b60008060008060808587031215612d9f57600080fd5b612da885612ce3565b9350612db660208601612ce3565b925060408501359150606085013567ffffffffffffffff811115612dd957600080fd5b8501601f81018713612dea57600080fd5b612df987823560208401612c8b565b91505092959194509250565b60008060408385031215612e1857600080fd5b612e2183612ce3565b915060208301358015158114612e3657600080fd5b809150509250929050565b60008060408385031215612e5457600080fd5b612e5d83612ce3565b946020939093013593505050565b600080600060608486031215612e8057600080fd5b612e8984612ce3565b92506020808501359250604085013567ffffffffffffffff80821115612eae57600080fd5b818701915087601f830112612ec257600080fd5b813581811115612ed457612ed4613327565b8060051b9150612ee58483016131a6565b8181528481019084860184860187018c1015612f0057600080fd5b600095505b83861015612f23578035835260019590950194918601918601612f05565b508096505050505050509250925092565b600060208284031215612f4657600080fd5b5035919050565b600060208284031215612f5f57600080fd5b8135610c428161333d565b600060208284031215612f7c57600080fd5b8151610c428161333d565b600060208284031215612f9957600080fd5b813567ffffffffffffffff811115612fb057600080fd5b8201601f81018413612fc157600080fd5b611eac84823560208401612c8b565b60008151808452612fe8816020860160208601613239565b601f01601f19169290920160200192915050565b6000825161300e818460208701613239565b9190910192915050565b6000835161302a818460208801613239565b83519083019061303e818360208801613239565b01949350505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061307a90830184612fd0565b9695505050505050565b602081526000610c426020830184612fd0565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252601d908201527f5374617274696e6720696e64657820697320616c726561647920736574000000604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b604051601f8201601f1916810167ffffffffffffffff811182821017156131cf576131cf613327565b604052919050565b600082198211156131ea576131ea6132cf565b500190565b6000826131fe576131fe6132e5565b500490565b600081600019048311821515161561321d5761321d6132cf565b500290565b600082821015613234576132346132cf565b500390565b60005b8381101561325457818101518382015260200161323c565b8381111561195e5750506000910152565b600181811c9082168061327957607f821691505b6020821081141561329a57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156132b4576132b46132cf565b5060010190565b6000826132ca576132ca6132e5565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114610d1657600080fdfe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e697066733a2f2f516d584369324363373769576a666173746634647a6e6f675368646f63344574693674314c63376e376559427267a26469706673582212208ab3885420cedffd586d53f18ed32f6e711792642e1775ecf112939a30ee329a64736f6c63430008070033

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

00000000000000000000000000000000000000000000000000000000000000c8000000000000000000000000000000000000000000000000000000000000003200000000000000000000000000000000000000000000000000000000000000320000000000000000000000002f1daaabe3463ba5224386dcefb2c9d9024a9b3b

-----Decoded View---------------
Arg [0] : maxNFTSupply (uint256): 200
Arg [1] : _airdropSupply (uint256): 50
Arg [2] : _presaleSupply (uint256): 50
Arg [3] : fundReceiver (address): 0x2F1DAAaBe3463bA5224386DCEFB2c9D9024a9b3b

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000c8
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000032
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000032
Arg [3] : 0000000000000000000000002f1daaabe3463ba5224386dcefb2c9d9024a9b3b


Deployed Bytecode Sourcemap

67653:7624:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;10108:150;;;;;;;;;;-1:-1:-1;10108:150:0;;;;;:::i;:::-;-1:-1:-1;;;;;;10217:33:0;10193:4;10217:33;;;;;;;;;;;;;;10108:150;;;;7699:14:1;;7692:22;7674:41;;7662:2;7647:18;10108:150:0;;;;;;;;51335:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;54121:221::-;;;;;;;;;;-1:-1:-1;54121:221:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;6773:32:1;;;6755:51;;6743:2;6728:18;54121:221:0;6609:203:1;53651:404:0;;;;;;;;;;-1:-1:-1;53651:404:0;;;;;:::i;:::-;;:::i;:::-;;53129:211;;;;;;;;;;;;;:::i;:::-;;;7872:25:1;;;7860:2;7845:18;53129:211:0;7726:177:1;67817:39:0;;;;;;;;;;;;67855:1;67817:39;;68395:32;;;;;;;;;;-1:-1:-1;68395:32:0;;;;;;;;68476:34;;;;;;;;;;-1:-1:-1;68476:34:0;;;;;;;;;;;68187:38;;;;;;;;;;;;;;;;55011:305;;;;;;;;;;-1:-1:-1;55011:305:0;;;;;:::i;:::-;;:::i;74746:99::-;;;;;;;;;;;;;:::i;52891:162::-;;;;;;;;;;-1:-1:-1;52891:162:0;;;;;:::i;:::-;;:::i;74853:89::-;;;;;;;;;;;;;:::i;55387:151::-;;;;;;;;;;-1:-1:-1;55387:151:0;;;;;:::i;:::-;;:::i;75090:178::-;;;;;;;;;;-1:-1:-1;75090:178:0;;;;;:::i;:::-;;:::i;73743:240::-;;;;;;;;;;;;;:::i;53417:172::-;;;;;;;;;;-1:-1:-1;53417:172:0;;;;;:::i;:::-;;:::i;68034:25::-;;;;;;;;;;;;;;;;73590:99;;;;;;;;;;-1:-1:-1;73590:99:0;;;;;:::i;:::-;;:::i;68519:31::-;;;;;;;;;;-1:-1:-1;68519:31:0;;;;;;;-1:-1:-1;;;;;68519:31:0;;;51091:177;;;;;;;;;;-1:-1:-1;51091:177:0;;;;;:::i;:::-;;:::i;70747:1193::-;;;;;;:::i;:::-;;:::i;52710:97::-;;;;;;;;;;;;;:::i;68232:35::-;;;;;;;;;;;;;;;;67863:32;;;;;;;;;;;;;;;73991:240;;;;;;;;;;;;;:::i;50808:221::-;;;;;;;;;;-1:-1:-1;50808:221:0;;;;;:::i;:::-;;:::i;66029:148::-;;;;;;;;;;;;;:::i;73255:327::-;;;;;;;;;;-1:-1:-1;73255:327:0;;;;;:::i;:::-;;:::i;68654:95::-;;;;;;;;;;;;;;;;68434:35;;;;;;;;;;-1:-1:-1;68434:35:0;;;;;;;;;;;74239:228;;;;;;;;;;;;;:::i;68142:38::-;;;;;;;;;;;;;;;;65378:87;;;;;;;;;;-1:-1:-1;65451:6:0;;-1:-1:-1;;;;;65451:6:0;65378:87;;71974:1220;;;;;;:::i;:::-;;:::i;51504:104::-;;;;;;;;;;;;;:::i;54414:295::-;;;;;;;;;;-1:-1:-1;54414:295:0;;;;;:::i;:::-;;:::i;67759:41::-;;;;;;;;;;;;67794:6;67759:41;;67947:38;;;;;;;;;;;;;;;74563:108;;;;;;;;;;-1:-1:-1;74563:108:0;;;;;:::i;:::-;;:::i;55609:285::-;;;;;;;;;;-1:-1:-1;55609:285:0;;;;;:::i;:::-;;:::i;69136:1554::-;;;;;;;;;;-1:-1:-1;69136:1554:0;;;;;:::i;:::-;;:::i;68276:55::-;;;;;;;;;;-1:-1:-1;68276:55:0;;;;;:::i;:::-;;;;;;;;;;;;;;74475:80;;;;;;;;;;-1:-1:-1;74475:80:0;;;;;:::i;:::-;;:::i;68338:48::-;;;;;;;;;;-1:-1:-1;68338:48:0;;;;;:::i;:::-;;;;;;;;;;;;;;54780:164;;;;;;;;;;-1:-1:-1;54780:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;54901:25:0;;;54877:4;54901:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;54780:164;68559:88;;;;;;;;;;;;;;;;66332:244;;;;;;;;;;-1:-1:-1;66332:244:0;;;;;:::i;:::-;;:::i;67992:35::-;;;;;;;;;;;;;;;74960:97;;;;;;;;;;;;;:::i;67902:38::-;;;;;;;;;;;;;;;51335:100;51389:13;51422:5;51415:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51335:100;:::o;54121:221::-;54197:7;54225:16;54233:7;54225;:16::i;:::-;54217:73;;;;-1:-1:-1;;;54217:73:0;;16521:2:1;54217:73:0;;;16503:21:1;16560:2;16540:18;;;16533:30;16599:34;16579:18;;;16572:62;-1:-1:-1;;;16650:18:1;;;16643:42;16702:19;;54217:73:0;;;;;;;;;-1:-1:-1;54310:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;54310:24:0;;54121:221::o;53651:404::-;53732:13;53748:23;53763:7;53748:14;:23::i;:::-;53732:39;;53796:5;-1:-1:-1;;;;;53790:11:0;:2;-1:-1:-1;;;;;53790:11:0;;;53782:57;;;;-1:-1:-1;;;53782:57:0;;18526:2:1;53782:57:0;;;18508:21:1;18565:2;18545:18;;;18538:30;18604:34;18584:18;;;18577:62;-1:-1:-1;;;18655:18:1;;;18648:31;18696:19;;53782:57:0;18324:397:1;53782:57:0;685:10;-1:-1:-1;;;;;53860:21:0;;;;:69;;-1:-1:-1;53885:44:0;53909:5;685:10;54780:164;:::i;53885:44::-;53852:161;;;;-1:-1:-1;;;53852:161:0;;14158:2:1;53852:161:0;;;14140:21:1;14197:2;14177:18;;;14170:30;14236:34;14216:18;;;14209:62;14307:26;14287:18;;;14280:54;14351:19;;53852:161:0;13956:420:1;53852:161:0;54026:21;54035:2;54039:7;54026:8;:21::i;:::-;53721:334;53651:404;;:::o;53129:211::-;53190:7;53311:21;:12;:19;:21::i;:::-;53304:28;;53129:211;:::o;55011:305::-;55172:41;685:10;55205:7;55172:18;:41::i;:::-;55164:103;;;;-1:-1:-1;;;55164:103:0;;;;;;;:::i;:::-;55280:28;55290:4;55296:2;55300:7;55280:9;:28::i;74746:99::-;65451:6;;-1:-1:-1;;;;;65451:6:0;685:10;65598:23;65590:68;;;;-1:-1:-1;;;65590:68:0;;;;;;;:::i;:::-;74823:14:::1;::::0;;-1:-1:-1;;74805:32:0;::::1;74823:14:::0;;;;::::1;;;74822:15;74805:32:::0;;::::1;;::::0;;74746:99::o;52891:162::-;-1:-1:-1;;;;;53015:20:0;;52988:7;53015:20;;;:13;:20;;;;;:30;;53039:5;53015:23;:30::i;:::-;53008:37;;52891:162;;;;;:::o;74853:89::-;65451:6;;-1:-1:-1;;;;;65451:6:0;685:10;65598:23;65590:68;;;;-1:-1:-1;;;65590:68:0;;;;;;;:::i;:::-;74922:12:::1;::::0;;-1:-1:-1;;74906:28:0;::::1;74922:12;::::0;;::::1;74921:13;74906:28;::::0;;74853:89::o;55387:151::-;55491:39;55508:4;55514:2;55518:7;55491:39;;;;;;;;;;;;:16;:39::i;75090:178::-;75149:39;75168:10;75180:7;75149:18;:39::i;:::-;75141:94;;;;-1:-1:-1;;;75141:94:0;;13747:2:1;75141:94:0;;;13729:21:1;13786:2;13766:18;;;13759:30;13825:34;13805:18;;;13798:62;-1:-1:-1;;;13876:18:1;;;13869:40;13926:19;;75141:94:0;13545:406:1;75141:94:0;75246:14;75252:7;75246:5;:14::i;:::-;75090:178;:::o;73743:240::-;65451:6;;-1:-1:-1;;;;;65451:6:0;685:10;65598:23;65590:68;;;;-1:-1:-1;;;65590:68:0;;;;;;;:::i;:::-;73817:23:::1;::::0;:28;73809:70:::1;;;;-1:-1:-1::0;;;73809:70:0::1;;;;;;;:::i;:::-;73962:13;73941:16;73956:1;73941:12;:16;:::i;:::-;73926:49;::::0;;73931:27:::1;73926:49;:::i;:::-;73900:23;:75:::0;73743:240::o;53417:172::-;53492:7;;53534:22;:12;53550:5;53534:15;:22::i;:::-;-1:-1:-1;53512:44:0;53417:172;-1:-1:-1;;;53417:172:0:o;73590:99::-;65451:6;;-1:-1:-1;;;;;65451:6:0;685:10;65598:23;65590:68;;;;-1:-1:-1;;;65590:68:0;;;;;;;:::i;:::-;73661:20:::1;73673:7;73661:11;:20::i;51091:177::-:0;51163:7;51190:70;51207:7;51190:70;;;;;;;;;;;;;;;;;:12;;:70;:16;:70::i;70747:1193::-;70895:10;;70971:12;;;;70963:56;;;;-1:-1:-1;;;70963:56:0;;9093:2:1;70963:56:0;;;9075:21:1;9132:2;9112:18;;;9105:30;9171:33;9151:18;;;9144:61;9222:18;;70963:56:0;8891:355:1;70963:56:0;71070:7;71038:28;71052:14;71038:11;:28;:::i;:::-;:39;;71030:88;;;;-1:-1:-1;;;71030:88:0;;17295:2:1;71030:88:0;;;17277:21:1;17334:2;17314:18;;;17307:30;17373:34;17353:18;;;17346:62;-1:-1:-1;;;17424:18:1;;;17417:34;17468:19;;71030:88:0;17093:400:1;71030:88:0;71169:9;71137:28;67794:6;71150:14;71137:12;:28::i;:::-;:41;;71129:85;;;;-1:-1:-1;;;71129:85:0;;11806:2:1;71129:85:0;;;11788:21:1;11845:2;11825:18;;;11818:30;11884:33;11864:18;;;11857:61;11935:18;;71129:85:0;11604:355:1;71129:85:0;71230:14;;;;;;;71225:378;;67855:1;71269:14;:32;;71261:77;;;;-1:-1:-1;;;71261:77:0;;14994:2:1;71261:77:0;;;14976:21:1;;;15013:18;;;15006:30;15072:34;15052:18;;;15045:62;15124:18;;71261:77:0;14792:356:1;71261:77:0;-1:-1:-1;;;;;71361:17:0;;;;;;:13;:17;;;;;;67855:1;;71361:34;;71381:14;;71361:34;:::i;:::-;:52;;71353:119;;;;-1:-1:-1;;;71353:119:0;;19704:2:1;71353:119:0;;;19686:21:1;19743:2;19723:18;;;19716:30;19782:34;19762:18;;;19755:62;-1:-1:-1;;;19833:18:1;;;19826:52;19895:19;;71353:119:0;19502:418:1;71353:119:0;71521:4;;71537:20;;-1:-1:-1;;5518:2:1;5514:15;;;5510:53;71537:20:0;;;5498:66:1;71495:64:0;;71514:5;;5580:12:1;;71537:20:0;;;;;;;;;;;;;71527:31;;;;;;71495:18;:64::i;:::-;71487:104;;;;-1:-1:-1;;;71487:104:0;;8334:2:1;71487:104:0;;;8316:21:1;8373:2;8353:18;;;8346:30;8412:29;8392:18;;;8385:57;8459:18;;71487:104:0;8132:351:1;71487:104:0;71712:8;;:28;;-1:-1:-1;;;;;71712:8:0;;;;;;;;;71730:9;71712:28;;;;;;;;;71730:9;71712:8;:28;;;;;;;;;;;;;;;;;;;;-1:-1:-1;71774:1:0;71761:133;71782:14;71777:1;:19;71761:133;;-1:-1:-1;;;;;71818:17:0;;;;;;:13;:17;;;;;:19;;;;;;:::i;:::-;;;;-1:-1:-1;71852:30:0;;-1:-1:-1;71862:2:0;71866:15;71880:1;71866:11;:15;:::i;:::-;71852:9;:30::i;:::-;71798:3;;;;:::i;:::-;;;;71761:133;;;;71918:14;71904:10;;:28;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;70747:1193:0:o;52710:97::-;52758:13;52791:8;52784:15;;;;;:::i;73991:240::-;65451:6;;-1:-1:-1;;;;;65451:6:0;685:10;65598:23;65590:68;;;;-1:-1:-1;;;65590:68:0;;;;;;;:::i;:::-;74065:23:::1;::::0;:28;74057:70:::1;;;;-1:-1:-1::0;;;74057:70:0::1;;;;;;;:::i;:::-;74210:13;74189:16;74204:1;74189:12;:16;:::i;:::-;74174:49;::::0;;74179:27:::1;74174:49;:::i;:::-;74148:23;:75:::0;73991:240::o;50808:221::-;50880:7;-1:-1:-1;;;;;50908:19:0;;50900:74;;;;-1:-1:-1;;;50900:74:0;;14583:2:1;50900:74:0;;;14565:21:1;14622:2;14602:18;;;14595:30;14661:34;14641:18;;;14634:62;-1:-1:-1;;;14712:18:1;;;14705:40;14762:19;;50900:74:0;14381:406:1;50900:74:0;-1:-1:-1;;;;;50992:20:0;;;;;;:13;:20;;;;;:29;;:27;:29::i;66029:148::-;65451:6;;-1:-1:-1;;;;;65451:6:0;685:10;65598:23;65590:68;;;;-1:-1:-1;;;65590:68:0;;;;;;;:::i;:::-;66120:6:::1;::::0;66099:40:::1;::::0;66136:1:::1;::::0;-1:-1:-1;;;;;66120:6:0::1;::::0;66099:40:::1;::::0;66136:1;;66099:40:::1;66150:6;:19:::0;;-1:-1:-1;;;;;;66150:19:0::1;::::0;;66029:148::o;73255:327::-;65451:6;;-1:-1:-1;;;;;65451:6:0;685:10;65598:23;65590:68;;;;-1:-1:-1;;;65590:68:0;;;;;;;:::i;:::-;73360:13:::1;73346:10;;73329:14;:27;;;;:::i;:::-;:44;;73321:96;;;::::0;-1:-1:-1;;;73321:96:0;;20539:2:1;73321:96:0::1;::::0;::::1;20521:21:1::0;20578:2;20558:18;;;20551:30;20617:34;20597:18;;;20590:62;-1:-1:-1;;;20668:18:1;;;20661:37;20715:19;;73321:96:0::1;20337:403:1::0;73321:96:0::1;73443:1;73430:106;73451:14;73446:1;:19;73430:106;;73487:37;73497:10;73522:1;73509:10;;:14;;;;:::i;73487:37::-;73467:3:::0;::::1;::::0;::::1;:::i;:::-;;;;73430:106;;;;73560:14;73546:10;;:28;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;;73255:327:0:o;74239:228::-;65451:6;;-1:-1:-1;;;;;65451:6:0;685:10;65598:23;65590:68;;;;-1:-1:-1;;;65590:68:0;;;;;;;:::i;:::-;74310:20:::1;::::0;:25;74302:67:::1;;;;-1:-1:-1::0;;;74302:67:0::1;;;;;;;:::i;:::-;74449:10;74428:16;74443:1;74428:12;:16;:::i;:::-;74413:46;::::0;;74418:27:::1;74413:46;:::i;:::-;74390:20;:69:::0;74239:228::o;71974:1220::-;72129:10;;72205:15;;;;;;;72197:62;;;;-1:-1:-1;;;72197:62:0;;13344:2:1;72197:62:0;;;13326:21:1;13383:2;13363:18;;;13356:30;13422:34;13402:18;;;13395:62;-1:-1:-1;;;13473:18:1;;;13466:32;13515:19;;72197:62:0;13142:398:1;72197:62:0;67855:1;72278:14;:32;;72270:77;;;;-1:-1:-1;;;72270:77:0;;14994:2:1;72270:77:0;;;14976:21:1;;;15013:18;;;15006:30;15072:34;15052:18;;;15045:62;15124:18;;72270:77:0;14792:356:1;72270:77:0;72401:29;72417:13;72401;:29;:::i;:::-;72367:28;72381:14;72367:11;:28;:::i;:::-;72366:65;;72358:121;;;;-1:-1:-1;;;72358:121:0;;20127:2:1;72358:121:0;;;20109:21:1;20166:2;20146:18;;;20139:30;20205:34;20185:18;;;20178:62;-1:-1:-1;;;20256:18:1;;;20249:41;20307:19;;72358:121:0;19925:407:1;72358:121:0;72530:9;72498:28;67794:6;72511:14;72498:12;:28::i;:::-;:41;;72490:85;;;;-1:-1:-1;;;72490:85:0;;11806:2:1;72490:85:0;;;11788:21:1;11845:2;11825:18;;;11818:30;11884:33;11864:18;;;11857:61;11935:18;;72490:85:0;11604:355:1;72490:85:0;-1:-1:-1;;;;;72594:24:0;;;;;;:20;:24;;;;;;67855:1;;72594:41;;72621:14;;72594:41;:::i;:::-;:59;;72586:126;;;;-1:-1:-1;;;72586:126:0;;20947:2:1;72586:126:0;;;20929:21:1;20986:2;20966:18;;;20959:30;21025:34;21005:18;;;20998:62;-1:-1:-1;;;21076:18:1;;;21069:52;21138:19;;72586:126:0;20745:418:1;72586:126:0;72757:11;;72780:20;;-1:-1:-1;;5518:2:1;5514:15;;;5510:53;72780:20:0;;;5498:66:1;72731:71:0;;72750:5;;5580:12:1;;72780:20:0;5369:229:1;72731:71:0;72723:126;;;;-1:-1:-1;;;72723:126:0;;10636:2:1;72723:126:0;;;10618:21:1;10675:2;10655:18;;;10648:30;10714:34;10694:18;;;10687:62;-1:-1:-1;;;10765:18:1;;;10758:40;10815:19;;72723:126:0;10434:406:1;72723:126:0;72959:8;;:28;;-1:-1:-1;;;;;72959:8:0;;;;;;;;;72977:9;72959:28;;;;;;;;;72977:9;72959:8;:28;;;;;;;;;;;;;;;;;;;;-1:-1:-1;73021:1:0;73008:140;73029:14;73024:1;:19;73008:140;;-1:-1:-1;;;;;73065:24:0;;;;;;:20;:24;;;;;:26;;;;;;:::i;:::-;;;;-1:-1:-1;73106:30:0;;-1:-1:-1;73116:2:0;73120:15;73134:1;73120:11;:15;:::i;73106:30::-;73045:3;;;;:::i;:::-;;;;73008:140;;51504:104;51560:13;51593:7;51586:14;;;;;:::i;54414:295::-;-1:-1:-1;;;;;54517:24:0;;685:10;54517:24;;54509:62;;;;-1:-1:-1;;;54509:62:0;;11452:2:1;54509:62:0;;;11434:21:1;11491:2;11471:18;;;11464:30;11530:27;11510:18;;;11503:55;11575:18;;54509:62:0;11250:349:1;54509:62:0;685:10;54584:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;54584:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;54584:53:0;;;;;;;;;;54653:48;;7674:41:1;;;54584:42:0;;685:10;54653:48;;7647:18:1;54653:48:0;;;;;;;54414:295;;:::o;74563:108::-;65451:6;;-1:-1:-1;;;;;65451:6:0;685:10;65598:23;65590:68;;;;-1:-1:-1;;;65590:68:0;;;;;;;:::i;:::-;74637:11:::1;:26:::0;74563:108::o;55609:285::-;55741:41;685:10;55774:7;55741:18;:41::i;:::-;55733:103;;;;-1:-1:-1;;;55733:103:0;;;;;;;:::i;:::-;55847:39;55861:4;55867:2;55871:7;55880:5;55847:13;:39::i;:::-;55609:285;;;;:::o;69136:1554::-;69209:13;69243:16;69251:7;69243;:16::i;:::-;69235:76;;;;-1:-1:-1;;;69235:76:0;;18110:2:1;69235:76:0;;;18092:21:1;18149:2;18129:18;;;18122:30;18188:34;18168:18;;;18161:62;-1:-1:-1;;;18239:18:1;;;18232:45;18294:19;;69235:76:0;17908:411:1;69235:76:0;69324:18;69345:9;:7;:9::i;:::-;69324:30;;69365:25;:83;;;;;;;;;;;;;;;;;;-1:-1:-1;69459:29:0;69491;69507:13;69491;:29;:::i;:::-;69459:61;;69592:23;;69619:1;69592:28;;:56;;;;;69635:13;69624:7;:24;;69592:56;69588:298;;;69665:11;69689:23;;69679:7;:33;;;;:::i;:::-;69665:47;;69737:13;69731:3;:19;69727:80;;;69771:20;69778:13;69771:20;;:::i;:::-;;;69727:80;69852:4;69858:14;:3;:12;:14::i;:::-;69835:38;;;;;;;;;:::i;:::-;;;;;;;;;;;;;69821:53;;;;;;69136:1554;;;:::o;69588:298::-;69961:23;;:27;;;;:63;;;70003:21;69992:7;:32;;69961:63;69957:313;;;70041:11;70065:23;;70055:7;:33;;;;:::i;:::-;70041:47;;70113:21;70107:3;:27;70103:88;;;70155:20;70162:13;70155:20;;:::i;69957:313::-;70346:20;;:25;70342:255;;70388:11;70412:20;;70402:7;:30;;;;:::i;:::-;70388:44;;70457:7;70451:3;:13;70447:71;;;70485:17;70492:10;70485:17;;:::i;74475:80::-;65451:6;;-1:-1:-1;;;;;65451:6:0;685:10;65598:23;65590:68;;;;-1:-1:-1;;;65590:68:0;;;;;;;:::i;:::-;74535:4:::1;:12:::0;74475:80::o;66332:244::-;65451:6;;-1:-1:-1;;;;;65451:6:0;685:10;65598:23;65590:68;;;;-1:-1:-1;;;65590:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;66421:22:0;::::1;66413:73;;;::::0;-1:-1:-1;;;66413:73:0;;9872:2:1;66413:73:0::1;::::0;::::1;9854:21:1::0;9911:2;9891:18;;;9884:30;9950:34;9930:18;;;9923:62;-1:-1:-1;;;10001:18:1;;;9994:36;10047:19;;66413:73:0::1;9670:402:1::0;66413:73:0::1;66523:6;::::0;66502:38:::1;::::0;-1:-1:-1;;;;;66502:38:0;;::::1;::::0;66523:6:::1;::::0;66502:38:::1;::::0;66523:6:::1;::::0;66502:38:::1;66551:6;:17:::0;;-1:-1:-1;;;;;;66551:17:0::1;-1:-1:-1::0;;;;;66551:17:0;;;::::1;::::0;;;::::1;::::0;;66332:244::o;74960:97::-;65451:6;;-1:-1:-1;;;;;65451:6:0;685:10;65598:23;65590:68;;;;-1:-1:-1;;;65590:68:0;;;;;;;:::i;:::-;75034:15:::1;::::0;;-1:-1:-1;;75015:34:0;::::1;75034:15;::::0;;;::::1;;;75033:16;75015:34:::0;;::::1;;::::0;;74960:97::o;57361:127::-;57426:4;57450:30;:12;57472:7;57450:21;:30::i;63379:192::-;63454:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;63454:29:0;-1:-1:-1;;;;;63454:29:0;;;;;;;;:24;;63508:23;63454:24;63508:14;:23::i;:::-;-1:-1:-1;;;;;63499:46:0;;;;;;;;;;;63379:192;;:::o;44120:123::-;44189:7;44216:19;44224:3;40782:19;;40699:110;57655:355;57748:4;57773:16;57781:7;57773;:16::i;:::-;57765:73;;;;-1:-1:-1;;;57765:73:0;;12573:2:1;57765:73:0;;;12555:21:1;12612:2;12592:18;;;12585:30;12651:34;12631:18;;;12624:62;-1:-1:-1;;;12702:18:1;;;12695:42;12754:19;;57765:73:0;12371:408:1;57765:73:0;57849:13;57865:23;57880:7;57865:14;:23::i;:::-;57849:39;;57918:5;-1:-1:-1;;;;;57907:16:0;:7;-1:-1:-1;;;;;57907:16:0;;:51;;;;57951:7;-1:-1:-1;;;;;57927:31:0;:20;57939:7;57927:11;:20::i;:::-;-1:-1:-1;;;;;57927:31:0;;57907:51;:94;;;-1:-1:-1;;;;;;54901:25:0;;;54877:4;54901:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;57962:39;57899:103;57655:355;-1:-1:-1;;;;57655:355:0:o;60791:599::-;60916:4;-1:-1:-1;;;;;60889:31:0;:23;60904:7;60889:14;:23::i;:::-;-1:-1:-1;;;;;60889:31:0;;60881:85;;;;-1:-1:-1;;;60881:85:0;;17700:2:1;60881:85:0;;;17682:21:1;17739:2;17719:18;;;17712:30;17778:34;17758:18;;;17751:62;-1:-1:-1;;;17829:18:1;;;17822:39;17878:19;;60881:85:0;17498:405:1;60881:85:0;-1:-1:-1;;;;;61003:16:0;;60995:65;;;;-1:-1:-1;;;60995:65:0;;11047:2:1;60995:65:0;;;11029:21:1;11086:2;11066:18;;;11059:30;11125:34;11105:18;;;11098:62;-1:-1:-1;;;11176:18:1;;;11169:34;11220:19;;60995:65:0;10845:400:1;60995:65:0;61177:29;61194:1;61198:7;61177:8;:29::i;:::-;-1:-1:-1;;;;;61219:19:0;;;;;;:13;:19;;;;;:35;;61246:7;61219:26;:35::i;:::-;-1:-1:-1;;;;;;61265:17:0;;;;;;:13;:17;;;;;:30;;61287:7;61265:21;:30::i;:::-;-1:-1:-1;61308:29:0;:12;61325:7;61334:2;61308:16;:29::i;:::-;;61374:7;61370:2;-1:-1:-1;;;;;61355:27:0;61364:4;-1:-1:-1;;;;;61355:27:0;;;;;;;;;;;60791:599;;;:::o;35919:137::-;35990:7;36025:22;36029:3;36041:5;36025:3;:22::i;59909:545::-;59969:13;59985:23;60000:7;59985:14;:23::i;:::-;59969:39;;60128:29;60145:1;60149:7;60128:8;:29::i;:::-;60216:19;;;;:10;:19;;;;;60210:33;;;;;:::i;:::-;:38;;-1:-1:-1;60206:97:0;;60272:19;;;;:10;:19;;;;;60265:26;;;:::i;:::-;-1:-1:-1;;;;;60315:20:0;;;;;;:13;:20;;;;;:36;;60343:7;60315:27;:36::i;:::-;-1:-1:-1;60364:28:0;:12;60384:7;60364:19;:28::i;:::-;-1:-1:-1;60410:36:0;;60438:7;;60434:1;;-1:-1:-1;;;;;60410:36:0;;;;;60434:1;;60410:36;59958:496;59909:545;:::o;44582:236::-;44662:7;;;;44722:22;44726:3;44738:5;44722:3;:22::i;:::-;44691:53;;;;-1:-1:-1;44582:236:0;-1:-1:-1;;;;;44582:236:0:o;61991:100::-;62064:19;;;;:8;;:19;;;;;:::i;:::-;;61991:100;:::o;45868:213::-;45975:7;46026:44;46031:3;46051;46057:12;46026:4;:44::i;:::-;46018:53;-1:-1:-1;45868:213:0;;;;;;:::o;14541:220::-;14599:7;14623:6;14619:20;;-1:-1:-1;14638:1:0;14631:8;;14619:20;14650:9;14662:5;14666:1;14662;:5;:::i;:::-;14650:17;-1:-1:-1;14695:1:0;14686:5;14690:1;14650:17;14686:5;:::i;:::-;:10;14678:56;;;;-1:-1:-1;;;14678:56:0;;16119:2:1;14678:56:0;;;16101:21:1;16158:2;16138:18;;;16131:30;16197:34;16177:18;;;16170:62;-1:-1:-1;;;16248:18:1;;;16241:31;16289:19;;14678:56:0;15917:397:1;66616:190:0;66741:4;66794;66765:25;66778:5;66785:4;66765:12;:25::i;:::-;:33;;66616:190;-1:-1:-1;;;;66616:190:0:o;58353:110::-;58429:26;58439:2;58443:7;58429:26;;;;;;;;;;;;:9;:26::i;56776:272::-;56890:28;56900:4;56906:2;56910:7;56890:9;:28::i;:::-;56937:48;56960:4;56966:2;56970:7;56979:5;56937:22;:48::i;:::-;56929:111;;;;-1:-1:-1;;;56929:111:0;;;;;;;:::i;46324:723::-;46380:13;46601:10;46597:53;;-1:-1:-1;;46628:10:0;;;;;;;;;;;;-1:-1:-1;;;46628:10:0;;;;;46324:723::o;46597:53::-;46675:5;46660:12;46716:78;46723:9;;46716:78;;46749:8;;;;:::i;:::-;;-1:-1:-1;46772:10:0;;-1:-1:-1;46780:2:0;46772:10;;:::i;:::-;;;46716:78;;;46804:19;46836:6;46826:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;46826:17:0;;46804:39;;46854:154;46861:10;;46854:154;;46888:11;46898:1;46888:11;;:::i;:::-;;-1:-1:-1;46957:10:0;46965:2;46957:5;:10;:::i;:::-;46944:24;;:2;:24;:::i;:::-;46931:39;;46914:6;46921;46914:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;46914:56:0;;;;;;;;-1:-1:-1;46985:11:0;46994:2;46985:11;;:::i;:::-;;;46854:154;;43881:151;43965:4;40574:17;;;:12;;;:17;;;;;;:22;;43989:35;40479:125;35006:137;35076:4;35100:35;35108:3;35128:5;35100:7;:35::i;34699:131::-;34766:4;34790:32;34795:3;34815:5;34790:4;:32::i;43304:185::-;43393:4;43417:64;43422:3;43442;-1:-1:-1;;;;;43456:23:0;;43417:4;:64::i;30957:204::-;31052:18;;31024:7;;31052:26;-1:-1:-1;31044:73:0;;;;-1:-1:-1;;;31044:73:0;;8690:2:1;31044:73:0;;;8672:21:1;8729:2;8709:18;;;8702:30;8768:34;8748:18;;;8741:62;-1:-1:-1;;;8819:18:1;;;8812:32;8861:19;;31044:73:0;8488:398:1;31044:73:0;31135:3;:11;;31147:5;31135:18;;;;;;;;:::i;:::-;;;;;;;;;31128:25;;30957:204;;;;:::o;43655:142::-;43732:4;43756:33;43764:3;43784;43756:7;:33::i;41164:279::-;41268:19;;41231:7;;;;41268:27;-1:-1:-1;41260:74:0;;;;-1:-1:-1;;;41260:74:0;;15355:2:1;41260:74:0;;;15337:21:1;15394:2;15374:18;;;15367:30;15433:34;15413:18;;;15406:62;-1:-1:-1;;;15484:18:1;;;15477:32;15526:19;;41260:74:0;15153:398:1;41260:74:0;41347:22;41372:3;:12;;41385:5;41372:19;;;;;;;;:::i;:::-;;;;;;;;;;;41347:44;;41410:5;:10;;;41422:5;:12;;;41402:33;;;;;41164:279;;;;;:::o;42661:319::-;42755:7;42794:17;;;:12;;;:17;;;;;;42845:12;42830:13;42822:36;;;;-1:-1:-1;;;42822:36:0;;;;;;;;:::i;:::-;-1:-1:-1;42912:3:0;42925:12;42936:1;42925:8;:12;:::i;:::-;42912:26;;;;;;;;:::i;:::-;;;;;;;;;;;:33;;;42905:40;;;42661:319;;;;;:::o;66820:701::-;66903:7;66946:4;66903:7;66961:523;66985:5;:12;66981:1;:16;66961:523;;;67019:20;67042:5;67048:1;67042:8;;;;;;;;:::i;:::-;;;;;;;67019:31;;67085:12;67069;:28;67065:408;;67222:44;;;;;;5760:19:1;;;5795:12;;;5788:28;;;5832:12;;67222:44:0;;;;;;;;;;;;67212:55;;;;;;67197:70;;67065:408;;;67412:44;;;;;;5760:19:1;;;5795:12;;;5788:28;;;5832:12;;67412:44:0;;;;;;;;;;;;67402:55;;;;;;67387:70;;67065:408;-1:-1:-1;66999:3:0;;;;:::i;:::-;;;;66961:523;;58690:250;58786:18;58792:2;58796:7;58786:5;:18::i;:::-;58823:54;58854:1;58858:2;58862:7;58871:5;58823:22;:54::i;:::-;58815:117;;;;-1:-1:-1;;;58815:117:0;;;;;;;:::i;62656:604::-;62777:4;-1:-1:-1;;;;;62804:13:0;;19463:20;62799:60;;-1:-1:-1;62843:4:0;62836:11;;62799:60;62869:23;62895:252;-1:-1:-1;;;685:10:0;63035:4;63054:7;63076:5;62911:181;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;-1:-1:-1;;;;;62911:181:0;;;;;;;-1:-1:-1;;;;;62911:181:0;;;;;;;;;;;62895:252;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;62895:15:0;;;:252;:15;:252::i;:::-;62869:278;;63158:13;63185:10;63174:32;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;63225:26:0;-1:-1:-1;;;63225:26:0;;-1:-1:-1;;;62656:604:0;;;;;;:::o;28659:1544::-;28725:4;28864:19;;;:12;;;:19;;;;;;28900:15;;28896:1300;;29262:21;29286:14;29299:1;29286:10;:14;:::i;:::-;29335:18;;29262:38;;-1:-1:-1;29315:17:0;;29335:22;;29356:1;;29335:22;:::i;:::-;29315:42;;29602:17;29622:3;:11;;29634:9;29622:22;;;;;;;;:::i;:::-;;;;;;;;;29602:42;;29768:9;29739:3;:11;;29751:13;29739:26;;;;;;;;:::i;:::-;;;;;;;;;;:38;29871:17;:13;29887:1;29871:17;:::i;:::-;29845:23;;;;:12;;;:23;;;;;:43;29997:17;;29845:3;;29997:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;30092:3;:12;;:19;30105:5;30092:19;;;;;;;;;;;30085:26;;;30135:4;30128:11;;;;;;;;28896:1300;30179:5;30172:12;;;;;28069:414;28132:4;40574:17;;;:12;;;:17;;;;;;28149:327;;-1:-1:-1;28192:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;28375:18;;28353:19;;;:12;;;:19;;;;;;:40;;;;28408:11;;28149:327;-1:-1:-1;28459:5:0;28452:12;;37979:692;38055:4;38190:17;;;:12;;;:17;;;;;;38224:13;38220:444;;-1:-1:-1;;38309:38:0;;;;;;;;;;;;;;;;;;38291:57;;;;;;;;:12;:57;;;;;;;;;;;;;;;;;;;;;;;;38506:19;;38486:17;;;:12;;;:17;;;;;;;:39;38540:11;;38220:444;38620:5;38584:3;38597:12;38608:1;38597:8;:12;:::i;:::-;38584:26;;;;;;;;:::i;:::-;;;;;;;;;;;:33;;:41;;;;38647:5;38640:12;;;;;38846:1549;38910:4;39045:17;;;:12;;;:17;;;;;;39079:13;;39075:1313;;39440:21;39464:12;39475:1;39464:8;:12;:::i;:::-;39511:19;;39440:36;;-1:-1:-1;39491:17:0;;39511:23;;39533:1;;39511:23;:::i;:::-;39491:43;;39779:26;39808:3;:12;;39821:9;39808:23;;;;;;;;:::i;:::-;;;;;;;;;;;39779:52;;39956:9;39926:3;:12;;39939:13;39926:27;;;;;;;;:::i;:::-;;;;;;;;;:39;;:27;;;;;:39;;;;;;;;;;;;40064:17;;:13;;:17;:::i;:::-;40046:14;;40033:28;;;;:12;;;:28;;;;;:48;40190:18;;40033:3;;40190:18;;;;;:::i;:::-;;;;;;;;;;-1:-1:-1;;40190:18:0;;;;;;;;;;;;;;;;;;;;;40286:17;;;:12;;;:17;;;;;;40279:24;;;;40190:18;-1:-1:-1;40320:11:0;;-1:-1:-1;;;;40320:11:0;59276:404;-1:-1:-1;;;;;59356:16:0;;59348:61;;;;-1:-1:-1;;;59348:61:0;;15758:2:1;59348:61:0;;;15740:21:1;;;15777:18;;;15770:30;15836:34;15816:18;;;15809:62;15888:18;;59348:61:0;15556:356:1;59348:61:0;59429:16;59437:7;59429;:16::i;:::-;59428:17;59420:58;;;;-1:-1:-1;;;59420:58:0;;10279:2:1;59420:58:0;;;10261:21:1;10318:2;10298:18;;;10291:30;10357;10337:18;;;10330:58;10405:18;;59420:58:0;10077:352:1;59420:58:0;-1:-1:-1;;;;;59549:17:0;;;;;;:13;:17;;;;;:30;;59571:7;59549:21;:30::i;:::-;-1:-1:-1;59592:29:0;:12;59609:7;59618:2;59592:16;:29::i;:::-;-1:-1:-1;59639:33:0;;59664:7;;-1:-1:-1;;;;;59639:33:0;;;59656:1;;59639:33;;59656:1;;59639:33;59276:404;;:::o;22014:195::-;22117:12;22149:52;22171:6;22179:4;22185:1;22188:12;22117;19463:20;;23310:60;;;;-1:-1:-1;;;23310:60:0;;19346:2:1;23310:60:0;;;19328:21:1;19385:2;19365:18;;;19358:30;19424:31;19404:18;;;19397:59;19473:18;;23310:60:0;19144:353:1;23310:60:0;23444:12;23458:23;23485:6;-1:-1:-1;;;;;23485:11:0;23505:5;23513:4;23485:33;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23443:75;;;;23536:52;23554:7;23563:10;23575:12;23536:17;:52::i;:::-;23529:59;23066:530;-1:-1:-1;;;;;;;23066:530:0:o;25606:742::-;25721:12;25750:7;25746:595;;;-1:-1:-1;25781:10:0;25774:17;;25746:595;25895:17;;:21;25891:439;;26158:10;26152:17;26219:15;26206:10;26202:2;26198:19;26191:44;25891:439;26301:12;26294:20;;-1:-1:-1;;;26294:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:406:1;78:5;112:18;104:6;101:30;98:56;;;134:18;;:::i;:::-;172:57;217:2;196:15;;-1:-1:-1;;192:29:1;223:4;188:40;172:57;:::i;:::-;163:66;;252:6;245:5;238:21;292:3;283:6;278:3;274:16;271:25;268:45;;;309:1;306;299:12;268:45;358:6;353:3;346:4;339:5;335:16;322:43;412:1;405:4;396:6;389:5;385:18;381:29;374:40;14:406;;;;;:::o;425:173::-;493:20;;-1:-1:-1;;;;;542:31:1;;532:42;;522:70;;588:1;585;578:12;522:70;425:173;;;:::o;603:186::-;662:6;715:2;703:9;694:7;690:23;686:32;683:52;;;731:1;728;721:12;683:52;754:29;773:9;754:29;:::i;794:260::-;862:6;870;923:2;911:9;902:7;898:23;894:32;891:52;;;939:1;936;929:12;891:52;962:29;981:9;962:29;:::i;:::-;952:39;;1010:38;1044:2;1033:9;1029:18;1010:38;:::i;:::-;1000:48;;794:260;;;;;:::o;1059:328::-;1136:6;1144;1152;1205:2;1193:9;1184:7;1180:23;1176:32;1173:52;;;1221:1;1218;1211:12;1173:52;1244:29;1263:9;1244:29;:::i;:::-;1234:39;;1292:38;1326:2;1315:9;1311:18;1292:38;:::i;:::-;1282:48;;1377:2;1366:9;1362:18;1349:32;1339:42;;1059:328;;;;;:::o;1392:666::-;1487:6;1495;1503;1511;1564:3;1552:9;1543:7;1539:23;1535:33;1532:53;;;1581:1;1578;1571:12;1532:53;1604:29;1623:9;1604:29;:::i;:::-;1594:39;;1652:38;1686:2;1675:9;1671:18;1652:38;:::i;:::-;1642:48;;1737:2;1726:9;1722:18;1709:32;1699:42;;1792:2;1781:9;1777:18;1764:32;1819:18;1811:6;1808:30;1805:50;;;1851:1;1848;1841:12;1805:50;1874:22;;1927:4;1919:13;;1915:27;-1:-1:-1;1905:55:1;;1956:1;1953;1946:12;1905:55;1979:73;2044:7;2039:2;2026:16;2021:2;2017;2013:11;1979:73;:::i;:::-;1969:83;;;1392:666;;;;;;;:::o;2063:347::-;2128:6;2136;2189:2;2177:9;2168:7;2164:23;2160:32;2157:52;;;2205:1;2202;2195:12;2157:52;2228:29;2247:9;2228:29;:::i;:::-;2218:39;;2307:2;2296:9;2292:18;2279:32;2354:5;2347:13;2340:21;2333:5;2330:32;2320:60;;2376:1;2373;2366:12;2320:60;2399:5;2389:15;;;2063:347;;;;;:::o;2415:254::-;2483:6;2491;2544:2;2532:9;2523:7;2519:23;2515:32;2512:52;;;2560:1;2557;2550:12;2512:52;2583:29;2602:9;2583:29;:::i;:::-;2573:39;2659:2;2644:18;;;;2631:32;;-1:-1:-1;;;2415:254:1:o;2674:1099::-;2776:6;2784;2792;2845:2;2833:9;2824:7;2820:23;2816:32;2813:52;;;2861:1;2858;2851:12;2813:52;2884:29;2903:9;2884:29;:::i;:::-;2874:39;;2932:2;2981;2970:9;2966:18;2953:32;2943:42;;3036:2;3025:9;3021:18;3008:32;3059:18;3100:2;3092:6;3089:14;3086:34;;;3116:1;3113;3106:12;3086:34;3154:6;3143:9;3139:22;3129:32;;3199:7;3192:4;3188:2;3184:13;3180:27;3170:55;;3221:1;3218;3211:12;3170:55;3257:2;3244:16;3279:2;3275;3272:10;3269:36;;;3285:18;;:::i;:::-;3331:2;3328:1;3324:10;3314:20;;3354:28;3378:2;3374;3370:11;3354:28;:::i;:::-;3416:15;;;3447:12;;;;3479:11;;;3509;;;3505:20;;3502:33;-1:-1:-1;3499:53:1;;;3548:1;3545;3538:12;3499:53;3570:1;3561:10;;3580:163;3594:2;3591:1;3588:9;3580:163;;;3651:17;;3639:30;;3612:1;3605:9;;;;;3689:12;;;;3721;;3580:163;;;3584:3;3762:5;3752:15;;;;;;;;2674:1099;;;;;:::o;3778:180::-;3837:6;3890:2;3878:9;3869:7;3865:23;3861:32;3858:52;;;3906:1;3903;3896:12;3858:52;-1:-1:-1;3929:23:1;;3778:180;-1:-1:-1;3778:180:1:o;3963:245::-;4021:6;4074:2;4062:9;4053:7;4049:23;4045:32;4042:52;;;4090:1;4087;4080:12;4042:52;4129:9;4116:23;4148:30;4172:5;4148:30;:::i;4213:249::-;4282:6;4335:2;4323:9;4314:7;4310:23;4306:32;4303:52;;;4351:1;4348;4341:12;4303:52;4383:9;4377:16;4402:30;4426:5;4402:30;:::i;4467:450::-;4536:6;4589:2;4577:9;4568:7;4564:23;4560:32;4557:52;;;4605:1;4602;4595:12;4557:52;4645:9;4632:23;4678:18;4670:6;4667:30;4664:50;;;4710:1;4707;4700:12;4664:50;4733:22;;4786:4;4778:13;;4774:27;-1:-1:-1;4764:55:1;;4815:1;4812;4805:12;4764:55;4838:73;4903:7;4898:2;4885:16;4880:2;4876;4872:11;4838:73;:::i;5107:257::-;5148:3;5186:5;5180:12;5213:6;5208:3;5201:19;5229:63;5285:6;5278:4;5273:3;5269:14;5262:4;5255:5;5251:16;5229:63;:::i;:::-;5346:2;5325:15;-1:-1:-1;;5321:29:1;5312:39;;;;5353:4;5308:50;;5107:257;-1:-1:-1;;5107:257:1:o;5855:274::-;5984:3;6022:6;6016:13;6038:53;6084:6;6079:3;6072:4;6064:6;6060:17;6038:53;:::i;:::-;6107:16;;;;;5855:274;-1:-1:-1;;5855:274:1:o;6134:470::-;6313:3;6351:6;6345:13;6367:53;6413:6;6408:3;6401:4;6393:6;6389:17;6367:53;:::i;:::-;6483:13;;6442:16;;;;6505:57;6483:13;6442:16;6539:4;6527:17;;6505:57;:::i;:::-;6578:20;;6134:470;-1:-1:-1;;;;6134:470:1:o;7041:488::-;-1:-1:-1;;;;;7310:15:1;;;7292:34;;7362:15;;7357:2;7342:18;;7335:43;7409:2;7394:18;;7387:34;;;7457:3;7452:2;7437:18;;7430:31;;;7235:4;;7478:45;;7503:19;;7495:6;7478:45;:::i;:::-;7470:53;7041:488;-1:-1:-1;;;;;;7041:488:1:o;7908:219::-;8057:2;8046:9;8039:21;8020:4;8077:44;8117:2;8106:9;8102:18;8094:6;8077:44;:::i;9251:414::-;9453:2;9435:21;;;9492:2;9472:18;;;9465:30;9531:34;9526:2;9511:18;;9504:62;-1:-1:-1;;;9597:2:1;9582:18;;9575:48;9655:3;9640:19;;9251:414::o;12784:353::-;12986:2;12968:21;;;13025:2;13005:18;;;12998:30;13064:31;13059:2;13044:18;;13037:59;13128:2;13113:18;;12784:353::o;16732:356::-;16934:2;16916:21;;;16953:18;;;16946:30;17012:34;17007:2;16992:18;;16985:62;17079:2;17064:18;;16732:356::o;18726:413::-;18928:2;18910:21;;;18967:2;18947:18;;;18940:30;19006:34;19001:2;18986:18;;18979:62;-1:-1:-1;;;19072:2:1;19057:18;;19050:47;19129:3;19114:19;;18726:413::o;21350:275::-;21421:2;21415:9;21486:2;21467:13;;-1:-1:-1;;21463:27:1;21451:40;;21521:18;21506:34;;21542:22;;;21503:62;21500:88;;;21568:18;;:::i;:::-;21604:2;21597:22;21350:275;;-1:-1:-1;21350:275:1:o;21630:128::-;21670:3;21701:1;21697:6;21694:1;21691:13;21688:39;;;21707:18;;:::i;:::-;-1:-1:-1;21743:9:1;;21630:128::o;21763:120::-;21803:1;21829;21819:35;;21834:18;;:::i;:::-;-1:-1:-1;21868:9:1;;21763:120::o;21888:168::-;21928:7;21994:1;21990;21986:6;21982:14;21979:1;21976:21;21971:1;21964:9;21957:17;21953:45;21950:71;;;22001:18;;:::i;:::-;-1:-1:-1;22041:9:1;;21888:168::o;22061:125::-;22101:4;22129:1;22126;22123:8;22120:34;;;22134:18;;:::i;:::-;-1:-1:-1;22171:9:1;;22061:125::o;22191:258::-;22263:1;22273:113;22287:6;22284:1;22281:13;22273:113;;;22363:11;;;22357:18;22344:11;;;22337:39;22309:2;22302:10;22273:113;;;22404:6;22401:1;22398:13;22395:48;;;-1:-1:-1;;22439:1:1;22421:16;;22414:27;22191:258::o;22454:380::-;22533:1;22529:12;;;;22576;;;22597:61;;22651:4;22643:6;22639:17;22629:27;;22597:61;22704:2;22696:6;22693:14;22673:18;22670:38;22667:161;;;22750:10;22745:3;22741:20;22738:1;22731:31;22785:4;22782:1;22775:15;22813:4;22810:1;22803:15;22667:161;;22454:380;;;:::o;22839:135::-;22878:3;-1:-1:-1;;22899:17:1;;22896:43;;;22919:18;;:::i;:::-;-1:-1:-1;22966:1:1;22955:13;;22839:135::o;22979:112::-;23011:1;23037;23027:35;;23042:18;;:::i;:::-;-1:-1:-1;23076:9:1;;22979:112::o;23096:127::-;23157:10;23152:3;23148:20;23145:1;23138:31;23188:4;23185:1;23178:15;23212:4;23209:1;23202:15;23228:127;23289:10;23284:3;23280:20;23277:1;23270:31;23320:4;23317:1;23310:15;23344:4;23341:1;23334:15;23360:127;23421:10;23416:3;23412:20;23409:1;23402:31;23452:4;23449:1;23442:15;23476:4;23473:1;23466:15;23492:127;23553:10;23548:3;23544:20;23541:1;23534:31;23584:4;23581:1;23574:15;23608:4;23605:1;23598:15;23624:127;23685:10;23680:3;23676:20;23673:1;23666:31;23716:4;23713:1;23706:15;23740:4;23737:1;23730:15;23756:131;-1:-1:-1;;;;;;23830:32:1;;23820:43;;23810:71;;23877:1;23874;23867:12

Swarm Source

ipfs://8ab3885420cedffd586d53f18ed32f6e711792642e1775ecf112939a30ee329a
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.