ETH Price: $3,413.30 (-1.46%)
Gas: 8 Gwei

Token

Baddies (BD)
 

Overview

Max Total Supply

1,044 BD

Holders

605

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Balance
2 BD
0x6aef363a43d849e7a9146dfb8b948eaa8d10140a
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:
BaddiesNFT

Compiler Version
v0.6.6+commit.6c089d02

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-09-25
*/

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

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <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 payable) {
        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

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <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

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.2 <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

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.2 <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

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.2 <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

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <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

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <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 () internal {
        // 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

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <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

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.2 <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

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <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

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <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

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <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);
        uint256 index = digits - 1;
        temp = value;
        while (temp != 0) {
            buffer[index--] = bytes1(uint8(48 + temp % 10));
            temp /= 10;
        }
        return string(buffer);
    }
}

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

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <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_) public {
        _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);
    }

    function _approve(address to, uint256 tokenId) private {
        _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

// SPDX-License-Identifier: MIT

pragma solidity >=0.6.0 <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 () internal {
        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;
    }
}

// File: contracts/BaddiesNFT.sol

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



contract BaddiesNFT is ERC721, Ownable {
    using SafeMath for uint256;

    bool public SALE_ACTIVE = false;
    bool public PRESALE_ACTIVE = false;
    uint256 public PRESALE_MINTED;
    uint256 public STARTING_INDEX;
    string public PROVENANCE = "";

    uint256 public constant MAX_SUPPLY = 8765;
    uint256 public constant MAX_PRESALE = 2346;
    uint256 public constant MAX_PURCHASE = 10;
    uint256 public constant MAX_PRESALE_PURCHASE = 3;
    uint256 public constant BADDIE_PRICE = 0.08765 ether; // 0.08765 ETH
    uint256 public constant NUM_TO_RESERVE = 65;

    mapping(address => bool) public PRESALER_LIST;
    mapping(address => uint256) public PRESALE_PURCHASES;

    constructor() public ERC721("Baddies", "BD") {}

    function flipSaleState() external onlyOwner {
        SALE_ACTIVE = !SALE_ACTIVE;
    }

    function flipPresaleState() external onlyOwner {
        PRESALE_ACTIVE = !PRESALE_ACTIVE;
    }

    function addToPresaleList(address[] calldata entries) external onlyOwner {
        for(uint256 i = 0; i < entries.length; i++) {
            address entry = entries[i];
            require(entry != address(0), "NULL_ADDRESS");
            require(!PRESALER_LIST[entry], "DUPLICATE_ENTRY");

            PRESALER_LIST[entry] = true;
        }   
    }

    function removeFromPresaleList(address[] calldata entries) external onlyOwner {
        for(uint256 i = 0; i < entries.length; i++) {
            address entry = entries[i];
            require(entry != address(0), "NULL_ADDRESS");

            PRESALER_LIST[entry] = false;
        }
    }

    function isPresaler(address addr) external view returns (bool) {
        return PRESALER_LIST[addr];
    }
    
    function presalePurchasedCount(address addr) external view returns (uint256) {
        return PRESALE_PURCHASES[addr];
    }

    function withdraw() public onlyOwner {
        uint256 balance = address(this).balance;
        msg.sender.transfer(balance);
    }

    function reserveBaddies() public onlyOwner {
        require(
            totalSupply().add(NUM_TO_RESERVE) <= MAX_SUPPLY,
            "Reserve would exceed max supply of Baddies"
        );

        uint256 supply = totalSupply();
        for (uint256 i = 0; i < NUM_TO_RESERVE; i++) {
            _safeMint(msg.sender, supply + i);
        }
    }

    function mintBaddies(uint256 numberOfTokens) external payable {
        require(SALE_ACTIVE, "Sale must be started to mint baddies");
        require(
            numberOfTokens <= MAX_PURCHASE,
            "Can only mint 10 baddies at a time"
        );
        uint256 supply = totalSupply();
        require(
            supply.add(numberOfTokens) <= MAX_SUPPLY,
            "Purchase would exceed max supply of baddies"
        );
        require(
            BADDIE_PRICE.mul(numberOfTokens) <= msg.value,
            "Ether value sent is not correct"
        );
        
        for (uint256 i = 0; i < numberOfTokens; i++) {
            _safeMint(msg.sender, supply + i);
        }
    }

    function presaleMint(uint256 numberOfTokens) external payable {
        require(PRESALE_ACTIVE, "Presale closed");
        require(PRESALER_LIST[msg.sender], "Not qualified for presale");
        require(PRESALE_MINTED + numberOfTokens <= MAX_PRESALE, "Purchase would exceed max presale");
        uint256 supply = totalSupply();
        require(supply.add(numberOfTokens) <= MAX_SUPPLY, "Purchase would exceed max supply of baddies");
        require(PRESALE_PURCHASES[msg.sender] + numberOfTokens <= MAX_PRESALE_PURCHASE, "Purchase would exceed your max allocation");
        require(BADDIE_PRICE.mul(numberOfTokens) <= msg.value, "Ether value sent is not correct");
        
        for (uint256 i = 0; i < numberOfTokens; i++) {
            PRESALE_MINTED++;
            PRESALE_PURCHASES[msg.sender]++;
            _safeMint(msg.sender, supply + i);
        }
    }

    function setStartingIndex() public onlyOwner {
        require(STARTING_INDEX == 0, "Starting index is already set");

        STARTING_INDEX = uint(blockhash(block.number - 1)) % MAX_SUPPLY;
        if (STARTING_INDEX == 0) {
            STARTING_INDEX = STARTING_INDEX.add(1);
        }
    }

    function setProvenanceHash(string memory provenanceHash) public onlyOwner {
        PROVENANCE = provenanceHash;
    }

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

    function tokenURI(uint256 tokenId) public view override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");
        
        string memory base = baseURI();
        if (STARTING_INDEX == 0) {
            return base;
        }

        uint256 id = (tokenId + STARTING_INDEX) % MAX_SUPPLY;
        return string(abi.encodePacked(base, id.toString()));
    }
}

// File: contracts/Migrations.sol

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

contract Migrations {
  address public owner = msg.sender;
  uint public last_completed_migration;

  modifier restricted() {
    require(
      msg.sender == owner,
      "This function is restricted to the contract's owner"
    );
    _;
  }

  function setCompleted(uint completed) public restricted {
    last_completed_migration = completed;
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"BADDIE_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PRESALE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PRESALE_PURCHASE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_PURCHASE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NUM_TO_RESERVE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"PRESALER_LIST","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRESALE_ACTIVE","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRESALE_MINTED","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"PRESALE_PURCHASES","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PROVENANCE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SALE_ACTIVE","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"STARTING_INDEX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"entries","type":"address[]"}],"name":"addToPresaleList","outputs":[],"stateMutability":"nonpayable","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":[],"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":[{"internalType":"address","name":"addr","type":"address"}],"name":"isPresaler","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numberOfTokens","type":"uint256"}],"name":"mintBaddies","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"uint256","name":"numberOfTokens","type":"uint256"}],"name":"presaleMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"presalePurchasedCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"entries","type":"address[]"}],"name":"removeFromPresaleList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reserveBaddies","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"provenanceHash","type":"string"}],"name":"setProvenanceHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setStartingIndex","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"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":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526000600a60146101000a81548160ff0219169083151502179055506000600a60156101000a81548160ff02191690831515021790555060405180602001604052806000815250600d90805190602001906200006192919062000338565b503480156200006f57600080fd5b506040518060400160405280600781526020017f42616464696573000000000000000000000000000000000000000000000000008152506040518060400160405280600281526020017f4244000000000000000000000000000000000000000000000000000000000000815250620000f46301ffc9a760e01b6200022760201b60201c565b81600690805190602001906200010c92919062000338565b5080600790805190602001906200012592919062000338565b506200013e6380ac58cd60e01b6200022760201b60201c565b62000156635b5e139f60e01b6200022760201b60201c565b6200016e63780e9d6360e01b6200022760201b60201c565b50506000620001826200033060201b60201c565b905080600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a350620003e7565b63ffffffff60e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161415620002c4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f4552433136353a20696e76616c696420696e746572666163652069640000000081525060200191505060405180910390fd5b6001600080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600033905090565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106200037b57805160ff1916838001178555620003ac565b82800160010185558215620003ac579182015b82811115620003ab5782518255916020019190600101906200038e565b5b509050620003bb9190620003bf565b5090565b620003e491905b80821115620003e0576000816000905550600101620003c6565b5090565b90565b614cc680620003f76000396000f3fe60806040526004361061027d5760003560e01c80636c0360eb1161014f578063b17d0247116100c1578063e985e9c51161007a578063e985e9c51461118f578063e986655014611218578063f216ddfd1461122f578063f2fde38b1461125e578063f7de95e4146112af578063f81227d4146112da5761027d565b8063b17d024714610f17578063b88d4fde14610f45578063c87b56dd14611057578063c9b298f11461110b578063daeee21b14611139578063e60400b4146111645761027d565b80638da5cb5b116101135780638da5cb5b14610cb957806392ac5acb14610d1057806395d89b4114610d3b5780639e273b2f14610dcb578063a22cb46514610e34578063b179e06014610e915761027d565b80636c0360eb14610afc57806370a0823114610b8c5780637146bd0814610bf1578063715018a614610c1c5780637204a3c914610c335761027d565b806332cb6b0c116101f35780634d4c4e99116101ac5780634d4c4e991461084a5780634f6ccce71461087557806355f804b3146108c45780635ce7af1f1461098c5780636352211e146109f15780636373a6b114610a6c5761027d565b806332cb6b0c146106e257806334918dfd1461070d57806336a30cac146107245780633ccfd60b146107895780633fea6aae146107a057806342842e0e146107cf5761027d565b806318160ddd1161024557806318160ddd146105225780631d6372481461054d5780632046932a1461056457806323b872dd146105cd5780632a2c6c08146106485780632f745c59146106735761027d565b806301ffc9a71461028257806306fdde03146102f4578063081812fc14610384578063095ea7b3146103ff578063109695231461045a575b600080fd5b34801561028e57600080fd5b506102da600480360360208110156102a557600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690602001909291905050506112f1565b604051808215151515815260200191505060405180910390f35b34801561030057600080fd5b50610309611358565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561034957808201518184015260208101905061032e565b50505050905090810190601f1680156103765780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561039057600080fd5b506103bd600480360360208110156103a757600080fd5b81019080803590602001909291905050506113fa565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561040b57600080fd5b506104586004803603604081101561042257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611495565b005b34801561046657600080fd5b506105206004803603602081101561047d57600080fd5b810190808035906020019064010000000081111561049a57600080fd5b8201836020820111156104ac57600080fd5b803590602001918460018302840111640100000000831117156104ce57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506115d9565b005b34801561052e57600080fd5b506105376116a2565b6040518082815260200191505060405180910390f35b34801561055957600080fd5b506105626116b3565b005b34801561057057600080fd5b506105b36004803603602081101561058757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061180f565b604051808215151515815260200191505060405180910390f35b3480156105d957600080fd5b50610646600480360360608110156105f057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061182f565b005b34801561065457600080fd5b5061065d6118a5565b6040518082815260200191505060405180910390f35b34801561067f57600080fd5b506106cc6004803603604081101561069657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506118aa565b6040518082815260200191505060405180910390f35b3480156106ee57600080fd5b506106f7611905565b6040518082815260200191505060405180910390f35b34801561071957600080fd5b5061072261190b565b005b34801561073057600080fd5b506107736004803603602081101561074757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506119e6565b6040518082815260200191505060405180910390f35b34801561079557600080fd5b5061079e6119fe565b005b3480156107ac57600080fd5b506107b5611afc565b604051808215151515815260200191505060405180910390f35b3480156107db57600080fd5b50610848600480360360608110156107f257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611b0f565b005b34801561085657600080fd5b5061085f611b2f565b6040518082815260200191505060405180910390f35b34801561088157600080fd5b506108ae6004803603602081101561089857600080fd5b8101908080359060200190929190505050611b35565b6040518082815260200191505060405180910390f35b3480156108d057600080fd5b5061098a600480360360208110156108e757600080fd5b810190808035906020019064010000000081111561090457600080fd5b82018360208201111561091657600080fd5b8035906020019184600183028401116401000000008311171561093857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611b58565b005b34801561099857600080fd5b506109db600480360360208110156109af57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611c13565b6040518082815260200191505060405180910390f35b3480156109fd57600080fd5b50610a2a60048036036020811015610a1457600080fd5b8101908080359060200190929190505050611c5c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610a7857600080fd5b50610a81611c93565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610ac1578082015181840152602081019050610aa6565b50505050905090810190601f168015610aee5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610b0857600080fd5b50610b11611d31565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610b51578082015181840152602081019050610b36565b50505050905090810190601f168015610b7e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610b9857600080fd5b50610bdb60048036036020811015610baf57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611dd3565b6040518082815260200191505060405180910390f35b348015610bfd57600080fd5b50610c06611ea8565b6040518082815260200191505060405180910390f35b348015610c2857600080fd5b50610c31611ead565b005b348015610c3f57600080fd5b50610cb760048036036020811015610c5657600080fd5b8101908080359060200190640100000000811115610c7357600080fd5b820183602082011115610c8557600080fd5b80359060200191846020830284011164010000000083111715610ca757600080fd5b909192939192939050505061201d565b005b348015610cc557600080fd5b50610cce6122d8565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610d1c57600080fd5b50610d25612302565b6040518082815260200191505060405180910390f35b348015610d4757600080fd5b50610d5061230e565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610d90578082015181840152602081019050610d75565b50505050905090810190601f168015610dbd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610dd757600080fd5b50610e1a60048036036020811015610dee57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506123b0565b604051808215151515815260200191505060405180910390f35b348015610e4057600080fd5b50610e8f60048036036040811015610e5757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050612406565b005b348015610e9d57600080fd5b50610f1560048036036020811015610eb457600080fd5b8101908080359060200190640100000000811115610ed157600080fd5b820183602082011115610ee357600080fd5b80359060200191846020830284011164010000000083111715610f0557600080fd5b90919293919293905050506125be565b005b610f4360048036036020811015610f2d57600080fd5b81019080803590602001909291905050506127b9565b005b348015610f5157600080fd5b5061105560048036036080811015610f6857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610fcf57600080fd5b820183602082011115610fe157600080fd5b8035906020019184600183028401116401000000008311171561100357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506129ad565b005b34801561106357600080fd5b506110906004803603602081101561107a57600080fd5b8101908080359060200190929190505050612a25565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156110d05780820151818401526020810190506110b5565b50505050905090810190601f1680156110fd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6111376004803603602081101561112157600080fd5b8101908080359060200190929190505050612b89565b005b34801561114557600080fd5b5061114e612f5a565b6040518082815260200191505060405180910390f35b34801561117057600080fd5b50611179612f5f565b6040518082815260200191505060405180910390f35b34801561119b57600080fd5b506111fe600480360360408110156111b257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612f65565b604051808215151515815260200191505060405180910390f35b34801561122457600080fd5b5061122d612ff9565b005b34801561123b57600080fd5b50611244613163565b604051808215151515815260200191505060405180910390f35b34801561126a57600080fd5b506112ad6004803603602081101561128157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613176565b005b3480156112bb57600080fd5b506112c461336b565b6040518082815260200191505060405180910390f35b3480156112e657600080fd5b506112ef613371565b005b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b606060068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156113f05780601f106113c5576101008083540402835291602001916113f0565b820191906000526020600020905b8154815290600101906020018083116113d357829003601f168201915b5050505050905090565b60006114058261344c565b61145a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180614b6e602c913960400191505060405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006114a082611c5c565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611527576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180614bf26021913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16611546613469565b73ffffffffffffffffffffffffffffffffffffffff16148061157557506115748161156f613469565b612f65565b5b6115ca576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526038815260200180614a756038913960400191505060405180910390fd5b6115d48383613471565b505050565b6115e1613469565b73ffffffffffffffffffffffffffffffffffffffff166115ff6122d8565b73ffffffffffffffffffffffffffffffffffffffff1614611688576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b80600d908051906020019061169e929190614872565b5050565b60006116ae600261352a565b905090565b6116bb613469565b73ffffffffffffffffffffffffffffffffffffffff166116d96122d8565b73ffffffffffffffffffffffffffffffffffffffff1614611762576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b61223d61178060416117726116a2565b61353f90919063ffffffff16565b11156117d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a81526020018061495b602a913960400191505060405180910390fd5b60006117e16116a2565b905060008090505b604181101561180b576117fe338284016135c7565b80806001019150506117e9565b5050565b600e6020528060005260406000206000915054906101000a900460ff1681565b61184061183a613469565b826135e5565b611895576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526031815260200180614c3c6031913960400191505060405180910390fd5b6118a08383836136d9565b505050565b600381565b60006118fd82600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061391c90919063ffffffff16565b905092915050565b61223d81565b611913613469565b73ffffffffffffffffffffffffffffffffffffffff166119316122d8565b73ffffffffffffffffffffffffffffffffffffffff16146119ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600a60149054906101000a900460ff1615600a60146101000a81548160ff021916908315150217905550565b600f6020528060005260406000206000915090505481565b611a06613469565b73ffffffffffffffffffffffffffffffffffffffff16611a246122d8565b73ffffffffffffffffffffffffffffffffffffffff1614611aad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60004790503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611af8573d6000803e3d6000fd5b5050565b600a60159054906101000a900460ff1681565b611b2a838383604051806020016040528060008152506129ad565b505050565b61092a81565b600080611b4c83600261393690919063ffffffff16565b50905080915050919050565b611b60613469565b73ffffffffffffffffffffffffffffffffffffffff16611b7e6122d8565b73ffffffffffffffffffffffffffffffffffffffff1614611c07576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b611c1081613965565b50565b6000600f60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000611c8c82604051806060016040528060298152602001614ad760299139600261397f9092919063ffffffff16565b9050919050565b600d8054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611d295780601f10611cfe57610100808354040283529160200191611d29565b820191906000526020600020905b815481529060010190602001808311611d0c57829003601f168201915b505050505081565b606060098054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611dc95780601f10611d9e57610100808354040283529160200191611dc9565b820191906000526020600020905b815481529060010190602001808311611dac57829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611e5a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180614aad602a913960400191505060405180910390fd5b611ea1600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061399e565b9050919050565b600a81565b611eb5613469565b73ffffffffffffffffffffffffffffffffffffffff16611ed36122d8565b73ffffffffffffffffffffffffffffffffffffffff1614611f5c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b612025613469565b73ffffffffffffffffffffffffffffffffffffffff166120436122d8565b73ffffffffffffffffffffffffffffffffffffffff16146120cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60008090505b828290508110156122d35760008383838181106120eb57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156121ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e554c4c5f41444452455353000000000000000000000000000000000000000081525060200191505060405180910390fd5b600e60008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561226d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f4455504c49434154455f454e545259000000000000000000000000000000000081525060200191505060405180910390fd5b6001600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505080806001019150506120d2565b505050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6701376535ea90200081565b606060078054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156123a65780601f1061237b576101008083540402835291602001916123a6565b820191906000526020600020905b81548152906001019060200180831161238957829003601f168201915b5050505050905090565b6000600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b61240e613469565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156124af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f4552433732313a20617070726f766520746f2063616c6c65720000000000000081525060200191505060405180910390fd5b80600560006124bc613469565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612569613469565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051808215151515815260200191505060405180910390a35050565b6125c6613469565b73ffffffffffffffffffffffffffffffffffffffff166125e46122d8565b73ffffffffffffffffffffffffffffffffffffffff161461266d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60008090505b828290508110156127b457600083838381811061268c57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561274e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e554c4c5f41444452455353000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550508080600101915050612673565b505050565b600a60149054906101000a900460ff1661281e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180614c6d6024913960400191505060405180910390fd5b600a811115612878576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806149b76022913960400191505060405180910390fd5b60006128826116a2565b905061223d61289a838361353f90919063ffffffff16565b11156128f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b815260200180614b22602b913960400191505060405180910390fd5b3461290d836701376535ea9020006139b390919063ffffffff16565b1115612981576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45746865722076616c75652073656e74206973206e6f7420636f72726563740081525060200191505060405180910390fd5b60008090505b828110156129a85761299b338284016135c7565b8080600101915050612987565b505050565b6129be6129b8613469565b836135e5565b612a13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526031815260200180614c3c6031913960400191505060405180910390fd5b612a1f84848484613a39565b50505050565b6060612a308261344c565b612a85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180614bc3602f913960400191505060405180910390fd5b6060612a8f611d31565b90506000600c541415612aa55780915050612b84565b600061223d600c54850181612ab657fe5b06905081612ac382613aab565b6040516020018083805190602001908083835b60208310612af95780518252602082019150602081019050602083039250612ad6565b6001836020036101000a03801982511681845116808217855250505050505090500182805190602001908083835b60208310612b4a5780518252602082019150602081019050602083039250612b27565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052925050505b919050565b600a60159054906101000a900460ff16612c0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f50726573616c6520636c6f73656400000000000000000000000000000000000081525060200191505060405180910390fd5b600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16612cca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f4e6f74207175616c696669656420666f722070726573616c650000000000000081525060200191505060405180910390fd5b61092a81600b54011115612d29576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061493a6021913960400191505060405180910390fd5b6000612d336116a2565b905061223d612d4b838361353f90919063ffffffff16565b1115612da2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b815260200180614b22602b913960400191505060405180910390fd5b600382600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054011115612e3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526029815260200180614c136029913960400191505060405180910390fd5b34612e59836701376535ea9020006139b390919063ffffffff16565b1115612ecd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45746865722076616c75652073656e74206973206e6f7420636f72726563740081525060200191505060405180910390fd5b60008090505b82811015612f5557600b60008154809291906001019190505550600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154809291906001019190505550612f48338284016135c7565b8080600101915050612ed3565b505050565b604181565b600b5481565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b613001613469565b73ffffffffffffffffffffffffffffffffffffffff1661301f6122d8565b73ffffffffffffffffffffffffffffffffffffffff16146130a8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6000600c5414613120576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5374617274696e6720696e64657820697320616c72656164792073657400000081525060200191505060405180910390fd5b61223d600143034060001c8161313257fe5b06600c819055506000600c5414156131615761315a6001600c5461353f90919063ffffffff16565b600c819055505b565b600a60149054906101000a900460ff1681565b61317e613469565b73ffffffffffffffffffffffffffffffffffffffff1661319c6122d8565b73ffffffffffffffffffffffffffffffffffffffff1614613225576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156132ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806149d96026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600c5481565b613379613469565b73ffffffffffffffffffffffffffffffffffffffff166133976122d8565b73ffffffffffffffffffffffffffffffffffffffff1614613420576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600a60159054906101000a900460ff1615600a60156101000a81548160ff021916908315150217905550565b6000613462826002613bf290919063ffffffff16565b9050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166134e483611c5c565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061353882600001613c0c565b9050919050565b6000808284019050838110156135bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b6135e1828260405180602001604052806000815250613c1d565b5050565b60006135f08261344c565b613645576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180614a49602c913960400191505060405180910390fd5b600061365083611c5c565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806136bf57508373ffffffffffffffffffffffffffffffffffffffff166136a7846113fa565b73ffffffffffffffffffffffffffffffffffffffff16145b806136d057506136cf8185612f65565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff166136f982611c5c565b73ffffffffffffffffffffffffffffffffffffffff1614613765576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526029815260200180614b9a6029913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156137eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806149ff6024913960400191505060405180910390fd5b6137f6838383613c8e565b613801600082613471565b61385281600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020613c9390919063ffffffff16565b506138a481600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020613cad90919063ffffffff16565b506138bb81836002613cc79092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b600061392b8360000183613cfc565b60001c905092915050565b6000806000806139498660000186613d7f565b915091508160001c8160001c8090509350935050509250929050565b806009908051906020019061397b929190614872565b5050565b6000613992846000018460001b84613e18565b60001c90509392505050565b60006139ac82600001613f0e565b9050919050565b6000808314156139c65760009050613a33565b60008284029050828482816139d757fe5b0414613a2e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180614b4d6021913960400191505060405180910390fd5b809150505b92915050565b613a448484846136d9565b613a5084848484613f1f565b613aa5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806149856032913960400191505060405180910390fd5b50505050565b60606000821415613af3576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050613bed565b600082905060005b60008214613b1d578080600101915050600a8281613b1557fe5b049150613afb565b60608167ffffffffffffffff81118015613b3657600080fd5b506040519080825280601f01601f191660200182016040528015613b695781602001600182028036833780820191505090505b50905060006001830390508593505b60008414613be557600a8481613b8a57fe5b0660300160f81b82828060019003935081518110613ba457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8481613bdd57fe5b049350613b78565b819450505050505b919050565b6000613c04836000018360001b614164565b905092915050565b600081600001805490509050919050565b613c278383614187565b613c346000848484613f1f565b613c89576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806149856032913960400191505060405180910390fd5b505050565b505050565b6000613ca5836000018360001b61437b565b905092915050565b6000613cbf836000018360001b614463565b905092915050565b6000613cf3846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b6144d3565b90509392505050565b600081836000018054905011613d5d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806149186022913960400191505060405180910390fd5b826000018281548110613d6c57fe5b9060005260206000200154905092915050565b60008082846000018054905011613de1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180614b006022913960400191505060405180910390fd5b6000846000018481548110613df257fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b60008084600101600085815260200190815260200160002054905060008114158390613edf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613ea4578082015181840152602081019050613e89565b50505050905090810190601f168015613ed15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50846000016001820381548110613ef257fe5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b6000613f408473ffffffffffffffffffffffffffffffffffffffff166145af565b613f4d576001905061415c565b60606140e363150b7a0260e01b613f62613469565b888787604051602401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015614012578082015181840152602081019050613ff7565b50505050905090810190601f16801561403f5780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051806060016040528060328152602001614985603291398773ffffffffffffffffffffffffffffffffffffffff166145c29092919063ffffffff16565b905060008180602001905160208110156140fc57600080fd5b8101908080519060200190929190505050905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614925050505b949350505050565b600080836001016000848152602001908152602001600020541415905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561422a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4552433732313a206d696e7420746f20746865207a65726f206164647265737381525060200191505060405180910390fd5b6142338161344c565b156142a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000081525060200191505060405180910390fd5b6142b260008383613c8e565b61430381600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020613cad90919063ffffffff16565b5061431a81836002613cc79092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b6000808360010160008481526020019081526020016000205490506000811461445757600060018203905060006001866000018054905003905060008660000182815481106143c657fe5b90600052602060002001549050808760000184815481106143e357fe5b906000526020600020018190555060018301876001016000838152602001908152602001600020819055508660000180548061441b57fe5b6001900381819060005260206000200160009055905586600101600087815260200190815260200160002060009055600194505050505061445d565b60009150505b92915050565b600061446f83836145da565b6144c85782600001829080600181540180825580915050600190039060005260206000200160009091909190915055826000018054905083600101600084815260200190815260200160002081905550600190506144cd565b600090505b92915050565b600080846001016000858152602001908152602001600020549050600081141561457a578460000160405180604001604052808681526020018581525090806001815401808255809150506001900390600052602060002090600202016000909190919091506000820151816000015560208201518160010155505084600001805490508560010160008681526020019081526020016000208190555060019150506145a8565b8285600001600183038154811061458d57fe5b90600052602060002090600202016001018190555060009150505b9392505050565b600080823b905060008111915050919050565b60606145d184846000856145fd565b90509392505050565b600080836001016000848152602001908152602001600020541415905092915050565b606082471015614658576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180614a236026913960400191505060405180910390fd5b614661856145af565b6146d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b602083106147235780518252602082019150602081019050602083039250614700565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114614785576040519150601f19603f3d011682016040523d82523d6000602084013e61478a565b606091505b509150915061479a8282866147a6565b92505050949350505050565b606083156147b65782905061486b565b6000835111156147c95782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614830578082015181840152602081019050614815565b50505050905090810190601f16801561485d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106148b357805160ff19168380011785556148e1565b828001600101855582156148e1579182015b828111156148e05782518255916020019190600101906148c5565b5b5090506148ee91906148f2565b5090565b61491491905b808211156149105760008160009055506001016148f8565b5090565b9056fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473507572636861736520776f756c6420657863656564206d61782070726573616c655265736572766520776f756c6420657863656564206d617820737570706c79206f6620426164646965734552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e74657243616e206f6e6c79206d696e74203130206261646469657320617420612074696d654f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734552433732313a207472616e7366657220746f20746865207a65726f2061646472657373416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c4552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e6473507572636861736520776f756c6420657863656564206d617820737570706c79206f662062616464696573536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e6572507572636861736520776f756c642065786365656420796f7572206d617820616c6c6f636174696f6e4552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656453616c65206d757374206265207374617274656420746f206d696e742062616464696573a264697066735822122016af09d2312a4755f74fe703abe99fce42af724b02f534cee71071a8436ed40a64736f6c63430006060033

Deployed Bytecode

0x60806040526004361061027d5760003560e01c80636c0360eb1161014f578063b17d0247116100c1578063e985e9c51161007a578063e985e9c51461118f578063e986655014611218578063f216ddfd1461122f578063f2fde38b1461125e578063f7de95e4146112af578063f81227d4146112da5761027d565b8063b17d024714610f17578063b88d4fde14610f45578063c87b56dd14611057578063c9b298f11461110b578063daeee21b14611139578063e60400b4146111645761027d565b80638da5cb5b116101135780638da5cb5b14610cb957806392ac5acb14610d1057806395d89b4114610d3b5780639e273b2f14610dcb578063a22cb46514610e34578063b179e06014610e915761027d565b80636c0360eb14610afc57806370a0823114610b8c5780637146bd0814610bf1578063715018a614610c1c5780637204a3c914610c335761027d565b806332cb6b0c116101f35780634d4c4e99116101ac5780634d4c4e991461084a5780634f6ccce71461087557806355f804b3146108c45780635ce7af1f1461098c5780636352211e146109f15780636373a6b114610a6c5761027d565b806332cb6b0c146106e257806334918dfd1461070d57806336a30cac146107245780633ccfd60b146107895780633fea6aae146107a057806342842e0e146107cf5761027d565b806318160ddd1161024557806318160ddd146105225780631d6372481461054d5780632046932a1461056457806323b872dd146105cd5780632a2c6c08146106485780632f745c59146106735761027d565b806301ffc9a71461028257806306fdde03146102f4578063081812fc14610384578063095ea7b3146103ff578063109695231461045a575b600080fd5b34801561028e57600080fd5b506102da600480360360208110156102a557600080fd5b8101908080357bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191690602001909291905050506112f1565b604051808215151515815260200191505060405180910390f35b34801561030057600080fd5b50610309611358565b6040518080602001828103825283818151815260200191508051906020019080838360005b8381101561034957808201518184015260208101905061032e565b50505050905090810190601f1680156103765780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b34801561039057600080fd5b506103bd600480360360208110156103a757600080fd5b81019080803590602001909291905050506113fa565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b34801561040b57600080fd5b506104586004803603604081101561042257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611495565b005b34801561046657600080fd5b506105206004803603602081101561047d57600080fd5b810190808035906020019064010000000081111561049a57600080fd5b8201836020820111156104ac57600080fd5b803590602001918460018302840111640100000000831117156104ce57600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506115d9565b005b34801561052e57600080fd5b506105376116a2565b6040518082815260200191505060405180910390f35b34801561055957600080fd5b506105626116b3565b005b34801561057057600080fd5b506105b36004803603602081101561058757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff16906020019092919050505061180f565b604051808215151515815260200191505060405180910390f35b3480156105d957600080fd5b50610646600480360360608110156105f057600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919050505061182f565b005b34801561065457600080fd5b5061065d6118a5565b6040518082815260200191505060405180910390f35b34801561067f57600080fd5b506106cc6004803603604081101561069657600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803590602001909291905050506118aa565b6040518082815260200191505060405180910390f35b3480156106ee57600080fd5b506106f7611905565b6040518082815260200191505060405180910390f35b34801561071957600080fd5b5061072261190b565b005b34801561073057600080fd5b506107736004803603602081101561074757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506119e6565b6040518082815260200191505060405180910390f35b34801561079557600080fd5b5061079e6119fe565b005b3480156107ac57600080fd5b506107b5611afc565b604051808215151515815260200191505060405180910390f35b3480156107db57600080fd5b50610848600480360360608110156107f257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff16906020019092919080359060200190929190505050611b0f565b005b34801561085657600080fd5b5061085f611b2f565b6040518082815260200191505060405180910390f35b34801561088157600080fd5b506108ae6004803603602081101561089857600080fd5b8101908080359060200190929190505050611b35565b6040518082815260200191505060405180910390f35b3480156108d057600080fd5b5061098a600480360360208110156108e757600080fd5b810190808035906020019064010000000081111561090457600080fd5b82018360208201111561091657600080fd5b8035906020019184600183028401116401000000008311171561093857600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f820116905080830192505050505050509192919290505050611b58565b005b34801561099857600080fd5b506109db600480360360208110156109af57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611c13565b6040518082815260200191505060405180910390f35b3480156109fd57600080fd5b50610a2a60048036036020811015610a1457600080fd5b8101908080359060200190929190505050611c5c565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610a7857600080fd5b50610a81611c93565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610ac1578082015181840152602081019050610aa6565b50505050905090810190601f168015610aee5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610b0857600080fd5b50610b11611d31565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610b51578082015181840152602081019050610b36565b50505050905090810190601f168015610b7e5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610b9857600080fd5b50610bdb60048036036020811015610baf57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050611dd3565b6040518082815260200191505060405180910390f35b348015610bfd57600080fd5b50610c06611ea8565b6040518082815260200191505060405180910390f35b348015610c2857600080fd5b50610c31611ead565b005b348015610c3f57600080fd5b50610cb760048036036020811015610c5657600080fd5b8101908080359060200190640100000000811115610c7357600080fd5b820183602082011115610c8557600080fd5b80359060200191846020830284011164010000000083111715610ca757600080fd5b909192939192939050505061201d565b005b348015610cc557600080fd5b50610cce6122d8565b604051808273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200191505060405180910390f35b348015610d1c57600080fd5b50610d25612302565b6040518082815260200191505060405180910390f35b348015610d4757600080fd5b50610d5061230e565b6040518080602001828103825283818151815260200191508051906020019080838360005b83811015610d90578082015181840152602081019050610d75565b50505050905090810190601f168015610dbd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b348015610dd757600080fd5b50610e1a60048036036020811015610dee57600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff1690602001909291905050506123b0565b604051808215151515815260200191505060405180910390f35b348015610e4057600080fd5b50610e8f60048036036040811015610e5757600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803515159060200190929190505050612406565b005b348015610e9d57600080fd5b50610f1560048036036020811015610eb457600080fd5b8101908080359060200190640100000000811115610ed157600080fd5b820183602082011115610ee357600080fd5b80359060200191846020830284011164010000000083111715610f0557600080fd5b90919293919293905050506125be565b005b610f4360048036036020811015610f2d57600080fd5b81019080803590602001909291905050506127b9565b005b348015610f5157600080fd5b5061105560048036036080811015610f6857600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff1690602001909291908035906020019092919080359060200190640100000000811115610fcf57600080fd5b820183602082011115610fe157600080fd5b8035906020019184600183028401116401000000008311171561100357600080fd5b91908080601f016020809104026020016040519081016040528093929190818152602001838380828437600081840152601f19601f8201169050808301925050505050505091929192905050506129ad565b005b34801561106357600080fd5b506110906004803603602081101561107a57600080fd5b8101908080359060200190929190505050612a25565b6040518080602001828103825283818151815260200191508051906020019080838360005b838110156110d05780820151818401526020810190506110b5565b50505050905090810190601f1680156110fd5780820380516001836020036101000a031916815260200191505b509250505060405180910390f35b6111376004803603602081101561112157600080fd5b8101908080359060200190929190505050612b89565b005b34801561114557600080fd5b5061114e612f5a565b6040518082815260200191505060405180910390f35b34801561117057600080fd5b50611179612f5f565b6040518082815260200191505060405180910390f35b34801561119b57600080fd5b506111fe600480360360408110156111b257600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050612f65565b604051808215151515815260200191505060405180910390f35b34801561122457600080fd5b5061122d612ff9565b005b34801561123b57600080fd5b50611244613163565b604051808215151515815260200191505060405180910390f35b34801561126a57600080fd5b506112ad6004803603602081101561128157600080fd5b81019080803573ffffffffffffffffffffffffffffffffffffffff169060200190929190505050613176565b005b3480156112bb57600080fd5b506112c461336b565b6040518082815260200191505060405180910390f35b3480156112e657600080fd5b506112ef613371565b005b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b606060068054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156113f05780601f106113c5576101008083540402835291602001916113f0565b820191906000526020600020905b8154815290600101906020018083116113d357829003601f168201915b5050505050905090565b60006114058261344c565b61145a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180614b6e602c913960400191505060405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b60006114a082611c5c565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415611527576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180614bf26021913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16611546613469565b73ffffffffffffffffffffffffffffffffffffffff16148061157557506115748161156f613469565b612f65565b5b6115ca576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526038815260200180614a756038913960400191505060405180910390fd5b6115d48383613471565b505050565b6115e1613469565b73ffffffffffffffffffffffffffffffffffffffff166115ff6122d8565b73ffffffffffffffffffffffffffffffffffffffff1614611688576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b80600d908051906020019061169e929190614872565b5050565b60006116ae600261352a565b905090565b6116bb613469565b73ffffffffffffffffffffffffffffffffffffffff166116d96122d8565b73ffffffffffffffffffffffffffffffffffffffff1614611762576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b61223d61178060416117726116a2565b61353f90919063ffffffff16565b11156117d7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a81526020018061495b602a913960400191505060405180910390fd5b60006117e16116a2565b905060008090505b604181101561180b576117fe338284016135c7565b80806001019150506117e9565b5050565b600e6020528060005260406000206000915054906101000a900460ff1681565b61184061183a613469565b826135e5565b611895576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526031815260200180614c3c6031913960400191505060405180910390fd5b6118a08383836136d9565b505050565b600381565b60006118fd82600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061391c90919063ffffffff16565b905092915050565b61223d81565b611913613469565b73ffffffffffffffffffffffffffffffffffffffff166119316122d8565b73ffffffffffffffffffffffffffffffffffffffff16146119ba576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600a60149054906101000a900460ff1615600a60146101000a81548160ff021916908315150217905550565b600f6020528060005260406000206000915090505481565b611a06613469565b73ffffffffffffffffffffffffffffffffffffffff16611a246122d8565b73ffffffffffffffffffffffffffffffffffffffff1614611aad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60004790503373ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015611af8573d6000803e3d6000fd5b5050565b600a60159054906101000a900460ff1681565b611b2a838383604051806020016040528060008152506129ad565b505050565b61092a81565b600080611b4c83600261393690919063ffffffff16565b50905080915050919050565b611b60613469565b73ffffffffffffffffffffffffffffffffffffffff16611b7e6122d8565b73ffffffffffffffffffffffffffffffffffffffff1614611c07576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b611c1081613965565b50565b6000600f60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6000611c8c82604051806060016040528060298152602001614ad760299139600261397f9092919063ffffffff16565b9050919050565b600d8054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611d295780601f10611cfe57610100808354040283529160200191611d29565b820191906000526020600020905b815481529060010190602001808311611d0c57829003601f168201915b505050505081565b606060098054600181600116156101000203166002900480601f016020809104026020016040519081016040528092919081815260200182805460018160011615610100020316600290048015611dc95780601f10611d9e57610100808354040283529160200191611dc9565b820191906000526020600020905b815481529060010190602001808311611dac57829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611e5a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602a815260200180614aad602a913960400191505060405180910390fd5b611ea1600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061399e565b9050919050565b600a81565b611eb5613469565b73ffffffffffffffffffffffffffffffffffffffff16611ed36122d8565b73ffffffffffffffffffffffffffffffffffffffff1614611f5c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b612025613469565b73ffffffffffffffffffffffffffffffffffffffff166120436122d8565b73ffffffffffffffffffffffffffffffffffffffff16146120cc576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60008090505b828290508110156122d35760008383838181106120eb57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156121ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e554c4c5f41444452455353000000000000000000000000000000000000000081525060200191505060405180910390fd5b600e60008273ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff161561226d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600f8152602001807f4455504c49434154455f454e545259000000000000000000000000000000000081525060200191505060405180910390fd5b6001600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505080806001019150506120d2565b505050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6701376535ea90200081565b606060078054600181600116156101000203166002900480601f0160208091040260200160405190810160405280929190818152602001828054600181600116156101000203166002900480156123a65780601f1061237b576101008083540402835291602001916123a6565b820191906000526020600020905b81548152906001019060200180831161238957829003601f168201915b5050505050905090565b6000600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919050565b61240e613469565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156124af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f4552433732313a20617070726f766520746f2063616c6c65720000000000000081525060200191505060405180910390fd5b80600560006124bc613469565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612569613469565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051808215151515815260200191505060405180910390a35050565b6125c6613469565b73ffffffffffffffffffffffffffffffffffffffff166125e46122d8565b73ffffffffffffffffffffffffffffffffffffffff161461266d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b60008090505b828290508110156127b457600083838381811061268c57fe5b9050602002013573ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561274e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600c8152602001807f4e554c4c5f41444452455353000000000000000000000000000000000000000081525060200191505060405180910390fd5b6000600e60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550508080600101915050612673565b505050565b600a60149054906101000a900460ff1661281e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526024815260200180614c6d6024913960400191505060405180910390fd5b600a811115612878576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806149b76022913960400191505060405180910390fd5b60006128826116a2565b905061223d61289a838361353f90919063ffffffff16565b11156128f1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b815260200180614b22602b913960400191505060405180910390fd5b3461290d836701376535ea9020006139b390919063ffffffff16565b1115612981576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45746865722076616c75652073656e74206973206e6f7420636f72726563740081525060200191505060405180910390fd5b60008090505b828110156129a85761299b338284016135c7565b8080600101915050612987565b505050565b6129be6129b8613469565b836135e5565b612a13576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526031815260200180614c3c6031913960400191505060405180910390fd5b612a1f84848484613a39565b50505050565b6060612a308261344c565b612a85576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602f815260200180614bc3602f913960400191505060405180910390fd5b6060612a8f611d31565b90506000600c541415612aa55780915050612b84565b600061223d600c54850181612ab657fe5b06905081612ac382613aab565b6040516020018083805190602001908083835b60208310612af95780518252602082019150602081019050602083039250612ad6565b6001836020036101000a03801982511681845116808217855250505050505090500182805190602001908083835b60208310612b4a5780518252602082019150602081019050602083039250612b27565b6001836020036101000a03801982511681845116808217855250505050505090500192505050604051602081830303815290604052925050505b919050565b600a60159054906101000a900460ff16612c0b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252600e8152602001807f50726573616c6520636c6f73656400000000000000000000000000000000000081525060200191505060405180910390fd5b600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16612cca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260198152602001807f4e6f74207175616c696669656420666f722070726573616c650000000000000081525060200191505060405180910390fd5b61092a81600b54011115612d29576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602181526020018061493a6021913960400191505060405180910390fd5b6000612d336116a2565b905061223d612d4b838361353f90919063ffffffff16565b1115612da2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602b815260200180614b22602b913960400191505060405180910390fd5b600382600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054011115612e3d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526029815260200180614c136029913960400191505060405180910390fd5b34612e59836701376535ea9020006139b390919063ffffffff16565b1115612ecd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601f8152602001807f45746865722076616c75652073656e74206973206e6f7420636f72726563740081525060200191505060405180910390fd5b60008090505b82811015612f5557600b60008154809291906001019190505550600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154809291906001019190505550612f48338284016135c7565b8080600101915050612ed3565b505050565b604181565b600b5481565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b613001613469565b73ffffffffffffffffffffffffffffffffffffffff1661301f6122d8565b73ffffffffffffffffffffffffffffffffffffffff16146130a8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b6000600c5414613120576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f5374617274696e6720696e64657820697320616c72656164792073657400000081525060200191505060405180910390fd5b61223d600143034060001c8161313257fe5b06600c819055506000600c5414156131615761315a6001600c5461353f90919063ffffffff16565b600c819055505b565b600a60149054906101000a900460ff1681565b61317e613469565b73ffffffffffffffffffffffffffffffffffffffff1661319c6122d8565b73ffffffffffffffffffffffffffffffffffffffff1614613225576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156132ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260268152602001806149d96026913960400191505060405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600c5481565b613379613469565b73ffffffffffffffffffffffffffffffffffffffff166133976122d8565b73ffffffffffffffffffffffffffffffffffffffff1614613420576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657281525060200191505060405180910390fd5b600a60159054906101000a900460ff1615600a60156101000a81548160ff021916908315150217905550565b6000613462826002613bf290919063ffffffff16565b9050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166134e483611c5c565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061353882600001613c0c565b9050919050565b6000808284019050838110156135bd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601b8152602001807f536166654d6174683a206164646974696f6e206f766572666c6f77000000000081525060200191505060405180910390fd5b8091505092915050565b6135e1828260405180602001604052806000815250613c1d565b5050565b60006135f08261344c565b613645576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252602c815260200180614a49602c913960400191505060405180910390fd5b600061365083611c5c565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806136bf57508373ffffffffffffffffffffffffffffffffffffffff166136a7846113fa565b73ffffffffffffffffffffffffffffffffffffffff16145b806136d057506136cf8185612f65565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff166136f982611c5c565b73ffffffffffffffffffffffffffffffffffffffff1614613765576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526029815260200180614b9a6029913960400191505060405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156137eb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260248152602001806149ff6024913960400191505060405180910390fd5b6137f6838383613c8e565b613801600082613471565b61385281600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020613c9390919063ffffffff16565b506138a481600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020613cad90919063ffffffff16565b506138bb81836002613cc79092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b600061392b8360000183613cfc565b60001c905092915050565b6000806000806139498660000186613d7f565b915091508160001c8160001c8090509350935050509250929050565b806009908051906020019061397b929190614872565b5050565b6000613992846000018460001b84613e18565b60001c90509392505050565b60006139ac82600001613f0e565b9050919050565b6000808314156139c65760009050613a33565b60008284029050828482816139d757fe5b0414613a2e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526021815260200180614b4d6021913960400191505060405180910390fd5b809150505b92915050565b613a448484846136d9565b613a5084848484613f1f565b613aa5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806149856032913960400191505060405180910390fd5b50505050565b60606000821415613af3576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050613bed565b600082905060005b60008214613b1d578080600101915050600a8281613b1557fe5b049150613afb565b60608167ffffffffffffffff81118015613b3657600080fd5b506040519080825280601f01601f191660200182016040528015613b695781602001600182028036833780820191505090505b50905060006001830390508593505b60008414613be557600a8481613b8a57fe5b0660300160f81b82828060019003935081518110613ba457fe5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8481613bdd57fe5b049350613b78565b819450505050505b919050565b6000613c04836000018360001b614164565b905092915050565b600081600001805490509050919050565b613c278383614187565b613c346000848484613f1f565b613c89576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260328152602001806149856032913960400191505060405180910390fd5b505050565b505050565b6000613ca5836000018360001b61437b565b905092915050565b6000613cbf836000018360001b614463565b905092915050565b6000613cf3846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b6144d3565b90509392505050565b600081836000018054905011613d5d576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260228152602001806149186022913960400191505060405180910390fd5b826000018281548110613d6c57fe5b9060005260206000200154905092915050565b60008082846000018054905011613de1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526022815260200180614b006022913960400191505060405180910390fd5b6000846000018481548110613df257fe5b906000526020600020906002020190508060000154816001015492509250509250929050565b60008084600101600085815260200190815260200160002054905060008114158390613edf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015613ea4578082015181840152602081019050613e89565b50505050905090810190601f168015613ed15780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b50846000016001820381548110613ef257fe5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b6000613f408473ffffffffffffffffffffffffffffffffffffffff166145af565b613f4d576001905061415c565b60606140e363150b7a0260e01b613f62613469565b888787604051602401808573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020018473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200183815260200180602001828103825283818151815260200191508051906020019080838360005b83811015614012578082015181840152602081019050613ff7565b50505050905090810190601f16801561403f5780820380516001836020036101000a031916815260200191505b5095505050505050604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff8381831617835250505050604051806060016040528060328152602001614985603291398773ffffffffffffffffffffffffffffffffffffffff166145c29092919063ffffffff16565b905060008180602001905160208110156140fc57600080fd5b8101908080519060200190929190505050905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614925050505b949350505050565b600080836001016000848152602001908152602001600020541415905092915050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561422a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825260208152602001807f4552433732313a206d696e7420746f20746865207a65726f206164647265737381525060200191505060405180910390fd5b6142338161344c565b156142a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601c8152602001807f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000081525060200191505060405180910390fd5b6142b260008383613c8e565b61430381600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020613cad90919063ffffffff16565b5061431a81836002613cc79092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b6000808360010160008481526020019081526020016000205490506000811461445757600060018203905060006001866000018054905003905060008660000182815481106143c657fe5b90600052602060002001549050808760000184815481106143e357fe5b906000526020600020018190555060018301876001016000838152602001908152602001600020819055508660000180548061441b57fe5b6001900381819060005260206000200160009055905586600101600087815260200190815260200160002060009055600194505050505061445d565b60009150505b92915050565b600061446f83836145da565b6144c85782600001829080600181540180825580915050600190039060005260206000200160009091909190915055826000018054905083600101600084815260200190815260200160002081905550600190506144cd565b600090505b92915050565b600080846001016000858152602001908152602001600020549050600081141561457a578460000160405180604001604052808681526020018581525090806001815401808255809150506001900390600052602060002090600202016000909190919091506000820151816000015560208201518160010155505084600001805490508560010160008681526020019081526020016000208190555060019150506145a8565b8285600001600183038154811061458d57fe5b90600052602060002090600202016001018190555060009150505b9392505050565b600080823b905060008111915050919050565b60606145d184846000856145fd565b90509392505050565b600080836001016000848152602001908152602001600020541415905092915050565b606082471015614658576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401808060200182810382526026815260200180614a236026913960400191505060405180910390fd5b614661856145af565b6146d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040180806020018281038252601d8152602001807f416464726573733a2063616c6c20746f206e6f6e2d636f6e747261637400000081525060200191505060405180910390fd5b600060608673ffffffffffffffffffffffffffffffffffffffff1685876040518082805190602001908083835b602083106147235780518252602082019150602081019050602083039250614700565b6001836020036101000a03801982511681845116808217855250505050505090500191505060006040518083038185875af1925050503d8060008114614785576040519150601f19603f3d011682016040523d82523d6000602084013e61478a565b606091505b509150915061479a8282866147a6565b92505050949350505050565b606083156147b65782905061486b565b6000835111156147c95782518084602001fd5b816040517f08c379a00000000000000000000000000000000000000000000000000000000081526004018080602001828103825283818151815260200191508051906020019080838360005b83811015614830578082015181840152602081019050614815565b50505050905090810190601f16801561485d5780820380516001836020036101000a031916815260200191505b509250505060405180910390fd5b9392505050565b828054600181600116156101000203166002900490600052602060002090601f016020900481019282601f106148b357805160ff19168380011785556148e1565b828001600101855582156148e1579182015b828111156148e05782518255916020019190600101906148c5565b5b5090506148ee91906148f2565b5090565b61491491905b808211156149105760008160009055506001016148f8565b5090565b9056fe456e756d657261626c655365743a20696e646578206f7574206f6620626f756e6473507572636861736520776f756c6420657863656564206d61782070726573616c655265736572766520776f756c6420657863656564206d617820737570706c79206f6620426164646965734552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e74657243616e206f6e6c79206d696e74203130206261646469657320617420612074696d654f776e61626c653a206e6577206f776e657220697320746865207a65726f20616464726573734552433732313a207472616e7366657220746f20746865207a65726f2061646472657373416464726573733a20696e73756666696369656e742062616c616e636520666f722063616c6c4552433732313a206f70657261746f7220717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c4552433732313a2062616c616e636520717565727920666f7220746865207a65726f20616464726573734552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656e456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e6473507572636861736520776f756c6420657863656564206d617820737570706c79206f662062616464696573536166654d6174683a206d756c7469706c69636174696f6e206f766572666c6f774552433732313a20617070726f76656420717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a207472616e73666572206f6620746f6b656e2074686174206973206e6f74206f776e4552433732314d657461646174613a2055524920717565727920666f72206e6f6e6578697374656e7420746f6b656e4552433732313a20617070726f76616c20746f2063757272656e74206f776e6572507572636861736520776f756c642065786365656420796f7572206d617820616c6c6f636174696f6e4552433732313a207472616e736665722063616c6c6572206973206e6f74206f776e6572206e6f7220617070726f76656453616c65206d757374206265207374617274656420746f206d696e742062616464696573a264697066735822122016af09d2312a4755f74fe703abe99fce42af724b02f534cee71071a8436ed40a64736f6c63430006060033

Deployed Bytecode Sourcemap

67188:4988:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12:1:-1;9;2:12;10421:150:0;;5:9:-1;2:2;;;27:1;24;17:12;2:2;10421:150:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;10421:150:0;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;51911:100;;5:9:-1;2:2;;;27:1;24;17:12;2:2;51911:100:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;51911:100:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54697:221;;5:9:-1;2:2;;;27:1;24;17:12;2:2;54697:221:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;54697:221:0;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;54227:404;;5:9:-1;2:2;;;27:1;24;17:12;2:2;54227:404:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;54227:404:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;71511:120;;5:9:-1;2:2;;;27:1;24;17:12;2:2;71511:120:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;71511:120:0;;;;;;;;;;27:11:-1;14;11:28;8:2;;;52:1;49;42:12;8:2;71511:120:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;71511:120:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;71511:120:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;71511:120:0;;;;;;;;;;;;;;;:::i;:::-;;53705:211;;5:9:-1;2:2;;;27:1;24;17:12;2:2;53705:211:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;69222:359;;5:9:-1;2:2;;;27:1;24;17:12;2:2;69222:359:0;;;:::i;:::-;;67784:45;;5:9:-1;2:2;;;27:1;24;17:12;2:2;67784:45:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;67784:45:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;55587:305;;5:9:-1;2:2;;;27:1;24;17:12;2:2;55587:305:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;55587:305:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;67603:48;;5:9:-1;2:2;;;27:1;24;17:12;2:2;67603:48:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;53467:162;;5:9:-1;2:2;;;27:1;24;17:12;2:2;53467:162:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;53467:162:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;67458:41;;5:9:-1;2:2;;;27:1;24;17:12;2:2;67458:41:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;67952:89;;5:9:-1;2:2;;;27:1;24;17:12;2:2;67952:89:0;;;:::i;:::-;;67836:52;;5:9:-1;2:2;;;27:1;24;17:12;2:2;67836:52:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;67836:52:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;69080:134;;5:9:-1;2:2;;;27:1;24;17:12;2:2;69080:134:0;;;:::i;:::-;;67307:34;;5:9:-1;2:2;;;27:1;24;17:12;2:2;67307:34:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;55963:151;;5:9:-1;2:2;;;27:1;24;17:12;2:2;55963:151:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;55963:151:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;67506:42;;5:9:-1;2:2;;;27:1;24;17:12;2:2;67506:42:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;53993:172;;5:9:-1;2:2;;;27:1;24;17:12;2:2;53993:172:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;53993:172:0;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;71639:99;;5:9:-1;2:2;;;27:1;24;17:12;2:2;71639:99:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;71639:99:0;;;;;;;;;;27:11:-1;14;11:28;8:2;;;52:1;49;42:12;8:2;71639:99:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;71639:99:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;71639:99:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;71639:99:0;;;;;;;;;;;;;;;:::i;:::-;;68946:126;;5:9:-1;2:2;;;27:1;24;17:12;2:2;68946:126:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;68946:126:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;51667:177;;5:9:-1;2:2;;;27:1;24;17:12;2:2;51667:177:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;51667:177:0;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;67420:29;;5:9:-1;2:2;;;27:1;24;17:12;2:2;67420:29:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;67420:29:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53286:97;;5:9:-1;2:2;;;27:1;24;17:12;2:2;53286:97:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;53286:97:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51384:221;;5:9:-1;2:2;;;27:1;24;17:12;2:2;51384:221:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;51384:221:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;67555:41;;5:9:-1;2:2;;;27:1;24;17:12;2:2;67555:41:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;66533:148;;5:9:-1;2:2;;;27:1;24;17:12;2:2;66533:148:0;;;:::i;:::-;;68155:358;;5:9:-1;2:2;;;27:1;24;17:12;2:2;68155:358:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;68155:358:0;;;;;;;;;;27:11:-1;14;11:28;8:2;;;52:1;49;42:12;8:2;68155:358:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;68155:358:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;68155:358:0;;;;;;;;;;;;:::i;:::-;;65882:87;;5:9:-1;2:2;;;27:1;24;17:12;2:2;65882:87:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;67658:52;;5:9:-1;2:2;;;27:1;24;17:12;2:2;67658:52:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;52080:104;;5:9:-1;2:2;;;27:1;24;17:12;2:2;52080:104:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;52080:104:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68826:108;;5:9:-1;2:2;;;27:1;24;17:12;2:2;68826:108:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;68826:108:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;54990:295;;5:9:-1;2:2;;;27:1;24;17:12;2:2;54990:295:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;54990:295:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;68521:297;;5:9:-1;2:2;;;27:1;24;17:12;2:2;68521:297:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;68521:297:0;;;;;;;;;;27:11:-1;14;11:28;8:2;;;52:1;49;42:12;8:2;68521:297:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;68521:297:0;;;;;;101:9:-1;95:2;81:12;77:21;67:8;63:36;60:51;39:11;25:12;22:29;11:108;8:2;;;132:1;129;122:12;8:2;68521:297:0;;;;;;;;;;;;:::i;:::-;;69589:713;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;69589:713:0;;;;;;;;;;;;;;;;;:::i;:::-;;56185:285;;5:9:-1;2:2;;;27:1;24;17:12;2:2;56185:285:0;;;;;;15:3:-1;10;7:12;4:2;;;32:1;29;22:12;4:2;56185:285:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;27:11:-1;14;11:28;8:2;;;52:1;49;42:12;8:2;56185:285:0;;41:9:-1;34:4;18:14;14:25;11:40;8:2;;;64:1;61;54:12;8:2;56185:285:0;;;;;;100:9:-1;95:1;81:12;77:20;67:8;63:35;60:50;39:11;25:12;22:29;11:107;8:2;;;131:1;128;121:12;8:2;56185:285:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30:3:-1;22:6;14;1:33;99:1;93:3;85:6;81:16;74:27;137:4;133:9;126:4;121:3;117:14;113:30;106:37;;169:3;161:6;157:16;147:26;;56185:285:0;;;;;;;;;;;;;;;:::i;:::-;;71746:427;;5:9:-1;2:2;;;27:1;24;17:12;2:2;71746:427:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;71746:427:0;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;71746:427:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70310:884;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;70310:884:0;;;;;;;;;;;;;;;;;:::i;:::-;;67732:43;;5:9:-1;2:2;;;27:1;24;17:12;2:2;67732:43:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;67348:29;;5:9:-1;2:2;;;27:1;24;17:12;2:2;67348:29:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;55356:164;;5:9:-1;2:2;;;27:1;24;17:12;2:2;55356:164:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;55356:164:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;71202:301;;5:9:-1;2:2;;;27:1;24;17:12;2:2;71202:301:0;;;:::i;:::-;;67269:31;;5:9:-1;2:2;;;27:1;24;17:12;2:2;67269:31:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;66836:244;;5:9:-1;2:2;;;27:1;24;17:12;2:2;66836:244:0;;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;66836:244:0;;;;;;;;;;;;;;;;;;;:::i;:::-;;67384:29;;5:9:-1;2:2;;;27:1;24;17:12;2:2;67384:29:0;;;:::i;:::-;;;;;;;;;;;;;;;;;;;68049:98;;5:9:-1;2:2;;;27:1;24;17:12;2:2;68049:98:0;;;:::i;:::-;;10421:150;10506:4;10530:20;:33;10551:11;10530:33;;;;;;;;;;;;;;;;;;;;;;;;;;;10523:40;;10421:150;;;:::o;51911:100::-;51965:13;51998:5;51991:12;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51911:100;:::o;54697:221::-;54773:7;54801:16;54809:7;54801;:16::i;:::-;54793:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54886:15;:24;54902:7;54886:24;;;;;;;;;;;;;;;;;;;;;54879:31;;54697:221;;;:::o;54227:404::-;54308:13;54324:23;54339:7;54324:14;:23::i;:::-;54308:39;;54372:5;54366:11;;:2;:11;;;;54358:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54452:5;54436:21;;:12;:10;:12::i;:::-;:21;;;:69;;;;54461:44;54485:5;54492:12;:10;:12::i;:::-;54461:23;:44::i;:::-;54436:69;54428:161;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54602:21;54611:2;54615:7;54602:8;:21::i;:::-;54227:404;;;:::o;71511:120::-;66113:12;:10;:12::i;:::-;66102:23;;:7;:5;:7::i;:::-;:23;;;66094:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71609:14:::1;71596:10;:27;;;;;;;;;;;;:::i;:::-;;71511:120:::0;:::o;53705:211::-;53766:7;53887:21;:12;:19;:21::i;:::-;53880:28;;53705:211;:::o;69222:359::-;66113:12;:10;:12::i;:::-;66102:23;;:7;:5;:7::i;:::-;:23;;;66094:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67495:4:::1;69298:33;67773:2;69298:13;:11;:13::i;:::-;:17;;:33;;;;:::i;:::-;:47;;69276:139;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69428:14;69445:13;:11;:13::i;:::-;69428:30;;69474:9;69486:1:::0;69474:13:::1;;69469:105;67773:2;69489:1;:18;69469:105;;;69529:33;69539:10;69560:1;69551:6;:10;69529:9;:33::i;:::-;69509:3;;;;;;;69469:105;;;;66173:1;69222:359::o:0;67784:45::-;;;;;;;;;;;;;;;;;;;;;;:::o;55587:305::-;55748:41;55767:12;:10;:12::i;:::-;55781:7;55748:18;:41::i;:::-;55740:103;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55856:28;55866:4;55872:2;55876:7;55856:9;:28::i;:::-;55587:305;;;:::o;67603:48::-;67650:1;67603:48;:::o;53467:162::-;53564:7;53591:30;53615:5;53591:13;:20;53605:5;53591:20;;;;;;;;;;;;;;;:23;;:30;;;;:::i;:::-;53584:37;;53467:162;;;;:::o;67458:41::-;67495:4;67458:41;:::o;67952:89::-;66113:12;:10;:12::i;:::-;66102:23;;:7;:5;:7::i;:::-;:23;;;66094:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68022:11:::1;;;;;;;;;;;68021:12;68007:11;;:26;;;;;;;;;;;;;;;;;;67952:89::o:0;67836:52::-;;;;;;;;;;;;;;;;;:::o;69080:134::-;66113:12;:10;:12::i;:::-;66102:23;;:7;:5;:7::i;:::-;:23;;;66094:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69128:15:::1;69146:21;69128:39;;69178:10;:19;;:28;69198:7;69178:28;;;;;;;;;;;;;;;;;;;;;;;;8:9:-1;5:2;;;45:16;42:1;39::::0;24:38:::1;77:16;74:1;67:27;5:2;69178:28:0;66173:1;69080:134::o:0;67307:34::-;;;;;;;;;;;;;:::o;55963:151::-;56067:39;56084:4;56090:2;56094:7;56067:39;;;;;;;;;;;;:16;:39::i;:::-;55963:151;;;:::o;67506:42::-;67544:4;67506:42;:::o;53993:172::-;54068:7;54089:15;54110:22;54126:5;54110:12;:15;;:22;;;;:::i;:::-;54088:44;;;54150:7;54143:14;;;53993:172;;;:::o;71639:99::-;66113:12;:10;:12::i;:::-;66102:23;;:7;:5;:7::i;:::-;:23;;;66094:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71710:20:::1;71722:7;71710:11;:20::i;:::-;71639:99:::0;:::o;68946:126::-;69014:7;69041:17;:23;69059:4;69041:23;;;;;;;;;;;;;;;;69034:30;;68946:126;;;:::o;51667:177::-;51739:7;51766:70;51783:7;51766:70;;;;;;;;;;;;;;;;;:12;:16;;:70;;;;;:::i;:::-;51759:77;;51667:177;;;:::o;67420:29::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;53286:97::-;53334:13;53367:8;53360:15;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53286:97;:::o;51384:221::-;51456:7;51501:1;51484:19;;:5;:19;;;;51476:74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51568:29;:13;:20;51582:5;51568:20;;;;;;;;;;;;;;;:27;:29::i;:::-;51561:36;;51384:221;;;:::o;67555:41::-;67594:2;67555:41;:::o;66533:148::-;66113:12;:10;:12::i;:::-;66102:23;;:7;:5;:7::i;:::-;:23;;;66094:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66640:1:::1;66603:40;;66624:6;;;;;;;;;;;66603:40;;;;;;;;;;;;66671:1;66654:6;;:19;;;;;;;;;;;;;;;;;;66533:148::o:0;68155:358::-;66113:12;:10;:12::i;:::-;66102:23;;:7;:5;:7::i;:::-;:23;;;66094:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68243:9:::1;68255:1:::0;68243:13:::1;;68239:264;68262:7;;:14;;68258:1;:18;68239:264;;;68298:13;68314:7;;68322:1;68314:10;;;;;;;;;;;;;;;68298:26;;68364:1;68347:19;;:5;:19;;;;68339:44;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;68407:13;:20;68421:5;68407:20;;;;;;;;;;;;;;;;;;;;;;;;;68406:21;68398:49;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;68487:4;68464:13;:20;68478:5;68464:20;;;;;;;;;;;;;;;;:27;;;;;;;;;;;;;;;;;;68239:264;68278:3;;;;;;;68239:264;;;;68155:358:::0;;:::o;65882:87::-;65928:7;65955:6;;;;;;;;;;;65948:13;;65882:87;:::o;67658:52::-;67697:13;67658:52;:::o;52080:104::-;52136:13;52169:7;52162:14;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;52080:104;:::o;68826:108::-;68883:4;68907:13;:19;68921:4;68907:19;;;;;;;;;;;;;;;;;;;;;;;;;68900:26;;68826:108;;;:::o;54990:295::-;55105:12;:10;:12::i;:::-;55093:24;;:8;:24;;;;55085:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;55205:8;55160:18;:32;55179:12;:10;:12::i;:::-;55160:32;;;;;;;;;;;;;;;:42;55193:8;55160:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;55258:8;55229:48;;55244:12;:10;:12::i;:::-;55229:48;;;55268:8;55229:48;;;;;;;;;;;;;;;;;;;;;;54990:295;;:::o;68521:297::-;66113:12;:10;:12::i;:::-;66102:23;;:7;:5;:7::i;:::-;:23;;;66094:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68614:9:::1;68626:1:::0;68614:13:::1;;68610:201;68633:7;;:14;;68629:1;:18;68610:201;;;68669:13;68685:7;;68693:1;68685:10;;;;;;;;;;;;;;;68669:26;;68735:1;68718:19;;:5;:19;;;;68710:44;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;68794:5;68771:13;:20;68785:5;68771:20;;;;;;;;;;;;;;;;:28;;;;;;;;;;;;;;;;;;68610:201;68649:3;;;;;;;68610:201;;;;68521:297:::0;;:::o;69589:713::-;69670:11;;;;;;;;;;;69662:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67594:2;69755:14;:30;;69733:114;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69858:14;69875:13;:11;:13::i;:::-;69858:30;;67495:4;69921:26;69932:14;69921:6;:10;;:26;;;;:::i;:::-;:40;;69899:133;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70101:9;70065:32;70082:14;67697:13;70065:16;;:32;;;;:::i;:::-;:45;;70043:126;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70195:9;70207:1;70195:13;;70190:105;70214:14;70210:1;:18;70190:105;;;70250:33;70260:10;70281:1;70272:6;:10;70250:9;:33::i;:::-;70230:3;;;;;;;70190:105;;;;69589:713;;:::o;56185:285::-;56317:41;56336:12;:10;:12::i;:::-;56350:7;56317:18;:41::i;:::-;56309:103;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56423:39;56437:4;56443:2;56447:7;56456:5;56423:13;:39::i;:::-;56185:285;;;;:::o;71746:427::-;71811:13;71845:16;71853:7;71845;:16::i;:::-;71837:76;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71934:18;71955:9;:7;:9::i;:::-;71934:30;;71997:1;71979:14;;:19;71975:63;;;72022:4;72015:11;;;;;71975:63;72050:10;67495:4;72074:14;;72064:7;:24;72063:39;;;;;;72050:52;;72144:4;72150:13;:2;:11;:13::i;:::-;72127:37;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;182:3;176:10;171:3;164:23;98:2;93:3;89:12;82:19;;123:2;118:3;114:12;107:19;;148:2;143:3;139:12;132:19;;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;72127:37:0;;;;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;182:3;176:10;171:3;164:23;98:2;93:3;89:12;82:19;;123:2;118:3;114:12;107:19;;148:2;143:3;139:12;132:19;;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;72127:37:0;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;72127:37:0;;;72113:52;;;;71746:427;;;;:::o;70310:884::-;70391:14;;;;;;;;;;;70383:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70443:13;:25;70457:10;70443:25;;;;;;;;;;;;;;;;;;;;;;;;;70435:63;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67544:4;70534:14;70517;;:31;:46;;70509:92;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70612:14;70629:13;:11;:13::i;:::-;70612:30;;67495:4;70661:26;70672:14;70661:6;:10;;:26;;;;:::i;:::-;:40;;70653:96;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67650:1;70800:14;70768:17;:29;70786:10;70768:29;;;;;;;;;;;;;;;;:46;:70;;70760:124;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70939:9;70903:32;70920:14;67697:13;70903:16;;:32;;;;:::i;:::-;:45;;70895:89;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71010:9;71022:1;71010:13;;71005:182;71029:14;71025:1;:18;71005:182;;;71065:14;;:16;;;;;;;;;;;;;71096:17;:29;71114:10;71096:29;;;;;;;;;;;;;;;;:31;;;;;;;;;;;;;71142:33;71152:10;71173:1;71164:6;:10;71142:9;:33::i;:::-;71045:3;;;;;;;71005:182;;;;70310:884;;:::o;67732:43::-;67773:2;67732:43;:::o;67348:29::-;;;;:::o;55356:164::-;55453:4;55477:18;:25;55496:5;55477:25;;;;;;;;;;;;;;;:35;55503:8;55477:35;;;;;;;;;;;;;;;;;;;;;;;;;55470:42;;55356:164;;;;:::o;71202:301::-;66113:12;:10;:12::i;:::-;66102:23;;:7;:5;:7::i;:::-;:23;;;66094:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71284:1:::1;71266:14;;:19;71258:61;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;67495:4;71379:1;71364:12;:16;71354:27;71349:33;;:46;;;;;;71332:14;:63;;;;71428:1;71410:14;;:19;71406:90;;;71463:21;71482:1;71463:14;;:18;;:21;;;;:::i;:::-;71446:14;:38;;;;71406:90;71202:301::o:0;67269:31::-;;;;;;;;;;;;;:::o;66836:244::-;66113:12;:10;:12::i;:::-;66102:23;;:7;:5;:7::i;:::-;:23;;;66094:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66945:1:::1;66925:22;;:8;:22;;;;66917:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67035:8;67006:38;;67027:6;;;;;;;;;;;67006:38;;;;;;;;;;;;67064:8;67055:6;;:17;;;;;;;;;;;;;;;;;;66836:244:::0;:::o;67384:29::-;;;;:::o;68049:98::-;66113:12;:10;:12::i;:::-;66102:23;;:7;:5;:7::i;:::-;:23;;;66094:68;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;68125:14:::1;;;;;;;;;;;68124:15;68107:14;;:32;;;;;;;;;;;;;;;;;;68049:98::o:0;57937:127::-;58002:4;58026:30;58048:7;58026:12;:21;;:30;;;;:::i;:::-;58019:37;;57937:127;;;:::o;667:106::-;720:15;755:10;748:17;;667:106;:::o;63844:183::-;63937:2;63910:15;:24;63926:7;63910:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;63993:7;63989:2;63955:46;;63964:23;63979:7;63964:14;:23::i;:::-;63955:46;;;;;;;;;;;;63844:183;;:::o;44588:123::-;44657:7;44684:19;44692:3;:10;;44684:7;:19::i;:::-;44677:26;;44588:123;;;:::o;14014:179::-;14072:7;14092:9;14108:1;14104;:5;14092:17;;14133:1;14128;:6;;14120:46;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14184:1;14177:8;;;14014:179;;;;:::o;58929:110::-;59005:26;59015:2;59019:7;59005:26;;;;;;;;;;;;:9;:26::i;:::-;58929:110;;:::o;58231:355::-;58324:4;58349:16;58357:7;58349;:16::i;:::-;58341:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58425:13;58441:23;58456:7;58441:14;:23::i;:::-;58425:39;;58494:5;58483:16;;:7;:16;;;:51;;;;58527:7;58503:31;;:20;58515:7;58503:11;:20::i;:::-;:31;;;58483:51;:94;;;;58538:39;58562:5;58569:7;58538:23;:39::i;:::-;58483:94;58475:103;;;58231:355;;;;:::o;61367:599::-;61492:4;61465:31;;:23;61480:7;61465:14;:23::i;:::-;:31;;;61457:85;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61593:1;61579:16;;:2;:16;;;;61571:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61649:39;61670:4;61676:2;61680:7;61649:20;:39::i;:::-;61753:29;61770:1;61774:7;61753:8;:29::i;:::-;61795:35;61822:7;61795:13;:19;61809:4;61795:19;;;;;;;;;;;;;;;:26;;:35;;;;:::i;:::-;;61841:30;61863:7;61841:13;:17;61855:2;61841:17;;;;;;;;;;;;;;;:21;;:30;;;;:::i;:::-;;61884:29;61901:7;61910:2;61884:12;:16;;:29;;;;;:::i;:::-;;61950:7;61946:2;61931:27;;61940:4;61931:27;;;;;;;;;;;;61367:599;;;:::o;36348:137::-;36419:7;36454:22;36458:3;:10;;36470:5;36454:3;:22::i;:::-;36446:31;;36439:38;;36348:137;;;;:::o;45050:236::-;45130:7;45139;45160:11;45173:13;45190:22;45194:3;:10;;45206:5;45190:3;:22::i;:::-;45159:53;;;;45239:3;45231:12;;45269:5;45261:14;;45223:55;;;;;;;;;45050:236;;;;;:::o;62567:100::-;62651:8;62640;:19;;;;;;;;;;;;:::i;:::-;;62567:100;:::o;46336:213::-;46443:7;46494:44;46499:3;:10;;46519:3;46511:12;;46525;46494:4;:44::i;:::-;46486:53;;46463:78;;46336:213;;;;;:::o;35890:114::-;35950:7;35977:19;35985:3;:10;;35977:7;:19::i;:::-;35970:26;;35890:114;;;:::o;14893:220::-;14951:7;14980:1;14975;:6;14971:20;;;14990:1;14983:8;;;;14971:20;15002:9;15018:1;15014;:5;15002:17;;15047:1;15042;15038;:5;;;;;;:10;15030:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15104:1;15097:8;;;14893:220;;;;;:::o;57352:272::-;57466:28;57476:4;57482:2;57486:7;57466:9;:28::i;:::-;57513:48;57536:4;57542:2;57546:7;57555:5;57513:22;:48::i;:::-;57505:111;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57352:272;;;;:::o;46831:746::-;46887:13;47117:1;47108:5;:10;47104:53;;;47135:10;;;;;;;;;;;;;;;;;;;;;47104:53;47167:12;47182:5;47167:20;;47198:14;47223:78;47238:1;47230:4;:9;47223:78;;47256:8;;;;;;;47287:2;47279:10;;;;;;;;;47223:78;;;47311:19;47343:6;47333:17;;;5:9:-1;2:2;;;27:1;24;17:12;2:2;47333:17:0;;;;;;;;;;;;;;;;;;;;;;;;;;29:1:-1;21:6;17:14;124:4;108:14;100:6;87:42;155:4;147:6;143:17;133:27;;0:164;47333:17:0;;;;47311:39;;47361:13;47386:1;47377:6;:10;47361:26;;47405:5;47398:12;;47421:117;47436:1;47428:4;:9;47421:117;;47497:2;47490:4;:9;;;;;;47485:2;:14;47472:29;;47454:6;47461:7;;;;;;;47454:15;;;;;;;;;;;:47;;;;;;;;;;;47524:2;47516:10;;;;;;;;;47421:117;;;47562:6;47548:21;;;;;;46831:746;;;;:::o;44349:151::-;44433:4;44457:35;44467:3;:10;;44487:3;44479:12;;44457:9;:35::i;:::-;44450:42;;44349:151;;;;:::o;41167:110::-;41223:7;41250:3;:12;;:19;;;;41243:26;;41167:110;;;:::o;59266:250::-;59362:18;59368:2;59372:7;59362:5;:18::i;:::-;59399:54;59430:1;59434:2;59438:7;59447:5;59399:22;:54::i;:::-;59391:117;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;59266:250;;;:::o;64640:93::-;;;;:::o;35435:137::-;35505:4;35529:35;35537:3;:10;;35557:5;35549:14;;35529:7;:35::i;:::-;35522:42;;35435:137;;;;:::o;35128:131::-;35195:4;35219:32;35224:3;:10;;35244:5;35236:14;;35219:4;:32::i;:::-;35212:39;;35128:131;;;;:::o;43772:185::-;43861:4;43885:64;43890:3;:10;;43910:3;43902:12;;43940:5;43924:23;;43916:32;;43885:4;:64::i;:::-;43878:71;;43772:185;;;;;:::o;31386:204::-;31453:7;31502:5;31481:3;:11;;:18;;;;:26;31473:73;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;31564:3;:11;;31576:5;31564:18;;;;;;;;;;;;;;;;31557:25;;31386:204;;;;:::o;41632:279::-;41699:7;41708;41758:5;41736:3;:12;;:19;;;;:27;41728:74;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41815:22;41840:3;:12;;41853:5;41840:19;;;;;;;;;;;;;;;;;;41815:44;;41878:5;:10;;;41890:5;:12;;;41870:33;;;;;41632:279;;;;;:::o;43129:319::-;43223:7;43243:16;43262:3;:12;;:17;43275:3;43262:17;;;;;;;;;;;;43243:36;;43310:1;43298:8;:13;;43313:12;43290:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;43290:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;43380:3;:12;;43404:1;43393:8;:12;43380:26;;;;;;;;;;;;;;;;;;:33;;;43373:40;;;43129:319;;;;;:::o;30933:109::-;30989:7;31016:3;:11;;:18;;;;31009:25;;30933:109;;;:::o;63232:604::-;63353:4;63380:15;:2;:13;;;:15::i;:::-;63375:60;;63419:4;63412:11;;;;63375:60;63445:23;63471:252;63524:45;;;63584:12;:10;:12::i;:::-;63611:4;63630:7;63652:5;63487:181;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;63487:181:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49:4:-1;39:7;30;26:21;22:32;13:7;6:49;63487:181:0;;;;;;;38:4:-1;29:7;25:18;67:10;61:17;96:58;199:8;192:4;186;182:15;179:29;167:10;160:49;0:215;;;63487:181:0;63471:252;;;;;;;;;;;;;;;;;:2;:15;;;;:252;;;;;:::i;:::-;63445:278;;63734:13;63761:10;63750:32;;;;;15:2:-1;10:3;7:11;4:2;;;31:1;28;21:12;4:2;63750:32:0;;;;;;;;;;;;;;;;63734:48;;48381:10;63811:16;;63801:26;;;:6;:26;;;;63793:35;;;;63232:604;;;;;;;:::o;40947:125::-;41018:4;41063:1;41042:3;:12;;:17;41055:3;41042:17;;;;;;;;;;;;:22;;41035:29;;40947:125;;;;:::o;59852:404::-;59946:1;59932:16;;:2;:16;;;;59924:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60005:16;60013:7;60005;:16::i;:::-;60004:17;59996:58;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60067:45;60096:1;60100:2;60104:7;60067:20;:45::i;:::-;60125:30;60147:7;60125:13;:17;60139:2;60125:17;;;;;;;;;;;;;;;:21;;:30;;;;:::i;:::-;;60168:29;60185:7;60194:2;60168:12;:16;;:29;;;;;:::i;:::-;;60240:7;60236:2;60215:33;;60232:1;60215:33;;;;;;;;;;;;59852:404;;:::o;29088:1544::-;29154:4;29272:18;29293:3;:12;;:19;29306:5;29293:19;;;;;;;;;;;;29272:40;;29343:1;29329:10;:15;29325:1300;;29691:21;29728:1;29715:10;:14;29691:38;;29744:17;29785:1;29764:3;:11;;:18;;;;:22;29744:42;;30031:17;30051:3;:11;;30063:9;30051:22;;;;;;;;;;;;;;;;30031:42;;30197:9;30168:3;:11;;30180:13;30168:26;;;;;;;;;;;;;;;:38;;;;30316:1;30300:13;:17;30274:3;:12;;:23;30287:9;30274:23;;;;;;;;;;;:43;;;;30426:3;:11;;:17;;;;;;;;;;;;;;;;;;;;;;;;30521:3;:12;;:19;30534:5;30521:19;;;;;;;;;;;30514:26;;;30564:4;30557:11;;;;;;;;29325:1300;30608:5;30601:12;;;29088:1544;;;;;:::o;28498:414::-;28561:4;28583:21;28593:3;28598:5;28583:9;:21::i;:::-;28578:327;;28621:3;:11;;28638:5;28621:23;;39:1:-1;33:3;27:10;23:18;57:10;52:3;45:23;79:10;72:17;;0:93;28621:23:0;;;;;;;;;;;;;;;;;;;28804:3;:11;;:18;;;;28782:3;:12;;:19;28795:5;28782:19;;;;;;;;;;;:40;;;;28844:4;28837:11;;;;28578:327;28888:5;28881:12;;28498:414;;;;;:::o;38447:692::-;38523:4;38639:16;38658:3;:12;;:17;38671:3;38658:17;;;;;;;;;;;;38639:36;;38704:1;38692:8;:13;38688:444;;;38759:3;:12;;38777:38;;;;;;;;38794:3;38777:38;;;;38807:5;38777:38;;;38759:57;;39:1:-1;33:3;27:10;23:18;57:10;52:3;45:23;79:10;72:17;;0:93;38759:57:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;38974:3;:12;;:19;;;;38954:3;:12;;:17;38967:3;38954:17;;;;;;;;;;;:39;;;;39015:4;39008:11;;;;;38688:444;39088:5;39052:3;:12;;39076:1;39065:8;:12;39052:26;;;;;;;;;;;;;;;;;;:33;;:41;;;;39115:5;39108:12;;;38447:692;;;;;;:::o;19486:422::-;19546:4;19754:12;19865:7;19853:20;19845:28;;19899:1;19892:4;:8;19885:15;;;19486:422;;;:::o;22404:195::-;22507:12;22539:52;22561:6;22569:4;22575:1;22578:12;22539:21;:52::i;:::-;22532:59;;22404:195;;;;;:::o;30718:129::-;30791:4;30838:1;30815:3;:12;;:19;30828:5;30815:19;;;;;;;;;;;;:24;;30808:31;;30718:129;;;;:::o;23456:530::-;23583:12;23641:5;23616:21;:30;;23608:81;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23708:18;23719:6;23708:10;:18::i;:::-;23700:60;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23834:12;23848:23;23875:6;:11;;23895:5;23903:4;23875:33;;;;;;;;;;;;;36:153:-1;66:2;61:3;58:11;36:153;;182:3;176:10;171:3;164:23;98:2;93:3;89:12;82:19;;123:2;118:3;114:12;107:19;;148:2;143:3;139:12;132:19;;36:153;;;274:1;267:3;263:2;259:12;254:3;250:22;246:30;315:4;311:9;305:3;299:10;295:26;356:4;350:3;344:10;340:21;389:7;380;377:20;372:3;365:33;3:399;;;23875:33:0;;;;;;;;;;;;;;;;;;;;;;;;;12:1:-1;19;14:27;;;;67:4;61:11;56:16;;134:4;130:9;123:4;105:16;101:27;97:43;94:1;90:51;84:4;77:65;157:16;154:1;147:27;211:16;208:1;201:4;198:1;194:12;179:49;5:228;;14:27;32:4;27:9;;5:228;;23833:75:0;;;;23926:52;23944:7;23953:10;23965:12;23926:17;:52::i;:::-;23919:59;;;;23456:530;;;;;;:::o;25996:742::-;26111:12;26140:7;26136:595;;;26171:10;26164:17;;;;26136:595;26305:1;26285:10;:17;:21;26281:439;;;26548:10;26542:17;26609:15;26596:10;26592:2;26588:19;26581:44;26496:148;26691:12;26684:20;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23:1:-1;8:100;33:3;30:1;27:10;8:100;;;99:1;94:3;90:11;84:18;80:1;75:3;71:11;64:39;52:2;49:1;45:10;40:15;;8:100;;;12:14;26684:20:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25996:742;;;;;;:::o;67188:4988::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o

Swarm Source

ipfs://16af09d2312a4755f74fe703abe99fce42af724b02f534cee71071a8436ed40a
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.