ETH Price: $3,436.18 (-1.20%)
Gas: 4 Gwei

Token

Sevens Token (SEVENS)
 

Overview

Max Total Supply

7,000 SEVENS

Holders

2,793

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 SEVENS
0x46cfdc89d19c83d9a5f8a6a26411720d8b8371d4
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

The Sevens is a collection of 7000 algorithmically generated pieces of art with references from pop culture, anime, games, memes and movies.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
TheSevens

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 999999 runs

Other Settings:
istanbul EvmVersion, MIT license

Contract Source Code (Solidity)

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

// SPDX-License-Identifier: MIT

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

pragma solidity ^0.8.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with meta-transactions the account sending and
 * paying for execution may not be the actual sender (as far as an application
 * is concerned).
 *
 * This contract is only required for intermediate, library-like contracts.
 */
abstract contract Context {
    function _msgSender() internal view virtual returns (address) {
        return msg.sender;
    }

    function _msgData() internal view virtual returns (bytes calldata) {
        return msg.data;
    }
}

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

pragma solidity ^0.8.0;

/**
 * @dev Contract module which provides a basic access control mechanism, where
 * there is an account (an owner) that can be granted exclusive access to
 * specific functions.
 *
 * By default, the owner account will be the one that deploys the contract. This
 * can later be changed with {transferOwnership}.
 *
 * This module is used through inheritance. It will make available the modifier
 * `onlyOwner`, which can be applied to your functions to restrict their use to
 * the owner.
 */
abstract contract Ownable is Context {
    address private _owner;

    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _setOwner(_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 {
        _setOwner(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");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

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

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

pragma solidity ^0.8.0;

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

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

pragma solidity ^0.8.0;

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

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

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

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

pragma solidity ^0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

    /**
     * @dev Replacement for Solidity's `transfer`: sends `amount` wei to
     * `recipient`, forwarding all available gas and reverting on errors.
     *
     * https://eips.ethereum.org/EIPS/eip-1884[EIP1884] increases the gas cost
     * of certain opcodes, possibly making contracts go over the 2300 gas limit
     * imposed by `transfer`, making them unable to receive funds via
     * `transfer`. {sendValue} removes this limitation.
     *
     * https://diligence.consensys.net/posts/2019/09/stop-using-soliditys-transfer-now/[Learn more].
     *
     * IMPORTANT: because control is transferred to `recipient`, care must be
     * taken to not create reentrancy vulnerabilities. Consider using
     * {ReentrancyGuard} or the
     * https://solidity.readthedocs.io/en/v0.5.11/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        require(address(this).balance >= amount, "Address: insufficient balance");

        (bool success, ) = recipient.call{value: amount}("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

    /**
     * @dev Performs a Solidity function call using a low level `call`. A
     * plain `call` is an unsafe replacement for a function call: use this
     * function instead.
     *
     * If `target` reverts with a revert reason, it is bubbled up by this
     * function (like regular Solidity function calls).
     *
     * Returns the raw returned data. To convert to the expected return value,
     * use https://solidity.readthedocs.io/en/latest/units-and-global-variables.html?highlight=abi.decode#abi-encoding-and-decoding-functions[`abi.decode`].
     *
     * Requirements:
     *
     * - `target` must be a contract.
     * - calling `target` with `data` must not revert.
     *
     * _Available since v3.1._
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCall(target, data, "Address: low-level call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`], but with
     * `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but also transferring `value` wei to `target`.
     *
     * Requirements:
     *
     * - the calling contract must have an ETH balance of at least `value`.
     * - the called Solidity function must be `payable`.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value
    ) internal returns (bytes memory) {
        return functionCallWithValue(target, data, value, "Address: low-level call with value failed");
    }

    /**
     * @dev Same as {xref-Address-functionCallWithValue-address-bytes-uint256-}[`functionCallWithValue`], but
     * with `errorMessage` as a fallback revert reason when `target` reverts.
     *
     * _Available since v3.1._
     */
    function functionCallWithValue(
        address target,
        bytes memory data,
        uint256 value,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(address(this).balance >= value, "Address: insufficient balance for call");
        require(isContract(target), "Address: call to non-contract");

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        return functionStaticCall(target, data, "Address: low-level static call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionDelegateCall(target, data, "Address: low-level delegate call failed");
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

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

    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

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

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

pragma solidity ^0.8.0;

/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts that want to implement ERC165 should inherit from this contract and override {supportsInterface} to check
 * for the additional interface id that will be supported. For example:
 *
 * ```solidity
 * function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
 *     return interfaceId == type(MyInterface).interfaceId || super.supportsInterface(interfaceId);
 * }
 * ```
 *
 * Alternatively, {ERC165Storage} provides an easier to use but more expensive implementation.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

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

pragma solidity ^0.8.0;

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

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

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

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

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not 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 _owners[tokenId] != address(0);
    }

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @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");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(from, to, tokenId);
    }

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

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

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

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

pragma solidity ^0.8.0;

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

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

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

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

pragma solidity ^0.8.0;

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

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

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

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        require(signer != address(0), "ECDSA: invalid signature");

        return signer;
    }

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

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

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

pragma solidity ^0.8.0;

/**
 * @dev Wrappers over Solidity's uintXX/intXX casting operators with added overflow
 * checks.
 *
 * Downcasting from uint256/int256 in Solidity does not revert on overflow. This can
 * easily result in undesired exploitation or bugs, since developers usually
 * assume that overflows raise errors. `SafeCast` restores this intuition by
 * reverting the transaction when such 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.
 *
 * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
 * all math on `uint256` and `int256` and then downcasting.
 */
library SafeCast {
    /**
     * @dev Returns the downcasted uint224 from uint256, reverting on
     * overflow (when the input is greater than largest uint224).
     *
     * Counterpart to Solidity's `uint224` operator.
     *
     * Requirements:
     *
     * - input must fit into 224 bits
     */
    function toUint224(uint256 value) internal pure returns (uint224) {
        require(value <= type(uint224).max, "SafeCast: value doesn't fit in 224 bits");
        return uint224(value);
    }

    /**
     * @dev Returns the downcasted uint128 from uint256, reverting on
     * overflow (when the input is greater than largest uint128).
     *
     * Counterpart to Solidity's `uint128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     */
    function toUint128(uint256 value) internal pure returns (uint128) {
        require(value <= type(uint128).max, "SafeCast: value doesn't fit in 128 bits");
        return uint128(value);
    }

    /**
     * @dev Returns the downcasted uint96 from uint256, reverting on
     * overflow (when the input is greater than largest uint96).
     *
     * Counterpart to Solidity's `uint96` operator.
     *
     * Requirements:
     *
     * - input must fit into 96 bits
     */
    function toUint96(uint256 value) internal pure returns (uint96) {
        require(value <= type(uint96).max, "SafeCast: value doesn't fit in 96 bits");
        return uint96(value);
    }

    /**
     * @dev Returns the downcasted uint64 from uint256, reverting on
     * overflow (when the input is greater than largest uint64).
     *
     * Counterpart to Solidity's `uint64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     */
    function toUint64(uint256 value) internal pure returns (uint64) {
        require(value <= type(uint64).max, "SafeCast: value doesn't fit in 64 bits");
        return uint64(value);
    }

    /**
     * @dev Returns the downcasted uint32 from uint256, reverting on
     * overflow (when the input is greater than largest uint32).
     *
     * Counterpart to Solidity's `uint32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     */
    function toUint32(uint256 value) internal pure returns (uint32) {
        require(value <= type(uint32).max, "SafeCast: value doesn't fit in 32 bits");
        return uint32(value);
    }

    /**
     * @dev Returns the downcasted uint16 from uint256, reverting on
     * overflow (when the input is greater than largest uint16).
     *
     * Counterpart to Solidity's `uint16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     */
    function toUint16(uint256 value) internal pure returns (uint16) {
        require(value <= type(uint16).max, "SafeCast: value doesn't fit in 16 bits");
        return uint16(value);
    }

    /**
     * @dev Returns the downcasted uint8 from uint256, reverting on
     * overflow (when the input is greater than largest uint8).
     *
     * Counterpart to Solidity's `uint8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits.
     */
    function toUint8(uint256 value) internal pure returns (uint8) {
        require(value <= type(uint8).max, "SafeCast: value doesn't fit in 8 bits");
        return uint8(value);
    }

    /**
     * @dev Converts a signed int256 into an unsigned uint256.
     *
     * Requirements:
     *
     * - input must be greater than or equal to 0.
     */
    function toUint256(int256 value) internal pure returns (uint256) {
        require(value >= 0, "SafeCast: value must be positive");
        return uint256(value);
    }

    /**
     * @dev Returns the downcasted int128 from int256, reverting on
     * overflow (when the input is less than smallest int128 or
     * greater than largest int128).
     *
     * Counterpart to Solidity's `int128` operator.
     *
     * Requirements:
     *
     * - input must fit into 128 bits
     *
     * _Available since v3.1._
     */
    function toInt128(int256 value) internal pure returns (int128) {
        require(value >= type(int128).min && value <= type(int128).max, "SafeCast: value doesn't fit in 128 bits");
        return int128(value);
    }

    /**
     * @dev Returns the downcasted int64 from int256, reverting on
     * overflow (when the input is less than smallest int64 or
     * greater than largest int64).
     *
     * Counterpart to Solidity's `int64` operator.
     *
     * Requirements:
     *
     * - input must fit into 64 bits
     *
     * _Available since v3.1._
     */
    function toInt64(int256 value) internal pure returns (int64) {
        require(value >= type(int64).min && value <= type(int64).max, "SafeCast: value doesn't fit in 64 bits");
        return int64(value);
    }

    /**
     * @dev Returns the downcasted int32 from int256, reverting on
     * overflow (when the input is less than smallest int32 or
     * greater than largest int32).
     *
     * Counterpart to Solidity's `int32` operator.
     *
     * Requirements:
     *
     * - input must fit into 32 bits
     *
     * _Available since v3.1._
     */
    function toInt32(int256 value) internal pure returns (int32) {
        require(value >= type(int32).min && value <= type(int32).max, "SafeCast: value doesn't fit in 32 bits");
        return int32(value);
    }

    /**
     * @dev Returns the downcasted int16 from int256, reverting on
     * overflow (when the input is less than smallest int16 or
     * greater than largest int16).
     *
     * Counterpart to Solidity's `int16` operator.
     *
     * Requirements:
     *
     * - input must fit into 16 bits
     *
     * _Available since v3.1._
     */
    function toInt16(int256 value) internal pure returns (int16) {
        require(value >= type(int16).min && value <= type(int16).max, "SafeCast: value doesn't fit in 16 bits");
        return int16(value);
    }

    /**
     * @dev Returns the downcasted int8 from int256, reverting on
     * overflow (when the input is less than smallest int8 or
     * greater than largest int8).
     *
     * Counterpart to Solidity's `int8` operator.
     *
     * Requirements:
     *
     * - input must fit into 8 bits.
     *
     * _Available since v3.1._
     */
    function toInt8(int256 value) internal pure returns (int8) {
        require(value >= type(int8).min && value <= type(int8).max, "SafeCast: value doesn't fit in 8 bits");
        return int8(value);
    }

    /**
     * @dev Converts an unsigned uint256 into a signed int256.
     *
     * Requirements:
     *
     * - input must be less than or equal to maxInt256.
     */
    function toInt256(uint256 value) internal pure returns (int256) {
        // Note: Unsafe cast below is okay because `type(int256).max` is guaranteed to be positive
        require(value <= uint256(type(int256).max), "SafeCast: value doesn't fit in an int256");
        return int256(value);
    }
}

// File contracts/TheSevens.sol

pragma solidity =0.8.7;

contract TheSevens is ERC721Enumerable, Ownable {
    using ECDSA for bytes32;
    using SafeCast for uint256;

    event TokenPriceChanged(uint256 newTokenPrice);
    event PresaleConfigChanged(address whitelistSigner, uint32 startTime, uint32 endTime);
    event SaleConfigChanged(uint32 startTime, uint32 initMaxCount, uint32 maxCountUnlockTime, uint32 unlockedMaxCount);
    event IsBurnEnabledChanged(bool newIsBurnEnabled);
    event TreasuryChanged(address newTreasury);
    event BaseURIChanged(string newBaseURI);
    event PresaleMint(address minter, uint256 count);
    event SaleMint(address minter, uint256 count);

    // Both structs fit in a single storage slot for gas optimization
    struct PresaleConfig {
        address whitelistSigner;
        uint32 startTime;
        uint32 endTime;
    }
    struct SaleConfig {
        uint32 startTime;
        uint32 initMaxCount;
        uint32 maxCountUnlockTime;
        uint32 unlockedMaxCount;
    }

    uint256 public immutable maxSupply;
    uint256 public immutable reserveCount;

    uint256 public tokensReserved;
    uint256 public nextTokenId;
    bool public isBurnEnabled;
    address payable public treasury;

    uint256 public tokenPrice;

    PresaleConfig public presaleConfig;
    mapping(address => uint256) public presaleBoughtCounts;

    SaleConfig public saleConfig;

    string public baseURI;

    bytes32 public DOMAIN_SEPARATOR;
    bytes32 public constant PRESALE_TYPEHASH = keccak256("Presale(address buyer,uint256 maxCount)");

    constructor(uint256 _maxSupply, uint256 _reserveCount) ERC721("Sevens Token", "SEVENS") {
        require(_reserveCount <= _maxSupply, "TheSevens: reserve count out of range");

        maxSupply = _maxSupply;
        reserveCount = _reserveCount;

        uint256 chainId;
        assembly {
            chainId := chainid()
        }
        DOMAIN_SEPARATOR = keccak256(
            abi.encode(
                keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)"),
                keccak256(bytes("The Sevens")),
                keccak256(bytes("1")),
                chainId,
                address(this)
            )
        );
    }

    function reserveTokens(address recipient, uint256 count) external onlyOwner {
        require(recipient != address(0), "TheSevens: zero address");

        // Gas optimization
        uint256 _nextTokenId = nextTokenId;

        require(count > 0, "TheSevens: invalid count");
        require(_nextTokenId + count <= maxSupply, "TheSevens: max supply exceeded");

        require(tokensReserved + count <= reserveCount, "TheSevens: max reserve count exceeded");
        tokensReserved += count;

        for (uint256 ind = 0; ind < count; ind++) {
            _safeMint(recipient, _nextTokenId + ind);
        }
        nextTokenId += count;
    }

    function setTokenPrice(uint256 _tokenPrice) external onlyOwner {
        tokenPrice = _tokenPrice;
        emit TokenPriceChanged(_tokenPrice);
    }

    function setUpPresale(
        address whitelistSigner,
        uint256 startTime,
        uint256 endTime
    ) external onlyOwner {
        uint32 _startTime = startTime.toUint32();
        uint32 _endTime = endTime.toUint32();

        // Check params
        require(whitelistSigner != address(0), "TheSevens: zero address");
        require(_startTime > 0 && _endTime > _startTime, "TheSevens: invalid time range");

        presaleConfig = PresaleConfig({whitelistSigner: whitelistSigner, startTime: _startTime, endTime: _endTime});

        emit PresaleConfigChanged(whitelistSigner, _startTime, _endTime);
    }

    function setUpSale(
        uint256 startTime,
        uint256 initMaxCount,
        uint256 maxCountUnlockTime,
        uint256 unlockedMaxCount
    ) external onlyOwner {
        uint32 _startTime = startTime.toUint32();
        uint32 _initMaxCount = initMaxCount.toUint32();
        uint32 _maxCountUnlockTime = maxCountUnlockTime.toUint32();
        uint32 _unlockedMaxCount = unlockedMaxCount.toUint32();

        require(_initMaxCount > 0 && _unlockedMaxCount > 0, "TheSevens: zero amount");
        require(_startTime > 0 && _maxCountUnlockTime > _startTime, "TheSevens: invalid time range");

        saleConfig = SaleConfig({
            startTime: _startTime,
            initMaxCount: _initMaxCount,
            maxCountUnlockTime: _maxCountUnlockTime,
            unlockedMaxCount: _unlockedMaxCount
        });

        emit SaleConfigChanged(_startTime, _initMaxCount, _maxCountUnlockTime, _unlockedMaxCount);
    }

    function setIsBurnEnabled(bool _isBurnEnabled) external onlyOwner {
        isBurnEnabled = _isBurnEnabled;
        emit IsBurnEnabledChanged(_isBurnEnabled);
    }

    function setTreasury(address payable _treasury) external onlyOwner {
        treasury = _treasury;
        emit TreasuryChanged(_treasury);
    }

    function setBaseURI(string calldata newbaseURI) external onlyOwner {
        baseURI = newbaseURI;
        emit BaseURIChanged(newbaseURI);
    }

    function mintPresaleTokens(
        uint256 count,
        uint256 maxCount,
        bytes calldata signature
    ) external payable {
        // Gas optimization
        uint256 _nextTokenId = nextTokenId;

        // Make sure presale has been set up
        PresaleConfig memory _presaleConfig = presaleConfig;
        require(_presaleConfig.whitelistSigner != address(0), "TheSevens: presale not configured");

        require(treasury != address(0), "TheSevens: treasury not set");
        require(tokenPrice > 0, "TheSevens: token price not set");
        require(count > 0, "TheSevens: invalid count");
        require(block.timestamp >= _presaleConfig.startTime, "TheSevens: presale not started");
        require(block.timestamp < _presaleConfig.endTime, "TheSevens: presale ended");

        require(_nextTokenId + count <= maxSupply, "TheSevens: max supply exceeded");
        require(tokenPrice * count == msg.value, "TheSevens: incorrect Ether value");

        // Verify EIP-712 signature
        bytes32 digest = keccak256(
            abi.encodePacked("\x19\x01", DOMAIN_SEPARATOR, keccak256(abi.encode(PRESALE_TYPEHASH, msg.sender, maxCount)))
        );
        address recoveredAddress = digest.recover(signature);
        require(
            recoveredAddress != address(0) && recoveredAddress == _presaleConfig.whitelistSigner,
            "TheSevens: invalid signature"
        );

        require(presaleBoughtCounts[msg.sender] + count <= maxCount, "TheSevens: presale max count exceeded");
        presaleBoughtCounts[msg.sender] += count;

        // The contract never holds any Ether. Everything gets redirected to treasury directly.
        treasury.transfer(msg.value);

        for (uint256 ind = 0; ind < count; ind++) {
            _safeMint(msg.sender, _nextTokenId + ind);
        }
        nextTokenId += count;

        emit PresaleMint(msg.sender, count);
    }

    function mintTokens(uint256 count) external payable {
        // Gas optimization
        uint256 _nextTokenId = nextTokenId;

        // Make sure presale has been set up
        SaleConfig memory _saleConfig = saleConfig;
        require(_saleConfig.startTime > 0, "TheSevens: sale not configured");

        require(treasury != address(0), "TheSevens: treasury not set");
        require(tokenPrice > 0, "TheSevens: token price not set");
        require(count > 0, "TheSevens: invalid count");
        require(block.timestamp >= _saleConfig.startTime, "TheSevens: sale not started");

        require(
            count <=
                (
                    block.timestamp >= _saleConfig.maxCountUnlockTime
                        ? _saleConfig.unlockedMaxCount
                        : _saleConfig.initMaxCount
                ),
            "TheSevens: max count per tx exceeded"
        );
        require(_nextTokenId + count <= maxSupply, "TheSevens: max supply exceeded");
        require(tokenPrice * count == msg.value, "TheSevens: incorrect Ether value");

        // The contract never holds any Ether. Everything gets redirected to treasury directly.
        treasury.transfer(msg.value);

        for (uint256 ind = 0; ind < count; ind++) {
            _safeMint(msg.sender, _nextTokenId + ind);
        }
        nextTokenId += count;

        emit SaleMint(msg.sender, count);
    }

    function burn(uint256 tokenId) external {
        require(isBurnEnabled, "TheSevens: burning disabled");
        require(_isApprovedOrOwner(msg.sender, tokenId), "TheSevens: burn caller is not owner nor approved");
        _burn(tokenId);
    }

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"uint256","name":"_maxSupply","type":"uint256"},{"internalType":"uint256","name":"_reserveCount","type":"uint256"}],"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":false,"internalType":"string","name":"newBaseURI","type":"string"}],"name":"BaseURIChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bool","name":"newIsBurnEnabled","type":"bool"}],"name":"IsBurnEnabledChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"whitelistSigner","type":"address"},{"indexed":false,"internalType":"uint32","name":"startTime","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"endTime","type":"uint32"}],"name":"PresaleConfigChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"uint256","name":"count","type":"uint256"}],"name":"PresaleMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint32","name":"startTime","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"initMaxCount","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"maxCountUnlockTime","type":"uint32"},{"indexed":false,"internalType":"uint32","name":"unlockedMaxCount","type":"uint32"}],"name":"SaleConfigChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"minter","type":"address"},{"indexed":false,"internalType":"uint256","name":"count","type":"uint256"}],"name":"SaleMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"newTokenPrice","type":"uint256"}],"name":"TokenPriceChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newTreasury","type":"address"}],"name":"TreasuryChanged","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRESALE_TYPEHASH","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isBurnEnabled","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"count","type":"uint256"},{"internalType":"uint256","name":"maxCount","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"mintPresaleTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"name":"mintTokens","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"presaleBoughtCounts","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"presaleConfig","outputs":[{"internalType":"address","name":"whitelistSigner","type":"address"},{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"endTime","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reserveCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"count","type":"uint256"}],"name":"reserveTokens","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":[],"name":"saleConfig","outputs":[{"internalType":"uint32","name":"startTime","type":"uint32"},{"internalType":"uint32","name":"initMaxCount","type":"uint32"},{"internalType":"uint32","name":"maxCountUnlockTime","type":"uint32"},{"internalType":"uint32","name":"unlockedMaxCount","type":"uint32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newbaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_isBurnEnabled","type":"bool"}],"name":"setIsBurnEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenPrice","type":"uint256"}],"name":"setTokenPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"_treasury","type":"address"}],"name":"setTreasury","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"whitelistSigner","type":"address"},{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"endTime","type":"uint256"}],"name":"setUpPresale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"startTime","type":"uint256"},{"internalType":"uint256","name":"initMaxCount","type":"uint256"},{"internalType":"uint256","name":"maxCountUnlockTime","type":"uint256"},{"internalType":"uint256","name":"unlockedMaxCount","type":"uint256"}],"name":"setUpSale","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":[],"name":"tokenPrice","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":"tokensReserved","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"treasury","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

60c06040523480156200001157600080fd5b5060405162004efe38038062004efe8339810160408190526200003491620002f5565b604080518082018252600c81526b29b2bb32b739902a37b5b2b760a11b602080830191825283518085019094526006845265534556454e5360d01b90840152815191929162000086916000916200024f565b5080516200009c9060019060208401906200024f565b505050620000b9620000b3620001f960201b60201c565b620001fd565b818111156200011c5760405162461bcd60e51b815260206004820152602560248201527f546865536576656e733a207265736572766520636f756e74206f7574206f662060448201526472616e676560d81b606482015260840160405180910390fd5b608091825260a0908152604080518082018252600a81526954686520536576656e7360b01b6020918201528151808301835260018152603160f81b9082015281517f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f818301527f0ab5980cd5d0e231ff75911bdfbd21f86f13e5697593457def0e644f767be9ba818401527fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc66060820152469481019490945230848401528151808503909301835260c09093019052805191012060135562000357565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b8280546200025d906200031a565b90600052602060002090601f016020900481019282620002815760008555620002cc565b82601f106200029c57805160ff1916838001178555620002cc565b82800160010185558215620002cc579182015b82811115620002cc578251825591602001919060010190620002af565b50620002da929150620002de565b5090565b5b80821115620002da5760008155600101620002df565b600080604083850312156200030957600080fd5b505080516020909101519092909150565b600181811c908216806200032f57607f821691505b602082108114156200035157634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a051614b6562000399600039600081816103c0015261241801526000818161080d015281816110090152818161238501526128820152614b656000f3fe6080604052600436106102d15760003560e01c80636c0360eb1161017957806395d89b41116100d6578063d4ae75221161008a578063f0f4426011610064578063f0f4426014610885578063f2fde38b146108a5578063fd88fa69146108c557600080fd5b8063d4ae7522146107c7578063d5abeb01146107fb578063e985e9c51461082f57600080fd5b8063a22cb465116100bb578063a22cb46514610767578063b88d4fde14610787578063c87b56dd146107a757600080fd5b806395d89b411461073f57806397304ced1461075457600080fd5b806375794a3c1161012d5780637ff9b596116101125780637ff9b596146106835780638da5cb5b1461069957806390aa0b0f146106c457600080fd5b806375794a3c1461064d57806378cf19e91461066357600080fd5b806370a082311161015e57806370a08231146105eb578063715018a61461060b578063725c8ee71461062057600080fd5b80636c0360eb146105b65780636e0e5b19146105cb57600080fd5b8063339516c8116102325780634f6ccce7116101e657806361d027b3116101c057806361d027b3146105445780636352211e146105765780636a61e5fc1461059657600080fd5b80634f6ccce7146104e4578063522c698d1461050457806355f804b31461052457600080fd5b806342842e0e1161021757806342842e0e1461048e57806342966c68146104ae578063433adb05146104ce57600080fd5b8063339516c8146104585780633644e5151461047857600080fd5b806316317c21116102895780632164218b1161026e5780632164218b1461040557806323b872dd146104185780632f745c591461043857600080fd5b806316317c21146103ae57806318160ddd146103f057600080fd5b806307ebec27116102ba57806307ebec271461032d578063081812fc14610347578063095ea7b31461038c57600080fd5b806301ffc9a7146102d657806306fdde031461030b575b600080fd5b3480156102e257600080fd5b506102f66102f1366004614675565b61096a565b60405190151581526020015b60405180910390f35b34801561031757600080fd5b506103206109c6565b6040516103029190614894565b34801561033957600080fd5b50600d546102f69060ff1681565b34801561035357600080fd5b506103676103623660046146f1565b610a58565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610302565b34801561039857600080fd5b506103ac6103a73660046145f9565b610b37565b005b3480156103ba57600080fd5b506103e27f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610302565b3480156103fc57600080fd5b506008546103e2565b6103ac61041336600461470a565b610cc4565b34801561042457600080fd5b506103ac610433366004614485565b611456565b34801561044457600080fd5b506103e26104533660046145f9565b6114f7565b34801561046457600080fd5b506103ac61047336600461475d565b6115c6565b34801561048457600080fd5b506103e260135481565b34801561049a57600080fd5b506103ac6104a9366004614485565b611890565b3480156104ba57600080fd5b506103ac6104c93660046146f1565b6118ab565b3480156104da57600080fd5b506103e2600b5481565b3480156104f057600080fd5b506103e26104ff3660046146f1565b6119b9565b34801561051057600080fd5b506103ac61051f366004614625565b611a77565b34801561053057600080fd5b506103ac61053f3660046146af565b611d18565b34801561055057600080fd5b50600d5461036790610100900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561058257600080fd5b506103676105913660046146f1565b611de3565b3480156105a257600080fd5b506103ac6105b13660046146f1565b611e95565b3480156105c257600080fd5b50610320611f52565b3480156105d757600080fd5b506103ac6105e636600461465a565b611fe0565b3480156105f757600080fd5b506103e261060636600461442f565b6120c0565b34801561061757600080fd5b506103ac61218e565b34801561062c57600080fd5b506103e261063b36600461442f565b60106020526000908152604090205481565b34801561065957600080fd5b506103e2600c5481565b34801561066f57600080fd5b506103ac61067e3660046145f9565b61221b565b34801561068f57600080fd5b506103e2600e5481565b3480156106a557600080fd5b50600a5473ffffffffffffffffffffffffffffffffffffffff16610367565b3480156106d057600080fd5b5060115461070f9063ffffffff8082169164010000000081048216916801000000000000000082048116916c0100000000000000000000000090041684565b6040805163ffffffff95861681529385166020850152918416918301919091529091166060820152608001610302565b34801561074b57600080fd5b50610320612533565b6103ac6107623660046146f1565b612542565b34801561077357600080fd5b506103ac6107823660046145c4565b612a58565b34801561079357600080fd5b506103ac6107a23660046144c6565b612b6f565b3480156107b357600080fd5b506103206107c23660046146f1565b612c17565b3480156107d357600080fd5b506103e27f46d572d4aba7cc8ab12e37a6c279cfd599f9f5b73872e95b4bff2a237dd40f0e81565b34801561080757600080fd5b506103e27f000000000000000000000000000000000000000000000000000000000000000081565b34801561083b57600080fd5b506102f661084a36600461444c565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561089157600080fd5b506103ac6108a036600461442f565b612d27565b3480156108b157600080fd5b506103ac6108c036600461442f565b612e22565b3480156108d157600080fd5b50600f546109319073ffffffffffffffffffffffffffffffffffffffff81169063ffffffff740100000000000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b6040805173ffffffffffffffffffffffffffffffffffffffff909416845263ffffffff9283166020850152911690820152606001610302565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f780e9d630000000000000000000000000000000000000000000000000000000014806109c057506109c082612f4f565b92915050565b6060600080546109d590614953565b80601f0160208091040260200160405190810160405280929190818152602001828054610a0190614953565b8015610a4e5780601f10610a2357610100808354040283529160200191610a4e565b820191906000526020600020905b815481529060010190602001808311610a3157829003601f168201915b5050505050905090565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff16610b0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5060009081526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b6000610b4282611de3565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610c00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f72000000000000000000000000000000000000000000000000000000000000006064820152608401610b05565b3373ffffffffffffffffffffffffffffffffffffffff82161480610c295750610c29813361084a565b610cb5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610b05565b610cbf8383613032565b505050565b600c5460408051606081018252600f5473ffffffffffffffffffffffffffffffffffffffff811680835263ffffffff7401000000000000000000000000000000000000000083048116602085015278010000000000000000000000000000000000000000000000009092049091169282019290925290610dc6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f546865536576656e733a2070726573616c65206e6f7420636f6e66696775726560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152608401610b05565b600d54610100900473ffffffffffffffffffffffffffffffffffffffff16610e4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f546865536576656e733a207472656173757279206e6f742073657400000000006044820152606401610b05565b6000600e5411610eb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f546865536576656e733a20746f6b656e207072696365206e6f742073657400006044820152606401610b05565b60008611610f20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f546865536576656e733a20696e76616c696420636f756e7400000000000000006044820152606401610b05565b806020015163ffffffff16421015610f94576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f546865536576656e733a2070726573616c65206e6f74207374617274656400006044820152606401610b05565b806040015163ffffffff164210611007576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f546865536576656e733a2070726573616c6520656e64656400000000000000006044820152606401610b05565b7f000000000000000000000000000000000000000000000000000000000000000061103287846148a7565b111561109a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f546865536576656e733a206d617820737570706c7920657863656564656400006044820152606401610b05565b3486600e546110a991906148d3565b14611110576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f546865536576656e733a20696e636f72726563742045746865722076616c75656044820152606401610b05565b601354604080517f46d572d4aba7cc8ab12e37a6c279cfd599f9f5b73872e95b4bff2a237dd40f0e602082015233918101919091526060810187905260009190608001604051602081830303815290604052805190602001206040516020016111ab9291907f190100000000000000000000000000000000000000000000000000000000000081526002810192909252602282015260420190565b604051602081830303815290604052805190602001209050600061120786868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525086939250506130d29050565b905073ffffffffffffffffffffffffffffffffffffffff8116158015906112475750825173ffffffffffffffffffffffffffffffffffffffff8281169116145b6112ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f546865536576656e733a20696e76616c6964207369676e6174757265000000006044820152606401610b05565b3360009081526010602052604090205487906112ca908a906148a7565b1115611358576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f546865536576656e733a2070726573616c65206d617820636f756e742065786360448201527f65656465640000000000000000000000000000000000000000000000000000006064820152608401610b05565b33600090815260106020526040812080548a92906113779084906148a7565b9091555050600d5460405173ffffffffffffffffffffffffffffffffffffffff61010090920491909116903480156108fc02916000818181858888f193505050501580156113c9573d6000803e3d6000fd5b5060005b888110156113fa576113e8336113e383886148a7565b613190565b806113f2816149a7565b9150506113cd565b5087600c600082825461140d91906148a7565b909155505060408051338152602081018a90527ff5df7d07fef0d8ac7581015ebd1a3b7b7760da84b12f0c8174ae0dcd639cb6a391015b60405180910390a15050505050505050565b61146033826131ae565b6114ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f7665640000000000000000000000000000006064820152608401610b05565b610cbf83838361331e565b6000611502836120c0565b8210611590576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e64730000000000000000000000000000000000000000006064820152608401610b05565b5073ffffffffffffffffffffffffffffffffffffffff919091166000908152600660209081526040808320938352929052205490565b600a5473ffffffffffffffffffffffffffffffffffffffff163314611647576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b05565b600061165285613590565b9050600061165f85613590565b9050600061166c85613590565b9050600061167985613590565b905060008363ffffffff16118015611697575060008163ffffffff16115b6116fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f546865536576656e733a207a65726f20616d6f756e74000000000000000000006044820152606401610b05565b60008463ffffffff1611801561171e57508363ffffffff168263ffffffff16115b611784576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f546865536576656e733a20696e76616c69642074696d652072616e67650000006044820152606401610b05565b604080516080808201835263ffffffff87811680845287821660208086018290528884168688018190529388166060968701819052601180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001685176401000000008502177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000087027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff16176c01000000000000000000000000830217905587519384529083019190915294810191909152918201929092527f13f088a057ef4210c4d073c29c1b14137f9b4c8cecacd1dd349f49fb69991f579101611444565b610cbf83838360405180602001604052806000815250612b6f565b600d5460ff16611917576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f546865536576656e733a206275726e696e672064697361626c656400000000006044820152606401610b05565b61192133826131ae565b6119ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546865536576656e733a206275726e2063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f766564000000000000000000000000000000006064820152608401610b05565b6119b68161362a565b50565b60006119c460085490565b8210611a52576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e647300000000000000000000000000000000000000006064820152608401610b05565b60088281548110611a6557611a65614a81565b90600052602060002001549050919050565b600a5473ffffffffffffffffffffffffffffffffffffffff163314611af8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b05565b6000611b0383613590565b90506000611b1083613590565b905073ffffffffffffffffffffffffffffffffffffffff8516611b8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f546865536576656e733a207a65726f20616464726573730000000000000000006044820152606401610b05565b60008263ffffffff16118015611bb057508163ffffffff168163ffffffff16115b611c16576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f546865536576656e733a20696e76616c69642074696d652072616e67650000006044820152606401610b05565b604080516060808201835273ffffffffffffffffffffffffffffffffffffffff881680835263ffffffff8681166020808601829052918716948601859052600f80547fffffffffffffffff000000000000000000000000000000000000000000000000168417740100000000000000000000000000000000000000008302177fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000008702179055855192835290820152928301919091527f883135fc965d7f7dbcc3014a73e1da89792169e1946b4fa2b4217cef2ae08003910160405180910390a15050505050565b600a5473ffffffffffffffffffffffffffffffffffffffff163314611d99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b05565b611da560128383614323565b507f5411e8ebf1636d9e83d5fc4900bf80cbac82e8790da2a4c94db4895e889eedf68282604051611dd7929190614847565b60405180910390a15050565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff16806109c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e00000000000000000000000000000000000000000000006064820152608401610b05565b600a5473ffffffffffffffffffffffffffffffffffffffff163314611f16576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b05565b600e8190556040518181527fac21bacd333b316c6640fca5086322638b0a7aa4367179afd5dfcbe0a5427bc7906020015b60405180910390a150565b60128054611f5f90614953565b80601f0160208091040260200160405190810160405280929190818152602001828054611f8b90614953565b8015611fd85780601f10611fad57610100808354040283529160200191611fd8565b820191906000526020600020905b815481529060010190602001808311611fbb57829003601f168201915b505050505081565b600a5473ffffffffffffffffffffffffffffffffffffffff163314612061576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b05565b600d80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168215159081179091556040519081527f430864ad215aa849052adf33b0cae7eb033aa8a4f9cf45fb3973699038505ff390602001611f47565b600073ffffffffffffffffffffffffffffffffffffffff8216612165576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f2061646472657373000000000000000000000000000000000000000000006064820152608401610b05565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205490565b600a5473ffffffffffffffffffffffffffffffffffffffff16331461220f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b05565b6122196000613703565b565b600a5473ffffffffffffffffffffffffffffffffffffffff16331461229c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b05565b73ffffffffffffffffffffffffffffffffffffffff8216612319576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f546865536576656e733a207a65726f20616464726573730000000000000000006044820152606401610b05565b600c5481612383576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f546865536576656e733a20696e76616c696420636f756e7400000000000000006044820152606401610b05565b7f00000000000000000000000000000000000000000000000000000000000000006123ae83836148a7565b1115612416576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f546865536576656e733a206d617820737570706c7920657863656564656400006044820152606401610b05565b7f000000000000000000000000000000000000000000000000000000000000000082600b5461244591906148a7565b11156124d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f546865536576656e733a206d6178207265736572766520636f756e742065786360448201527f65656465640000000000000000000000000000000000000000000000000000006064820152608401610b05565b81600b60008282546124e591906148a7565b90915550600090505b8281101561251657612504846113e383856148a7565b8061250e816149a7565b9150506124ee565b5081600c600082825461252991906148a7565b9091555050505050565b6060600180546109d590614953565b600c546040805160808101825260115463ffffffff8082168084526401000000008304821660208501526801000000000000000083048216948401949094526c01000000000000000000000000909104166060820152906125ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f546865536576656e733a2073616c65206e6f7420636f6e6669677572656400006044820152606401610b05565b600d54610100900473ffffffffffffffffffffffffffffffffffffffff16612683576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f546865536576656e733a207472656173757279206e6f742073657400000000006044820152606401610b05565b6000600e54116126ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f546865536576656e733a20746f6b656e207072696365206e6f742073657400006044820152606401610b05565b60008311612759576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f546865536576656e733a20696e76616c696420636f756e7400000000000000006044820152606401610b05565b805163ffffffff164210156127ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f546865536576656e733a2073616c65206e6f74207374617274656400000000006044820152606401610b05565b806040015163ffffffff164210156127e65780602001516127ec565b80606001515b63ffffffff16831115612880576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f546865536576656e733a206d617820636f756e7420706572207478206578636560448201527f65646564000000000000000000000000000000000000000000000000000000006064820152608401610b05565b7f00000000000000000000000000000000000000000000000000000000000000006128ab84846148a7565b1115612913576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f546865536576656e733a206d617820737570706c7920657863656564656400006044820152606401610b05565b3483600e5461292291906148d3565b14612989576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f546865536576656e733a20696e636f72726563742045746865722076616c75656044820152606401610b05565b600d5460405173ffffffffffffffffffffffffffffffffffffffff61010090920491909116903480156108fc02916000818181858888f193505050501580156129d6573d6000803e3d6000fd5b5060005b83811015612a02576129f0336113e383866148a7565b806129fa816149a7565b9150506129da565b5082600c6000828254612a1591906148a7565b909155505060408051338152602081018590527f35b6d348af664cd334c7ec2746e1ab49907efa953fa3f622552cd0b19a828b3f910160405180910390a1505050565b73ffffffffffffffffffffffffffffffffffffffff8216331415612ad8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610b05565b33600081815260056020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b612b7933836131ae565b612c05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f7665640000000000000000000000000000006064820152608401610b05565b612c118484848461377a565b50505050565b60008181526002602052604090205460609073ffffffffffffffffffffffffffffffffffffffff16612ccb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201527f6e6578697374656e7420746f6b656e00000000000000000000000000000000006064820152608401610b05565b6000612cd561381d565b90506000815111612cf55760405180602001604052806000815250612d20565b80612cff8461382c565b604051602001612d109291906147d9565b6040516020818303038152906040525b9392505050565b600a5473ffffffffffffffffffffffffffffffffffffffff163314612da8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b05565b600d80547fffffffffffffffffffffff0000000000000000000000000000000000000000ff1661010073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527fc714d22a2f08b695f81e7c707058db484aa5b4d6b4c9fd64beb10fe85832f60890602001611f47565b600a5473ffffffffffffffffffffffffffffffffffffffff163314612ea3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b05565b73ffffffffffffffffffffffffffffffffffffffff8116612f46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610b05565b6119b681613703565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd000000000000000000000000000000000000000000000000000000001480612fe257507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b806109c057507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146109c0565b600081815260046020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416908117909155819061308c82611de3565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008151604114156131065760208201516040830151606084015160001a6130fc8682858561395e565b93505050506109c0565b81516040141561312e5760208201516040830151613125858383613bb6565b925050506109c0565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610b05565b6131aa828260405180602001604052806000815250613bf9565b5050565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff1661325f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e00000000000000000000000000000000000000006064820152608401610b05565b600061326a83611de3565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806132d957508373ffffffffffffffffffffffffffffffffffffffff166132c184610a58565b73ffffffffffffffffffffffffffffffffffffffff16145b80613316575073ffffffffffffffffffffffffffffffffffffffff80821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b8273ffffffffffffffffffffffffffffffffffffffff1661333e82611de3565b73ffffffffffffffffffffffffffffffffffffffff16146133e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201527f73206e6f74206f776e00000000000000000000000000000000000000000000006064820152608401610b05565b73ffffffffffffffffffffffffffffffffffffffff8216613483576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610b05565b61348e838383613c9c565b613499600082613032565b73ffffffffffffffffffffffffffffffffffffffff831660009081526003602052604081208054600192906134cf908490614910565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600090815260036020526040812080546001929061350a9084906148a7565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600063ffffffff821115613626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201527f32206269747300000000000000000000000000000000000000000000000000006064820152608401610b05565b5090565b600061363582611de3565b905061364381600084613c9c565b61364e600083613032565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600360205260408120805460019290613684908490614910565b909155505060008281526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555183919073ffffffffffffffffffffffffffffffffffffffff8416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b600a805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61378584848461331e565b61379184848484613da2565b612c11576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610b05565b6060601280546109d590614953565b60608161386c57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156138965780613880816149a7565b915061388f9050600a836148bf565b9150613870565b60008167ffffffffffffffff8111156138b1576138b1614ab0565b6040519080825280601f01601f1916602001820160405280156138db576020820181803683370190505b5090505b8415613316576138f0600183614910565b91506138fd600a866149e0565b6139089060306148a7565b60f81b81838151811061391d5761391d614a81565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350613957600a866148bf565b94506138df565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0821115613a10576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610b05565b8360ff16601b1480613a2557508360ff16601c145b613ab1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610b05565b6040805160008082526020820180845288905260ff871692820192909252606081018590526080810184905260019060a0016020604051602081039080840390855afa158015613b05573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116613bad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610b05565b95945050505050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821660ff83901c601b01613bef8682878561395e565b9695505050505050565b613c038383613f9e565b613c106000848484613da2565b610cbf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610b05565b73ffffffffffffffffffffffffffffffffffffffff8316613d0457613cff81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b613d41565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614613d4157613d41838261416c565b73ffffffffffffffffffffffffffffffffffffffff8216613d6557610cbf81614223565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614610cbf57610cbf82826142d2565b600073ffffffffffffffffffffffffffffffffffffffff84163b15613f96576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063150b7a0290613e19903390899088908890600401614808565b602060405180830381600087803b158015613e3357600080fd5b505af1925050508015613e81575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252613e7e91810190614692565b60015b613f4b573d808015613eaf576040519150601f19603f3d011682016040523d82523d6000602084013e613eb4565b606091505b508051613f43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610b05565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050613316565b506001613316565b73ffffffffffffffffffffffffffffffffffffffff821661401b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610b05565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16156140a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610b05565b6140b360008383613c9c565b73ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604081208054600192906140e99084906148a7565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001614179846120c0565b6141839190614910565b6000838152600760205260409020549091508082146141e35773ffffffffffffffffffffffffffffffffffffffff841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b50600091825260076020908152604080842084905573ffffffffffffffffffffffffffffffffffffffff9094168352600681528383209183525290812055565b60085460009061423590600190614910565b6000838152600960205260408120546008805493945090928490811061425d5761425d614a81565b90600052602060002001549050806008838154811061427e5761427e614a81565b60009182526020808320909101929092558281526009909152604080822084905585825281205560088054806142b6576142b6614a52565b6001900381819060005260206000200160009055905550505050565b60006142dd836120c0565b73ffffffffffffffffffffffffffffffffffffffff9093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b82805461432f90614953565b90600052602060002090601f01602090048101928261435157600085556143b5565b82601f10614388578280017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008235161785556143b5565b828001600101855582156143b5579182015b828111156143b557823582559160200191906001019061439a565b506136269291505b8082111561362657600081556001016143bd565b803580151581146143e157600080fd5b919050565b60008083601f8401126143f857600080fd5b50813567ffffffffffffffff81111561441057600080fd5b60208301915083602082850101111561442857600080fd5b9250929050565b60006020828403121561444157600080fd5b8135612d2081614adf565b6000806040838503121561445f57600080fd5b823561446a81614adf565b9150602083013561447a81614adf565b809150509250929050565b60008060006060848603121561449a57600080fd5b83356144a581614adf565b925060208401356144b581614adf565b929592945050506040919091013590565b600080600080608085870312156144dc57600080fd5b84356144e781614adf565b935060208501356144f781614adf565b925060408501359150606085013567ffffffffffffffff8082111561451b57600080fd5b818701915087601f83011261452f57600080fd5b81358181111561454157614541614ab0565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561458757614587614ab0565b816040528281528a60208487010111156145a057600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b600080604083850312156145d757600080fd5b82356145e281614adf565b91506145f0602084016143d1565b90509250929050565b6000806040838503121561460c57600080fd5b823561461781614adf565b946020939093013593505050565b60008060006060848603121561463a57600080fd5b833561464581614adf565b95602085013595506040909401359392505050565b60006020828403121561466c57600080fd5b612d20826143d1565b60006020828403121561468757600080fd5b8135612d2081614b01565b6000602082840312156146a457600080fd5b8151612d2081614b01565b600080602083850312156146c257600080fd5b823567ffffffffffffffff8111156146d957600080fd5b6146e5858286016143e6565b90969095509350505050565b60006020828403121561470357600080fd5b5035919050565b6000806000806060858703121561472057600080fd5b8435935060208501359250604085013567ffffffffffffffff81111561474557600080fd5b614751878288016143e6565b95989497509550505050565b6000806000806080858703121561477357600080fd5b5050823594602084013594506040840135936060013592509050565b600081518084526147a7816020860160208601614927565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600083516147eb818460208801614927565b8351908301906147ff818360208801614927565b01949350505050565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525083604083015260806060830152613bef608083018461478f565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b602081526000612d20602083018461478f565b600082198211156148ba576148ba6149f4565b500190565b6000826148ce576148ce614a23565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561490b5761490b6149f4565b500290565b600082821015614922576149226149f4565b500390565b60005b8381101561494257818101518382015260200161492a565b83811115612c115750506000910152565b600181811c9082168061496757607f821691505b602082108114156149a1577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156149d9576149d96149f4565b5060010190565b6000826149ef576149ef614a23565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff811681146119b657600080fd5b7fffffffff00000000000000000000000000000000000000000000000000000000811681146119b657600080fdfea26469706673582212200879ddd20c10c505d2ee41ece4554495b9fea91701064358340ece2741ba0b1164736f6c634300080700330000000000000000000000000000000000000000000000000000000000001b580000000000000000000000000000000000000000000000000000000000000096

Deployed Bytecode

0x6080604052600436106102d15760003560e01c80636c0360eb1161017957806395d89b41116100d6578063d4ae75221161008a578063f0f4426011610064578063f0f4426014610885578063f2fde38b146108a5578063fd88fa69146108c557600080fd5b8063d4ae7522146107c7578063d5abeb01146107fb578063e985e9c51461082f57600080fd5b8063a22cb465116100bb578063a22cb46514610767578063b88d4fde14610787578063c87b56dd146107a757600080fd5b806395d89b411461073f57806397304ced1461075457600080fd5b806375794a3c1161012d5780637ff9b596116101125780637ff9b596146106835780638da5cb5b1461069957806390aa0b0f146106c457600080fd5b806375794a3c1461064d57806378cf19e91461066357600080fd5b806370a082311161015e57806370a08231146105eb578063715018a61461060b578063725c8ee71461062057600080fd5b80636c0360eb146105b65780636e0e5b19146105cb57600080fd5b8063339516c8116102325780634f6ccce7116101e657806361d027b3116101c057806361d027b3146105445780636352211e146105765780636a61e5fc1461059657600080fd5b80634f6ccce7146104e4578063522c698d1461050457806355f804b31461052457600080fd5b806342842e0e1161021757806342842e0e1461048e57806342966c68146104ae578063433adb05146104ce57600080fd5b8063339516c8146104585780633644e5151461047857600080fd5b806316317c21116102895780632164218b1161026e5780632164218b1461040557806323b872dd146104185780632f745c591461043857600080fd5b806316317c21146103ae57806318160ddd146103f057600080fd5b806307ebec27116102ba57806307ebec271461032d578063081812fc14610347578063095ea7b31461038c57600080fd5b806301ffc9a7146102d657806306fdde031461030b575b600080fd5b3480156102e257600080fd5b506102f66102f1366004614675565b61096a565b60405190151581526020015b60405180910390f35b34801561031757600080fd5b506103206109c6565b6040516103029190614894565b34801561033957600080fd5b50600d546102f69060ff1681565b34801561035357600080fd5b506103676103623660046146f1565b610a58565b60405173ffffffffffffffffffffffffffffffffffffffff9091168152602001610302565b34801561039857600080fd5b506103ac6103a73660046145f9565b610b37565b005b3480156103ba57600080fd5b506103e27f000000000000000000000000000000000000000000000000000000000000009681565b604051908152602001610302565b3480156103fc57600080fd5b506008546103e2565b6103ac61041336600461470a565b610cc4565b34801561042457600080fd5b506103ac610433366004614485565b611456565b34801561044457600080fd5b506103e26104533660046145f9565b6114f7565b34801561046457600080fd5b506103ac61047336600461475d565b6115c6565b34801561048457600080fd5b506103e260135481565b34801561049a57600080fd5b506103ac6104a9366004614485565b611890565b3480156104ba57600080fd5b506103ac6104c93660046146f1565b6118ab565b3480156104da57600080fd5b506103e2600b5481565b3480156104f057600080fd5b506103e26104ff3660046146f1565b6119b9565b34801561051057600080fd5b506103ac61051f366004614625565b611a77565b34801561053057600080fd5b506103ac61053f3660046146af565b611d18565b34801561055057600080fd5b50600d5461036790610100900473ffffffffffffffffffffffffffffffffffffffff1681565b34801561058257600080fd5b506103676105913660046146f1565b611de3565b3480156105a257600080fd5b506103ac6105b13660046146f1565b611e95565b3480156105c257600080fd5b50610320611f52565b3480156105d757600080fd5b506103ac6105e636600461465a565b611fe0565b3480156105f757600080fd5b506103e261060636600461442f565b6120c0565b34801561061757600080fd5b506103ac61218e565b34801561062c57600080fd5b506103e261063b36600461442f565b60106020526000908152604090205481565b34801561065957600080fd5b506103e2600c5481565b34801561066f57600080fd5b506103ac61067e3660046145f9565b61221b565b34801561068f57600080fd5b506103e2600e5481565b3480156106a557600080fd5b50600a5473ffffffffffffffffffffffffffffffffffffffff16610367565b3480156106d057600080fd5b5060115461070f9063ffffffff8082169164010000000081048216916801000000000000000082048116916c0100000000000000000000000090041684565b6040805163ffffffff95861681529385166020850152918416918301919091529091166060820152608001610302565b34801561074b57600080fd5b50610320612533565b6103ac6107623660046146f1565b612542565b34801561077357600080fd5b506103ac6107823660046145c4565b612a58565b34801561079357600080fd5b506103ac6107a23660046144c6565b612b6f565b3480156107b357600080fd5b506103206107c23660046146f1565b612c17565b3480156107d357600080fd5b506103e27f46d572d4aba7cc8ab12e37a6c279cfd599f9f5b73872e95b4bff2a237dd40f0e81565b34801561080757600080fd5b506103e27f0000000000000000000000000000000000000000000000000000000000001b5881565b34801561083b57600080fd5b506102f661084a36600461444c565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561089157600080fd5b506103ac6108a036600461442f565b612d27565b3480156108b157600080fd5b506103ac6108c036600461442f565b612e22565b3480156108d157600080fd5b50600f546109319073ffffffffffffffffffffffffffffffffffffffff81169063ffffffff740100000000000000000000000000000000000000008204811691780100000000000000000000000000000000000000000000000090041683565b6040805173ffffffffffffffffffffffffffffffffffffffff909416845263ffffffff9283166020850152911690820152606001610302565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f780e9d630000000000000000000000000000000000000000000000000000000014806109c057506109c082612f4f565b92915050565b6060600080546109d590614953565b80601f0160208091040260200160405190810160405280929190818152602001828054610a0190614953565b8015610a4e5780601f10610a2357610100808354040283529160200191610a4e565b820191906000526020600020905b815481529060010190602001808311610a3157829003601f168201915b5050505050905090565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff16610b0e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5060009081526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b6000610b4282611de3565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610c00576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f72000000000000000000000000000000000000000000000000000000000000006064820152608401610b05565b3373ffffffffffffffffffffffffffffffffffffffff82161480610c295750610c29813361084a565b610cb5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610b05565b610cbf8383613032565b505050565b600c5460408051606081018252600f5473ffffffffffffffffffffffffffffffffffffffff811680835263ffffffff7401000000000000000000000000000000000000000083048116602085015278010000000000000000000000000000000000000000000000009092049091169282019290925290610dc6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f546865536576656e733a2070726573616c65206e6f7420636f6e66696775726560448201527f64000000000000000000000000000000000000000000000000000000000000006064820152608401610b05565b600d54610100900473ffffffffffffffffffffffffffffffffffffffff16610e4a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f546865536576656e733a207472656173757279206e6f742073657400000000006044820152606401610b05565b6000600e5411610eb6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f546865536576656e733a20746f6b656e207072696365206e6f742073657400006044820152606401610b05565b60008611610f20576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f546865536576656e733a20696e76616c696420636f756e7400000000000000006044820152606401610b05565b806020015163ffffffff16421015610f94576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f546865536576656e733a2070726573616c65206e6f74207374617274656400006044820152606401610b05565b806040015163ffffffff164210611007576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f546865536576656e733a2070726573616c6520656e64656400000000000000006044820152606401610b05565b7f0000000000000000000000000000000000000000000000000000000000001b5861103287846148a7565b111561109a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f546865536576656e733a206d617820737570706c7920657863656564656400006044820152606401610b05565b3486600e546110a991906148d3565b14611110576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f546865536576656e733a20696e636f72726563742045746865722076616c75656044820152606401610b05565b601354604080517f46d572d4aba7cc8ab12e37a6c279cfd599f9f5b73872e95b4bff2a237dd40f0e602082015233918101919091526060810187905260009190608001604051602081830303815290604052805190602001206040516020016111ab9291907f190100000000000000000000000000000000000000000000000000000000000081526002810192909252602282015260420190565b604051602081830303815290604052805190602001209050600061120786868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525086939250506130d29050565b905073ffffffffffffffffffffffffffffffffffffffff8116158015906112475750825173ffffffffffffffffffffffffffffffffffffffff8281169116145b6112ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f546865536576656e733a20696e76616c6964207369676e6174757265000000006044820152606401610b05565b3360009081526010602052604090205487906112ca908a906148a7565b1115611358576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f546865536576656e733a2070726573616c65206d617820636f756e742065786360448201527f65656465640000000000000000000000000000000000000000000000000000006064820152608401610b05565b33600090815260106020526040812080548a92906113779084906148a7565b9091555050600d5460405173ffffffffffffffffffffffffffffffffffffffff61010090920491909116903480156108fc02916000818181858888f193505050501580156113c9573d6000803e3d6000fd5b5060005b888110156113fa576113e8336113e383886148a7565b613190565b806113f2816149a7565b9150506113cd565b5087600c600082825461140d91906148a7565b909155505060408051338152602081018a90527ff5df7d07fef0d8ac7581015ebd1a3b7b7760da84b12f0c8174ae0dcd639cb6a391015b60405180910390a15050505050505050565b61146033826131ae565b6114ec576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f7665640000000000000000000000000000006064820152608401610b05565b610cbf83838361331e565b6000611502836120c0565b8210611590576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e64730000000000000000000000000000000000000000006064820152608401610b05565b5073ffffffffffffffffffffffffffffffffffffffff919091166000908152600660209081526040808320938352929052205490565b600a5473ffffffffffffffffffffffffffffffffffffffff163314611647576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b05565b600061165285613590565b9050600061165f85613590565b9050600061166c85613590565b9050600061167985613590565b905060008363ffffffff16118015611697575060008163ffffffff16115b6116fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f546865536576656e733a207a65726f20616d6f756e74000000000000000000006044820152606401610b05565b60008463ffffffff1611801561171e57508363ffffffff168263ffffffff16115b611784576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f546865536576656e733a20696e76616c69642074696d652072616e67650000006044820152606401610b05565b604080516080808201835263ffffffff87811680845287821660208086018290528884168688018190529388166060968701819052601180547fffffffffffffffffffffffffffffffffffffffffffffffff00000000000000001685176401000000008502177fffffffffffffffffffffffffffffffff0000000000000000ffffffffffffffff166801000000000000000087027fffffffffffffffffffffffffffffffff00000000ffffffffffffffffffffffff16176c01000000000000000000000000830217905587519384529083019190915294810191909152918201929092527f13f088a057ef4210c4d073c29c1b14137f9b4c8cecacd1dd349f49fb69991f579101611444565b610cbf83838360405180602001604052806000815250612b6f565b600d5460ff16611917576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f546865536576656e733a206275726e696e672064697361626c656400000000006044820152606401610b05565b61192133826131ae565b6119ad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603060248201527f546865536576656e733a206275726e2063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f766564000000000000000000000000000000006064820152608401610b05565b6119b68161362a565b50565b60006119c460085490565b8210611a52576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e647300000000000000000000000000000000000000006064820152608401610b05565b60088281548110611a6557611a65614a81565b90600052602060002001549050919050565b600a5473ffffffffffffffffffffffffffffffffffffffff163314611af8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b05565b6000611b0383613590565b90506000611b1083613590565b905073ffffffffffffffffffffffffffffffffffffffff8516611b8f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f546865536576656e733a207a65726f20616464726573730000000000000000006044820152606401610b05565b60008263ffffffff16118015611bb057508163ffffffff168163ffffffff16115b611c16576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f546865536576656e733a20696e76616c69642074696d652072616e67650000006044820152606401610b05565b604080516060808201835273ffffffffffffffffffffffffffffffffffffffff881680835263ffffffff8681166020808601829052918716948601859052600f80547fffffffffffffffff000000000000000000000000000000000000000000000000168417740100000000000000000000000000000000000000008302177fffffffff00000000ffffffffffffffffffffffffffffffffffffffffffffffff1678010000000000000000000000000000000000000000000000008702179055855192835290820152928301919091527f883135fc965d7f7dbcc3014a73e1da89792169e1946b4fa2b4217cef2ae08003910160405180910390a15050505050565b600a5473ffffffffffffffffffffffffffffffffffffffff163314611d99576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b05565b611da560128383614323565b507f5411e8ebf1636d9e83d5fc4900bf80cbac82e8790da2a4c94db4895e889eedf68282604051611dd7929190614847565b60405180910390a15050565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff16806109c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e00000000000000000000000000000000000000000000006064820152608401610b05565b600a5473ffffffffffffffffffffffffffffffffffffffff163314611f16576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b05565b600e8190556040518181527fac21bacd333b316c6640fca5086322638b0a7aa4367179afd5dfcbe0a5427bc7906020015b60405180910390a150565b60128054611f5f90614953565b80601f0160208091040260200160405190810160405280929190818152602001828054611f8b90614953565b8015611fd85780601f10611fad57610100808354040283529160200191611fd8565b820191906000526020600020905b815481529060010190602001808311611fbb57829003601f168201915b505050505081565b600a5473ffffffffffffffffffffffffffffffffffffffff163314612061576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b05565b600d80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00168215159081179091556040519081527f430864ad215aa849052adf33b0cae7eb033aa8a4f9cf45fb3973699038505ff390602001611f47565b600073ffffffffffffffffffffffffffffffffffffffff8216612165576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f2061646472657373000000000000000000000000000000000000000000006064820152608401610b05565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205490565b600a5473ffffffffffffffffffffffffffffffffffffffff16331461220f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b05565b6122196000613703565b565b600a5473ffffffffffffffffffffffffffffffffffffffff16331461229c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b05565b73ffffffffffffffffffffffffffffffffffffffff8216612319576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f546865536576656e733a207a65726f20616464726573730000000000000000006044820152606401610b05565b600c5481612383576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f546865536576656e733a20696e76616c696420636f756e7400000000000000006044820152606401610b05565b7f0000000000000000000000000000000000000000000000000000000000001b586123ae83836148a7565b1115612416576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f546865536576656e733a206d617820737570706c7920657863656564656400006044820152606401610b05565b7f000000000000000000000000000000000000000000000000000000000000009682600b5461244591906148a7565b11156124d3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f546865536576656e733a206d6178207265736572766520636f756e742065786360448201527f65656465640000000000000000000000000000000000000000000000000000006064820152608401610b05565b81600b60008282546124e591906148a7565b90915550600090505b8281101561251657612504846113e383856148a7565b8061250e816149a7565b9150506124ee565b5081600c600082825461252991906148a7565b9091555050505050565b6060600180546109d590614953565b600c546040805160808101825260115463ffffffff8082168084526401000000008304821660208501526801000000000000000083048216948401949094526c01000000000000000000000000909104166060820152906125ff576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f546865536576656e733a2073616c65206e6f7420636f6e6669677572656400006044820152606401610b05565b600d54610100900473ffffffffffffffffffffffffffffffffffffffff16612683576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f546865536576656e733a207472656173757279206e6f742073657400000000006044820152606401610b05565b6000600e54116126ef576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f546865536576656e733a20746f6b656e207072696365206e6f742073657400006044820152606401610b05565b60008311612759576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f546865536576656e733a20696e76616c696420636f756e7400000000000000006044820152606401610b05565b805163ffffffff164210156127ca576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f546865536576656e733a2073616c65206e6f74207374617274656400000000006044820152606401610b05565b806040015163ffffffff164210156127e65780602001516127ec565b80606001515b63ffffffff16831115612880576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f546865536576656e733a206d617820636f756e7420706572207478206578636560448201527f65646564000000000000000000000000000000000000000000000000000000006064820152608401610b05565b7f0000000000000000000000000000000000000000000000000000000000001b586128ab84846148a7565b1115612913576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601e60248201527f546865536576656e733a206d617820737570706c7920657863656564656400006044820152606401610b05565b3483600e5461292291906148d3565b14612989576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f546865536576656e733a20696e636f72726563742045746865722076616c75656044820152606401610b05565b600d5460405173ffffffffffffffffffffffffffffffffffffffff61010090920491909116903480156108fc02916000818181858888f193505050501580156129d6573d6000803e3d6000fd5b5060005b83811015612a02576129f0336113e383866148a7565b806129fa816149a7565b9150506129da565b5082600c6000828254612a1591906148a7565b909155505060408051338152602081018590527f35b6d348af664cd334c7ec2746e1ab49907efa953fa3f622552cd0b19a828b3f910160405180910390a1505050565b73ffffffffffffffffffffffffffffffffffffffff8216331415612ad8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610b05565b33600081815260056020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b612b7933836131ae565b612c05576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f7665640000000000000000000000000000006064820152608401610b05565b612c118484848461377a565b50505050565b60008181526002602052604090205460609073ffffffffffffffffffffffffffffffffffffffff16612ccb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201527f6e6578697374656e7420746f6b656e00000000000000000000000000000000006064820152608401610b05565b6000612cd561381d565b90506000815111612cf55760405180602001604052806000815250612d20565b80612cff8461382c565b604051602001612d109291906147d9565b6040516020818303038152906040525b9392505050565b600a5473ffffffffffffffffffffffffffffffffffffffff163314612da8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b05565b600d80547fffffffffffffffffffffff0000000000000000000000000000000000000000ff1661010073ffffffffffffffffffffffffffffffffffffffff8416908102919091179091556040519081527fc714d22a2f08b695f81e7c707058db484aa5b4d6b4c9fd64beb10fe85832f60890602001611f47565b600a5473ffffffffffffffffffffffffffffffffffffffff163314612ea3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610b05565b73ffffffffffffffffffffffffffffffffffffffff8116612f46576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f64647265737300000000000000000000000000000000000000000000000000006064820152608401610b05565b6119b681613703565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd000000000000000000000000000000000000000000000000000000001480612fe257507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b806109c057507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff000000000000000000000000000000000000000000000000000000008316146109c0565b600081815260046020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416908117909155819061308c82611de3565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008151604114156131065760208201516040830151606084015160001a6130fc8682858561395e565b93505050506109c0565b81516040141561312e5760208201516040830151613125858383613bb6565b925050506109c0565b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610b05565b6131aa828260405180602001604052806000815250613bf9565b5050565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff1661325f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e00000000000000000000000000000000000000006064820152608401610b05565b600061326a83611de3565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806132d957508373ffffffffffffffffffffffffffffffffffffffff166132c184610a58565b73ffffffffffffffffffffffffffffffffffffffff16145b80613316575073ffffffffffffffffffffffffffffffffffffffff80821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b8273ffffffffffffffffffffffffffffffffffffffff1661333e82611de3565b73ffffffffffffffffffffffffffffffffffffffff16146133e1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201527f73206e6f74206f776e00000000000000000000000000000000000000000000006064820152608401610b05565b73ffffffffffffffffffffffffffffffffffffffff8216613483576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610b05565b61348e838383613c9c565b613499600082613032565b73ffffffffffffffffffffffffffffffffffffffff831660009081526003602052604081208054600192906134cf908490614910565b909155505073ffffffffffffffffffffffffffffffffffffffff8216600090815260036020526040812080546001929061350a9084906148a7565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600063ffffffff821115613626576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f53616665436173743a2076616c756520646f65736e27742066697420696e203360448201527f32206269747300000000000000000000000000000000000000000000000000006064820152608401610b05565b5090565b600061363582611de3565b905061364381600084613c9c565b61364e600083613032565b73ffffffffffffffffffffffffffffffffffffffff81166000908152600360205260408120805460019290613684908490614910565b909155505060008281526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001690555183919073ffffffffffffffffffffffffffffffffffffffff8416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b600a805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61378584848461331e565b61379184848484613da2565b612c11576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610b05565b6060601280546109d590614953565b60608161386c57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156138965780613880816149a7565b915061388f9050600a836148bf565b9150613870565b60008167ffffffffffffffff8111156138b1576138b1614ab0565b6040519080825280601f01601f1916602001820160405280156138db576020820181803683370190505b5090505b8415613316576138f0600183614910565b91506138fd600a866149e0565b6139089060306148a7565b60f81b81838151811061391d5761391d614a81565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350613957600a866148bf565b94506138df565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0821115613a10576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610b05565b8360ff16601b1480613a2557508360ff16601c145b613ab1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c60448201527f75650000000000000000000000000000000000000000000000000000000000006064820152608401610b05565b6040805160008082526020820180845288905260ff871692820192909252606081018590526080810184905260019060a0016020604051602081039080840390855afa158015613b05573d6000803e3d6000fd5b50506040517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0015191505073ffffffffffffffffffffffffffffffffffffffff8116613bad576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610b05565b95945050505050565b60007f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821660ff83901c601b01613bef8682878561395e565b9695505050505050565b613c038383613f9e565b613c106000848484613da2565b610cbf576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610b05565b73ffffffffffffffffffffffffffffffffffffffff8316613d0457613cff81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b613d41565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614613d4157613d41838261416c565b73ffffffffffffffffffffffffffffffffffffffff8216613d6557610cbf81614223565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614610cbf57610cbf82826142d2565b600073ffffffffffffffffffffffffffffffffffffffff84163b15613f96576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063150b7a0290613e19903390899088908890600401614808565b602060405180830381600087803b158015613e3357600080fd5b505af1925050508015613e81575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0168201909252613e7e91810190614692565b60015b613f4b573d808015613eaf576040519150601f19603f3d011682016040523d82523d6000602084013e613eb4565b606091505b508051613f43576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610b05565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a0200000000000000000000000000000000000000000000000000000000149050613316565b506001613316565b73ffffffffffffffffffffffffffffffffffffffff821661401b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610b05565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16156140a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610b05565b6140b360008383613c9c565b73ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604081208054600192906140e99084906148a7565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001614179846120c0565b6141839190614910565b6000838152600760205260409020549091508082146141e35773ffffffffffffffffffffffffffffffffffffffff841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b50600091825260076020908152604080842084905573ffffffffffffffffffffffffffffffffffffffff9094168352600681528383209183525290812055565b60085460009061423590600190614910565b6000838152600960205260408120546008805493945090928490811061425d5761425d614a81565b90600052602060002001549050806008838154811061427e5761427e614a81565b60009182526020808320909101929092558281526009909152604080822084905585825281205560088054806142b6576142b6614a52565b6001900381819060005260206000200160009055905550505050565b60006142dd836120c0565b73ffffffffffffffffffffffffffffffffffffffff9093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b82805461432f90614953565b90600052602060002090601f01602090048101928261435157600085556143b5565b82601f10614388578280017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008235161785556143b5565b828001600101855582156143b5579182015b828111156143b557823582559160200191906001019061439a565b506136269291505b8082111561362657600081556001016143bd565b803580151581146143e157600080fd5b919050565b60008083601f8401126143f857600080fd5b50813567ffffffffffffffff81111561441057600080fd5b60208301915083602082850101111561442857600080fd5b9250929050565b60006020828403121561444157600080fd5b8135612d2081614adf565b6000806040838503121561445f57600080fd5b823561446a81614adf565b9150602083013561447a81614adf565b809150509250929050565b60008060006060848603121561449a57600080fd5b83356144a581614adf565b925060208401356144b581614adf565b929592945050506040919091013590565b600080600080608085870312156144dc57600080fd5b84356144e781614adf565b935060208501356144f781614adf565b925060408501359150606085013567ffffffffffffffff8082111561451b57600080fd5b818701915087601f83011261452f57600080fd5b81358181111561454157614541614ab0565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f0116810190838211818310171561458757614587614ab0565b816040528281528a60208487010111156145a057600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b600080604083850312156145d757600080fd5b82356145e281614adf565b91506145f0602084016143d1565b90509250929050565b6000806040838503121561460c57600080fd5b823561461781614adf565b946020939093013593505050565b60008060006060848603121561463a57600080fd5b833561464581614adf565b95602085013595506040909401359392505050565b60006020828403121561466c57600080fd5b612d20826143d1565b60006020828403121561468757600080fd5b8135612d2081614b01565b6000602082840312156146a457600080fd5b8151612d2081614b01565b600080602083850312156146c257600080fd5b823567ffffffffffffffff8111156146d957600080fd5b6146e5858286016143e6565b90969095509350505050565b60006020828403121561470357600080fd5b5035919050565b6000806000806060858703121561472057600080fd5b8435935060208501359250604085013567ffffffffffffffff81111561474557600080fd5b614751878288016143e6565b95989497509550505050565b6000806000806080858703121561477357600080fd5b5050823594602084013594506040840135936060013592509050565b600081518084526147a7816020860160208601614927565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b600083516147eb818460208801614927565b8351908301906147ff818360208801614927565b01949350505050565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525083604083015260806060830152613bef608083018461478f565b60208152816020820152818360408301376000818301604090810191909152601f9092017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0160101919050565b602081526000612d20602083018461478f565b600082198211156148ba576148ba6149f4565b500190565b6000826148ce576148ce614a23565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561490b5761490b6149f4565b500290565b600082821015614922576149226149f4565b500390565b60005b8381101561494257818101518382015260200161492a565b83811115612c115750506000910152565b600181811c9082168061496757607f821691505b602082108114156149a1577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156149d9576149d96149f4565b5060010190565b6000826149ef576149ef614a23565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b73ffffffffffffffffffffffffffffffffffffffff811681146119b657600080fd5b7fffffffff00000000000000000000000000000000000000000000000000000000811681146119b657600080fdfea26469706673582212200879ddd20c10c505d2ee41ece4554495b9fea91701064358340ece2741ba0b1164736f6c63430008070033

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

0000000000000000000000000000000000000000000000000000000000001b580000000000000000000000000000000000000000000000000000000000000096

-----Decoded View---------------
Arg [0] : _maxSupply (uint256): 7000
Arg [1] : _reserveCount (uint256): 150

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000001b58
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000096


Deployed Bytecode Sourcemap

57045:8960:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;36784:224;;;;;;;;;;-1:-1:-1;36784:224:0;;;;;:::i;:::-;;:::i;:::-;;;9845:14:1;;9838:22;9820:41;;9808:2;9793:18;36784:224:0;;;;;;;;23683:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;58200:25::-;;;;;;;;;;-1:-1:-1;58200:25:0;;;;;;;;25242:221;;;;;;;;;;-1:-1:-1;25242:221:0;;;;;:::i;:::-;;:::i;:::-;;;7905:42:1;7893:55;;;7875:74;;7863:2;7848:18;25242:221:0;7729:226:1;24765:411:0;;;;;;;;;;-1:-1:-1;24765:411:0;;;;;:::i;:::-;;:::i;:::-;;58085:37;;;;;;;;;;;;;;;;;;10018:25:1;;;10006:2;9991:18;58085:37:0;9872:177:1;37424:113:0;;;;;;;;;;-1:-1:-1;37512:10:0;:17;37424:113;;62249:1942;;;;;;:::i;:::-;;:::i;26132:339::-;;;;;;;;;;-1:-1:-1;26132:339:0;;;;;:::i;:::-;;:::i;37092:256::-;;;;;;;;;;-1:-1:-1;37092:256:0;;;;;:::i;:::-;;:::i;60802:952::-;;;;;;;;;;-1:-1:-1;60802:952:0;;;;;:::i;:::-;;:::i;58477:31::-;;;;;;;;;;;;;;;;26542:185;;;;;;;;;;-1:-1:-1;26542:185:0;;;;;:::i;:::-;;:::i;65646:248::-;;;;;;;;;;-1:-1:-1;65646:248:0;;;;;:::i;:::-;;:::i;58131:29::-;;;;;;;;;;;;;;;;37614:233;;;;;;;;;;-1:-1:-1;37614:233:0;;;;;:::i;:::-;;:::i;60160:634::-;;;;;;;;;;-1:-1:-1;60160:634:0;;;;;:::i;:::-;;:::i;62093:148::-;;;;;;;;;;-1:-1:-1;62093:148:0;;;;;:::i;:::-;;:::i;58232:31::-;;;;;;;;;;-1:-1:-1;58232:31:0;;;;;;;;;;;23377:239;;;;;;;;;;-1:-1:-1;23377:239:0;;;;;:::i;:::-;;:::i;60000:152::-;;;;;;;;;;-1:-1:-1;60000:152:0;;;;;:::i;:::-;;:::i;58447:21::-;;;;;;;;;;;;;:::i;61762:167::-;;;;;;;;;;-1:-1:-1;61762:167:0;;;;;:::i;:::-;;:::i;23107:208::-;;;;;;;;;;-1:-1:-1;23107:208:0;;;;;:::i;:::-;;:::i;2524:94::-;;;;;;;;;;;;;:::i;58347:54::-;;;;;;;;;;-1:-1:-1;58347:54:0;;;;;:::i;:::-;;;;;;;;;;;;;;58167:26;;;;;;;;;;;;;;;;59329:663;;;;;;;;;;-1:-1:-1;59329:663:0;;;;;:::i;:::-;;:::i;58272:25::-;;;;;;;;;;;;;;;;1873:87;;;;;;;;;;-1:-1:-1;1946:6:0;;;;1873:87;;58410:28;;;;;;;;;;-1:-1:-1;58410:28:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28081:10:1;28118:15;;;28100:34;;28170:15;;;28165:2;28150:18;;28143:43;28222:15;;;28202:18;;;28195:43;;;;28274:15;;;28269:2;28254:18;;28247:43;28058:3;28043:19;58410:28:0;27848:448:1;23852:104:0;;;;;;;;;;;;;:::i;64199:1439::-;;;;;;:::i;:::-;;:::i;25535:295::-;;;;;;;;;;-1:-1:-1;25535:295:0;;;;;:::i;:::-;;:::i;26798:328::-;;;;;;;;;;-1:-1:-1;26798:328:0;;;;;:::i;:::-;;:::i;24027:334::-;;;;;;;;;;-1:-1:-1;24027:334:0;;;;;:::i;:::-;;:::i;58515:95::-;;;;;;;;;;;;58558:52;58515:95;;58044:34;;;;;;;;;;;;;;;25901:164;;;;;;;;;;-1:-1:-1;25901:164:0;;;;;:::i;:::-;26022:25;;;;25998:4;26022:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;25901:164;61937:148;;;;;;;;;;-1:-1:-1;61937:148:0;;;;;:::i;:::-;;:::i;2773:192::-;;;;;;;;;;-1:-1:-1;2773:192:0;;;;;:::i;:::-;;:::i;58306:34::-;;;;;;;;;;-1:-1:-1;58306:34:0;;;;;;;;;;;;;;;;;;;;;;;;;9492:42:1;9480:55;;;9462:74;;9555:10;9601:15;;;9596:2;9581:18;;9574:43;9653:15;;9633:18;;;9626:43;9450:2;9435:18;58306:34:0;9264:411:1;36784:224:0;36886:4;36910:50;;;36925:35;36910:50;;:90;;;36964:36;36988:11;36964:23;:36::i;:::-;36903:97;36784:224;-1:-1:-1;;36784:224:0:o;23683:100::-;23737:13;23770:5;23763:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23683:100;:::o;25242:221::-;25318:7;28725:16;;;:7;:16;;;;;;:30;:16;25338:73;;;;;;;22799:2:1;25338:73:0;;;22781:21:1;22838:2;22818:18;;;22811:30;22877:34;22857:18;;;22850:62;22948:14;22928:18;;;22921:42;22980:19;;25338:73:0;;;;;;;;;-1:-1:-1;25431:24:0;;;;:15;:24;;;;;;;;;25242:221::o;24765:411::-;24846:13;24862:23;24877:7;24862:14;:23::i;:::-;24846:39;;24910:5;24904:11;;:2;:11;;;;24896:57;;;;;;;25154:2:1;24896:57:0;;;25136:21:1;25193:2;25173:18;;;25166:30;25232:34;25212:18;;;25205:62;25303:3;25283:18;;;25276:31;25324:19;;24896:57:0;24952:397:1;24896:57:0;741:10;24988:21;;;;;:62;;-1:-1:-1;25013:37:0;25030:5;741:10;25901:164;:::i;25013:37::-;24966:168;;;;;;;20430:2:1;24966:168:0;;;20412:21:1;20469:2;20449:18;;;20442:30;20508:34;20488:18;;;20481:62;20579:26;20559:18;;;20552:54;20623:19;;24966:168:0;20228:420:1;24966:168:0;25147:21;25156:2;25160:7;25147:8;:21::i;:::-;24835:341;24765:411;;:::o;62249:1942::-;62449:11;;62519:51;;;;;;;;62557:13;62519:51;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62581:90;;;;;;;24399:2:1;62581:90:0;;;24381:21:1;24438:2;24418:18;;;24411:30;24477:34;24457:18;;;24450:62;24548:3;24528:18;;;24521:31;24569:19;;62581:90:0;24197:397:1;62581:90:0;62692:8;;;;;:22;:8;62684:62;;;;;;;27151:2:1;62684:62:0;;;27133:21:1;27190:2;27170:18;;;27163:30;27229:29;27209:18;;;27202:57;27276:18;;62684:62:0;26949:351:1;62684:62:0;62778:1;62765:10;;:14;62757:57;;;;;;;22079:2:1;62757:57:0;;;22061:21:1;22118:2;22098:18;;;22091:30;22157:32;22137:18;;;22130:60;22207:18;;62757:57:0;21877:354:1;62757:57:0;62841:1;62833:5;:9;62825:46;;;;;;;15889:2:1;62825:46:0;;;15871:21:1;15928:2;15908:18;;;15901:30;15967:26;15947:18;;;15940:54;16011:18;;62825:46:0;15687:348:1;62825:46:0;62909:14;:24;;;62890:43;;:15;:43;;62882:86;;;;;;;16647:2:1;62882:86:0;;;16629:21:1;16686:2;16666:18;;;16659:30;16725:32;16705:18;;;16698:60;16775:18;;62882:86:0;16445:354:1;62882:86:0;63005:14;:22;;;62987:40;;:15;:40;62979:77;;;;;;;24801:2:1;62979:77:0;;;24783:21:1;24840:2;24820:18;;;24813:30;24879:26;24859:18;;;24852:54;24923:18;;62979:77:0;24599:348:1;62979:77:0;63101:9;63077:20;63092:5;63077:12;:20;:::i;:::-;:33;;63069:76;;;;;;;18940:2:1;63069:76:0;;;18922:21:1;18979:2;18959:18;;;18952:30;19018:32;18998:18;;;18991:60;19068:18;;63069:76:0;18738:354:1;63069:76:0;63186:9;63177:5;63164:10;;:18;;;;:::i;:::-;:31;63156:76;;;;;;;27507:2:1;63156:76:0;;;27489:21:1;;;27526:18;;;27519:30;27585:34;27565:18;;;27558:62;27637:18;;63156:76:0;27305:356:1;63156:76:0;63352:16;;63380:50;;;58558:52;63380:50;;;10256:25:1;63409:10:0;10297:18:1;;;10290:83;;;;10389:18;;;10382:34;;;63282:14:0;;63352:16;10229:18:1;;63380:50:0;;;;;;;;;;;;63370:61;;;;;;63323:109;;;;;;;;7550:66:1;7538:79;;7642:1;7633:11;;7626:27;;;;7678:2;7669:12;;7662:28;7715:2;7706:12;;7280:444;63323:109:0;;;;;;;;;;;;;63299:144;;;;;;63282:161;;63454:24;63481:25;63496:9;;63481:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;63481:6:0;;:25;-1:-1:-1;;63481:14:0;:25;-1:-1:-1;63481:25:0:i;:::-;63454:52;-1:-1:-1;63539:30:0;;;;;;;:84;;-1:-1:-1;63593:30:0;;63573:50;;;;;;;63539:84;63517:162;;;;;;;25556:2:1;63517:162:0;;;25538:21:1;25595:2;25575:18;;;25568:30;25634;25614:18;;;25607:58;25682:18;;63517:162:0;25354:352:1;63517:162:0;63720:10;63700:31;;;;:19;:31;;;;;;63743:8;;63700:39;;63734:5;;63700:39;:::i;:::-;:51;;63692:101;;;;;;;13177:2:1;63692:101:0;;;13159:21:1;13216:2;13196:18;;;13189:30;13255:34;13235:18;;;13228:62;13326:7;13306:18;;;13299:35;13351:19;;63692:101:0;12975:401:1;63692:101:0;63824:10;63804:31;;;;:19;:31;;;;;:40;;63839:5;;63804:31;:40;;63839:5;;63804:40;:::i;:::-;;;;-1:-1:-1;;63954:8:0;;:28;;:8;;;;;;;;;;63972:9;63954:28;;;;;;;;;63972:9;63954:8;:28;;;;;;;;;;;;;;;;;;;;;64000:11;63995:110;64023:5;64017:3;:11;63995:110;;;64052:41;64062:10;64074:18;64089:3;64074:12;:18;:::i;:::-;64052:9;:41::i;:::-;64030:5;;;;:::i;:::-;;;;63995:110;;;;64130:5;64115:11;;:20;;;;;;;:::i;:::-;;;;-1:-1:-1;;64153:30:0;;;64165:10;9136:74:1;;9241:2;9226:18;;9219:34;;;64153:30:0;;9109:18:1;64153:30:0;;;;;;;;62386:1805;;;;62249:1942;;;;:::o;26132:339::-;26327:41;741:10;26360:7;26327:18;:41::i;:::-;26319:103;;;;;;;25913:2:1;26319:103:0;;;25895:21:1;25952:2;25932:18;;;25925:30;25991:34;25971:18;;;25964:62;26062:19;26042:18;;;26035:47;26099:19;;26319:103:0;25711:413:1;26319:103:0;26435:28;26445:4;26451:2;26455:7;26435:9;:28::i;37092:256::-;37189:7;37225:23;37242:5;37225:16;:23::i;:::-;37217:5;:31;37209:87;;;;;;;13943:2:1;37209:87:0;;;13925:21:1;13982:2;13962:18;;;13955:30;14021:34;14001:18;;;13994:62;14092:13;14072:18;;;14065:41;14123:19;;37209:87:0;13741:407:1;37209:87:0;-1:-1:-1;37314:19:0;;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;37092:256::o;60802:952::-;1946:6;;2093:23;1946:6;741:10;2093:23;2085:68;;;;;;;23212:2:1;2085:68:0;;;23194:21:1;;;23231:18;;;23224:30;23290:34;23270:18;;;23263:62;23342:18;;2085:68:0;23010:356:1;2085:68:0;60989:17:::1;61009:20;:9;:18;:20::i;:::-;60989:40;;61040:20;61063:23;:12;:21;:23::i;:::-;61040:46;;61097:26;61126:29;:18;:27;:29::i;:::-;61097:58;;61166:24;61193:27;:16;:25;:27::i;:::-;61166:54;;61257:1;61241:13;:17;;;:42;;;;;61282:1;61262:17;:21;;;61241:42;61233:77;;;::::0;::::1;::::0;;15538:2:1;61233:77:0::1;::::0;::::1;15520:21:1::0;15577:2;15557:18;;;15550:30;15616:24;15596:18;;;15589:52;15658:18;;61233:77:0::1;15336:346:1::0;61233:77:0::1;61342:1;61329:10;:14;;;:50;;;;;61369:10;61347:32;;:19;:32;;;61329:50;61321:92;;;::::0;::::1;::::0;;20072:2:1;61321:92:0::1;::::0;::::1;20054:21:1::0;20111:2;20091:18;;;20084:30;20150:31;20130:18;;;20123:59;20199:18;;61321:92:0::1;19870:353:1::0;61321:92:0::1;61439:205;::::0;;::::1;::::0;;::::1;::::0;;::::1;::::0;;::::1;::::0;;;;;::::1;;::::0;;::::1;::::0;;;;;::::1;::::0;;;;;;;;::::1;::::0;;;;;;;61426:10:::1;:218:::0;;;;;;;;::::1;;::::0;;;;::::1;::::0;;;;;::::1;;::::0;;61662:84;;28100:34:1;;;28150:18;;;28143:43;;;;28202:18;;;28195:43;;;;28254:18;;;28247:43;;;;61662:84:0::1;::::0;28043:19:1;61662:84:0::1;27848:448:1::0;26542:185:0;26680:39;26697:4;26703:2;26707:7;26680:39;;;;;;;;;;;;:16;:39::i;65646:248::-;65705:13;;;;65697:53;;;;;;;12063:2:1;65697:53:0;;;12045:21:1;12102:2;12082:18;;;12075:30;12141:29;12121:18;;;12114:57;12188:18;;65697:53:0;11861:351:1;65697:53:0;65769:39;65788:10;65800:7;65769:18;:39::i;:::-;65761:100;;;;;;;19655:2:1;65761:100:0;;;19637:21:1;19694:2;19674:18;;;19667:30;19733:34;19713:18;;;19706:62;19804:18;19784;;;19777:46;19840:19;;65761:100:0;19453:412:1;65761:100:0;65872:14;65878:7;65872:5;:14::i;:::-;65646:248;:::o;37614:233::-;37689:7;37725:30;37512:10;:17;;37424:113;37725:30;37717:5;:38;37709:95;;;;;;;26738:2:1;37709:95:0;;;26720:21:1;26777:2;26757:18;;;26750:30;26816:34;26796:18;;;26789:62;26887:14;26867:18;;;26860:42;26919:19;;37709:95:0;26536:408:1;37709:95:0;37822:10;37833:5;37822:17;;;;;;;;:::i;:::-;;;;;;;;;37815:24;;37614:233;;;:::o;60160:634::-;1946:6;;2093:23;1946:6;741:10;2093:23;2085:68;;;;;;;23212:2:1;2085:68:0;;;23194:21:1;;;23231:18;;;23224:30;23290:34;23270:18;;;23263:62;23342:18;;2085:68:0;23010:356:1;2085:68:0;60307:17:::1;60327:20;:9;:18;:20::i;:::-;60307:40;;60358:15;60376:18;:7;:16;:18::i;:::-;60358:36:::0;-1:-1:-1;60440:29:0::1;::::0;::::1;60432:65;;;::::0;::::1;::::0;;12825:2:1;60432:65:0::1;::::0;::::1;12807:21:1::0;12864:2;12844:18;;;12837:30;12903:25;12883:18;;;12876:53;12946:18;;60432:65:0::1;12623:347:1::0;60432:65:0::1;60529:1;60516:10;:14;;;:39;;;;;60545:10;60534:21;;:8;:21;;;60516:39;60508:81;;;::::0;::::1;::::0;;20072:2:1;60508:81:0::1;::::0;::::1;20054:21:1::0;20111:2;20091:18;;;20084:30;20150:31;20130:18;;;20123:59;20199:18;;60508:81:0::1;19870:353:1::0;60508:81:0::1;60618:91;::::0;;::::1;::::0;;::::1;::::0;;::::1;::::0;::::1;::::0;;;::::1;::::0;;::::1;;::::0;;::::1;::::0;;;;;::::1;::::0;;;;;;60602:13:::1;:107:::0;;;;;;;;::::1;;::::0;::::1;::::0;;::::1;;::::0;;60727:59;;9462:74:1;;;9581:18;;;9574:43;9633:18;;;9626:43;;;;60727:59:0::1;::::0;9435:18:1;60727:59:0::1;;;;;;;60296:498;;60160:634:::0;;;:::o;62093:148::-;1946:6;;2093:23;1946:6;741:10;2093:23;2085:68;;;;;;;23212:2:1;2085:68:0;;;23194:21:1;;;23231:18;;;23224:30;23290:34;23270:18;;;23263:62;23342:18;;2085:68:0;23010:356:1;2085:68:0;62171:20:::1;:7;62181:10:::0;;62171:20:::1;:::i;:::-;;62207:26;62222:10;;62207:26;;;;;;;:::i;:::-;;;;;;;;62093:148:::0;;:::o;23377:239::-;23449:7;23485:16;;;:7;:16;;;;;;;;23520:19;23512:73;;;;;;;21266:2:1;23512:73:0;;;21248:21:1;21305:2;21285:18;;;21278:30;21344:34;21324:18;;;21317:62;21415:11;21395:18;;;21388:39;21444:19;;23512:73:0;21064:405:1;60000:152:0;1946:6;;2093:23;1946:6;741:10;2093:23;2085:68;;;;;;;23212:2:1;2085:68:0;;;23194:21:1;;;23231:18;;;23224:30;23290:34;23270:18;;;23263:62;23342:18;;2085:68:0;23010:356:1;2085:68:0;60074:10:::1;:24:::0;;;60114:30:::1;::::0;10018:25:1;;;60114:30:0::1;::::0;10006:2:1;9991:18;60114:30:0::1;;;;;;;;60000:152:::0;:::o;58447:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;61762:167::-;1946:6;;2093:23;1946:6;741:10;2093:23;2085:68;;;;;;;23212:2:1;2085:68:0;;;23194:21:1;;;23231:18;;;23224:30;23290:34;23270:18;;;23263:62;23342:18;;2085:68:0;23010:356:1;2085:68:0;61839:13:::1;:30:::0;;;::::1;::::0;::::1;;::::0;;::::1;::::0;;;61885:36:::1;::::0;9820:41:1;;;61885:36:0::1;::::0;9808:2:1;9793:18;61885:36:0::1;9680:187:1::0;23107:208:0;23179:7;23207:19;;;23199:74;;;;;;;20855:2:1;23199:74:0;;;20837:21:1;20894:2;20874:18;;;20867:30;20933:34;20913:18;;;20906:62;21004:12;20984:18;;;20977:40;21034:19;;23199:74:0;20653:406:1;23199:74:0;-1:-1:-1;23291:16:0;;;;;;:9;:16;;;;;;;23107:208::o;2524:94::-;1946:6;;2093:23;1946:6;741:10;2093:23;2085:68;;;;;;;23212:2:1;2085:68:0;;;23194:21:1;;;23231:18;;;23224:30;23290:34;23270:18;;;23263:62;23342:18;;2085:68:0;23010:356:1;2085:68:0;2589:21:::1;2607:1;2589:9;:21::i;:::-;2524:94::o:0;59329:663::-;1946:6;;2093:23;1946:6;741:10;2093:23;2085:68;;;;;;;23212:2:1;2085:68:0;;;23194:21:1;;;23231:18;;;23224:30;23290:34;23270:18;;;23263:62;23342:18;;2085:68:0;23010:356:1;2085:68:0;59424:23:::1;::::0;::::1;59416:59;;;::::0;::::1;::::0;;12825:2:1;59416:59:0::1;::::0;::::1;12807:21:1::0;12864:2;12844:18;;;12837:30;12903:25;12883:18;;;12876:53;12946:18;;59416:59:0::1;12623:347:1::0;59416:59:0::1;59540:11;::::0;59572:9;59564:46:::1;;;::::0;::::1;::::0;;15889:2:1;59564:46:0::1;::::0;::::1;15871:21:1::0;15928:2;15908:18;;;15901:30;15967:26;15947:18;;;15940:54;16011:18;;59564:46:0::1;15687:348:1::0;59564:46:0::1;59653:9;59629:20;59644:5:::0;59629:12;:20:::1;:::i;:::-;:33;;59621:76;;;::::0;::::1;::::0;;18940:2:1;59621:76:0::1;::::0;::::1;18922:21:1::0;18979:2;18959:18;;;18952:30;19018:32;18998:18;;;18991:60;19068:18;;59621:76:0::1;18738:354:1::0;59621:76:0::1;59744:12;59735:5;59718:14;;:22;;;;:::i;:::-;:38;;59710:88;;;::::0;::::1;::::0;;12419:2:1;59710:88:0::1;::::0;::::1;12401:21:1::0;12458:2;12438:18;;;12431:30;12497:34;12477:18;;;12470:62;12568:7;12548:18;;;12541:35;12593:19;;59710:88:0::1;12217:401:1::0;59710:88:0::1;59827:5;59809:14;;:23;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;59850:11:0::1;::::0;-1:-1:-1;59845:109:0::1;59873:5;59867:3;:11;59845:109;;;59902:40;59912:9:::0;59923:18:::1;59938:3:::0;59923:12;:18:::1;:::i;59902:40::-;59880:5:::0;::::1;::::0;::::1;:::i;:::-;;;;59845:109;;;;59979:5;59964:11;;:20;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;;;;;59329:663:0:o;23852:104::-;23908:13;23941:7;23934:14;;;;;:::i;64199:1439::-;64314:11;;64384:42;;;;;;;;64416:10;64384:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64437:68;;;;;;;18176:2:1;64437:68:0;;;18158:21:1;18215:2;18195:18;;;18188:30;18254:32;18234:18;;;18227:60;18304:18;;64437:68:0;17974:354:1;64437:68:0;64526:8;;;;;:22;:8;64518:62;;;;;;;27151:2:1;64518:62:0;;;27133:21:1;27190:2;27170:18;;;27163:30;27229:29;27209:18;;;27202:57;27276:18;;64518:62:0;26949:351:1;64518:62:0;64612:1;64599:10;;:14;64591:57;;;;;;;22079:2:1;64591:57:0;;;22061:21:1;22118:2;22098:18;;;22091:30;22157:32;22137:18;;;22130:60;22207:18;;64591:57:0;21877:354:1;64591:57:0;64675:1;64667:5;:9;64659:46;;;;;;;15889:2:1;64659:46:0;;;15871:21:1;15928:2;15908:18;;;15901:30;15967:26;15947:18;;;15940:54;16011:18;;64659:46:0;15687:348:1;64659:46:0;64743:21;;64724:40;;:15;:40;;64716:80;;;;;;;19299:2:1;64716:80:0;;;19281:21:1;19338:2;19318:18;;;19311:30;19377:29;19357:18;;;19350:57;19424:18;;64716:80:0;19097:351:1;64716:80:0;64899:11;:30;;;64880:49;;:15;:49;;:157;;65013:11;:24;;;64880:157;;;64957:11;:28;;;64880:157;64831:225;;:5;:225;;64809:311;;;;;;;18535:2:1;64809:311:0;;;18517:21:1;18574:2;18554:18;;;18547:30;18613:34;18593:18;;;18586:62;18684:6;18664:18;;;18657:34;18708:19;;64809:311:0;18333:400:1;64809:311:0;65163:9;65139:20;65154:5;65139:12;:20;:::i;:::-;:33;;65131:76;;;;;;;18940:2:1;65131:76:0;;;18922:21:1;18979:2;18959:18;;;18952:30;19018:32;18998:18;;;18991:60;19068:18;;65131:76:0;18738:354:1;65131:76:0;65248:9;65239:5;65226:10;;:18;;;;:::i;:::-;:31;65218:76;;;;;;;27507:2:1;65218:76:0;;;27489:21:1;;;27526:18;;;27519:30;27585:34;27565:18;;;27558:62;27637:18;;65218:76:0;27305:356:1;65218:76:0;65404:8;;:28;;:8;;;;;;;;;;65422:9;65404:28;;;;;;;;;65422:9;65404:8;:28;;;;;;;;;;;;;;;;;;;;;65450:11;65445:110;65473:5;65467:3;:11;65445:110;;;65502:41;65512:10;65524:18;65539:3;65524:12;:18;:::i;65502:41::-;65480:5;;;;:::i;:::-;;;;65445:110;;;;65580:5;65565:11;;:20;;;;;;;:::i;:::-;;;;-1:-1:-1;;65603:27:0;;;65612:10;9136:74:1;;9241:2;9226:18;;9219:34;;;65603:27:0;;9109:18:1;65603:27:0;;;;;;;64251:1387;;64199:1439;:::o;25535:295::-;25638:24;;;741:10;25638:24;;25630:62;;;;;;;17006:2:1;25630:62:0;;;16988:21:1;17045:2;17025:18;;;17018:30;17084:27;17064:18;;;17057:55;17129:18;;25630:62:0;16804:349:1;25630:62:0;741:10;25705:32;;;;:18;:32;;;;;;;;;:42;;;;;;;;;;;;:53;;;;;;;;;;;;;25774:48;;9820:41:1;;;25705:42:0;;741:10;25774:48;;9793:18:1;25774:48:0;;;;;;;25535:295;;:::o;26798:328::-;26973:41;741:10;27006:7;26973:18;:41::i;:::-;26965:103;;;;;;;25913:2:1;26965:103:0;;;25895:21:1;25952:2;25932:18;;;25925:30;25991:34;25971:18;;;25964:62;26062:19;26042:18;;;26035:47;26099:19;;26965:103:0;25711:413:1;26965:103:0;27079:39;27093:4;27099:2;27103:7;27112:5;27079:13;:39::i;:::-;26798:328;;;;:::o;24027:334::-;28701:4;28725:16;;;:7;:16;;;;;;24100:13;;28725:30;:16;24126:76;;;;;;;23983:2:1;24126:76:0;;;23965:21:1;24022:2;24002:18;;;23995:30;24061:34;24041:18;;;24034:62;24132:17;24112:18;;;24105:45;24167:19;;24126:76:0;23781:411:1;24126:76:0;24215:21;24239:10;:8;:10::i;:::-;24215:34;;24291:1;24273:7;24267:21;:25;:86;;;;;;;;;;;;;;;;;24319:7;24328:18;:7;:16;:18::i;:::-;24302:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;24267:86;24260:93;24027:334;-1:-1:-1;;;24027:334:0:o;61937:148::-;1946:6;;2093:23;1946:6;741:10;2093:23;2085:68;;;;;;;23212:2:1;2085:68:0;;;23194:21:1;;;23231:18;;;23224:30;23290:34;23270:18;;;23263:62;23342:18;;2085:68:0;23010:356:1;2085:68:0;62015:8:::1;:20:::0;;;::::1;;;::::0;::::1;::::0;;::::1;::::0;;;::::1;::::0;;;62051:26:::1;::::0;7875:74:1;;;62051:26:0::1;::::0;7863:2:1;7848:18;62051:26:0::1;7729:226:1::0;2773:192:0;1946:6;;2093:23;1946:6;741:10;2093:23;2085:68;;;;;;;23212:2:1;2085:68:0;;;23194:21:1;;;23231:18;;;23224:30;23290:34;23270:18;;;23263:62;23342:18;;2085:68:0;23010:356:1;2085:68:0;2862:22:::1;::::0;::::1;2854:73;;;::::0;::::1;::::0;;14774:2:1;2854:73:0::1;::::0;::::1;14756:21:1::0;14813:2;14793:18;;;14786:30;14852:34;14832:18;;;14825:62;14923:8;14903:18;;;14896:36;14949:19;;2854:73:0::1;14572:402:1::0;2854:73:0::1;2938:19;2948:8;2938:9;:19::i;22738:305::-:0;22840:4;22877:40;;;22892:25;22877:40;;:105;;-1:-1:-1;22934:48:0;;;22949:33;22934:48;22877:105;:158;;;-1:-1:-1;21378:25:0;21363:40;;;;22999:36;21254:157;32618:174;32693:24;;;;:15;:24;;;;;:29;;;;;;;;;;;;;:24;;32747:23;32693:24;32747:14;:23::i;:::-;32738:46;;;;;;;;;;;;32618:174;;:::o;44285:1270::-;44363:7;44583:9;:16;44603:2;44583:22;44579:969;;;44879:4;44864:20;;44858:27;44929:4;44914:20;;44908:27;44987:4;44972:20;;44966:27;44622:9;44958:36;45030:22;45038:4;44958:36;44858:27;44908;45030:7;:22::i;:::-;45023:29;;;;;;;44579:969;45074:9;:16;45094:2;45074:22;45070:478;;;45349:4;45334:20;;45328:27;45400:4;45385:20;;45379:27;45442:20;45450:4;45328:27;45379;45442:7;:20::i;:::-;45435:27;;;;;;45070:478;45495:41;;;;;13583:2:1;45495:41:0;;;13565:21:1;13622:2;13602:18;;;13595:30;13661:33;13641:18;;;13634:61;13712:18;;45495:41:0;13381:355:1;29620:110:0;29696:26;29706:2;29710:7;29696:26;;;;;;;;;;;;:9;:26::i;:::-;29620:110;;:::o;28930:348::-;29023:4;28725:16;;;:7;:16;;;;;;:30;:16;29040:73;;;;;;;17763:2:1;29040:73:0;;;17745:21:1;17802:2;17782:18;;;17775:30;17841:34;17821:18;;;17814:62;17912:14;17892:18;;;17885:42;17944:19;;29040:73:0;17561:408:1;29040:73:0;29124:13;29140:23;29155:7;29140:14;:23::i;:::-;29124:39;;29193:5;29182:16;;:7;:16;;;:51;;;;29226:7;29202:31;;:20;29214:7;29202:11;:20::i;:::-;:31;;;29182:51;:87;;;-1:-1:-1;26022:25:0;;;;25998:4;26022:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;29237:32;29174:96;28930:348;-1:-1:-1;;;;28930:348:0:o;31922:578::-;32081:4;32054:31;;:23;32069:7;32054:14;:23::i;:::-;:31;;;32046:85;;;;;;;23573:2:1;32046:85:0;;;23555:21:1;23612:2;23592:18;;;23585:30;23651:34;23631:18;;;23624:62;23722:11;23702:18;;;23695:39;23751:19;;32046:85:0;23371:405:1;32046:85:0;32150:16;;;32142:65;;;;;;;16242:2:1;32142:65:0;;;16224:21:1;16281:2;16261:18;;;16254:30;16320:34;16300:18;;;16293:62;16391:6;16371:18;;;16364:34;16415:19;;32142:65:0;16040:400:1;32142:65:0;32220:39;32241:4;32247:2;32251:7;32220:20;:39::i;:::-;32324:29;32341:1;32345:7;32324:8;:29::i;:::-;32366:15;;;;;;;:9;:15;;;;;:20;;32385:1;;32366:15;:20;;32385:1;;32366:20;:::i;:::-;;;;-1:-1:-1;;32397:13:0;;;;;;;:9;:13;;;;;:18;;32414:1;;32397:13;:18;;32414:1;;32397:18;:::i;:::-;;;;-1:-1:-1;;32426:16:0;;;;:7;:16;;;;;;:21;;;;;;;;;;;;;;32465:27;;32426:16;;32465:27;;;;;;;31922:578;;;:::o;52058:190::-;52114:6;52150:16;52141:25;;;52133:76;;;;;;;26331:2:1;52133:76:0;;;26313:21:1;26370:2;26350:18;;;26343:30;26409:34;26389:18;;;26382:62;26480:8;26460:18;;;26453:36;26506:19;;52133:76:0;26129:402:1;52133:76:0;-1:-1:-1;52234:5:0;52058:190::o;31225:360::-;31285:13;31301:23;31316:7;31301:14;:23::i;:::-;31285:39;;31337:48;31358:5;31373:1;31377:7;31337:20;:48::i;:::-;31426:29;31443:1;31447:7;31426:8;:29::i;:::-;31468:16;;;;;;;:9;:16;;;;;:21;;31488:1;;31468:16;:21;;31488:1;;31468:21;:::i;:::-;;;;-1:-1:-1;;31507:16:0;;;;:7;:16;;;;;;31500:23;;;;;;31541:36;31515:7;;31507:16;31500:23;31541:36;;;;;31507:16;;31541:36;31274:311;31225:360;:::o;2973:173::-;3048:6;;;;3065:17;;;;;;;;;;;3098:40;;3048:6;;;3065:17;3048:6;;3098:40;;3029:16;;3098:40;3018:128;2973:173;:::o;28008:315::-;28165:28;28175:4;28181:2;28185:7;28165:9;:28::i;:::-;28212:48;28235:4;28241:2;28245:7;28254:5;28212:22;:48::i;:::-;28204:111;;;;;;;14355:2:1;28204:111:0;;;14337:21:1;14394:2;14374:18;;;14367:30;14433:34;14413:18;;;14406:62;14504:20;14484:18;;;14477:48;14542:19;;28204:111:0;14153:414:1;65902:100:0;65954:13;65987:7;65980:14;;;;;:::i;18697:723::-;18753:13;18974:10;18970:53;;-1:-1:-1;;19001:10:0;;;;;;;;;;;;;;;;;;18697:723::o;18970:53::-;19048:5;19033:12;19089:78;19096:9;;19089:78;;19122:8;;;;:::i;:::-;;-1:-1:-1;19145:10:0;;-1:-1:-1;19153:2:0;19145:10;;:::i;:::-;;;19089:78;;;19177:19;19209:6;19199:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19199:17:0;;19177:39;;19227:154;19234:10;;19227:154;;19261:11;19271:1;19261:11;;:::i;:::-;;-1:-1:-1;19330:10:0;19338:2;19330:5;:10;:::i;:::-;19317:24;;:2;:24;:::i;:::-;19304:39;;19287:6;19294;19287:14;;;;;;;;:::i;:::-;;;;:56;;;;;;;;;;-1:-1:-1;19358:11:0;19367:2;19358:11;;:::i;:::-;;;19227:154;;46317:1512;46445:7;47384:66;47370:80;;;47348:164;;;;;;;17360:2:1;47348:164:0;;;17342:21:1;17399:2;17379:18;;;17372:30;17438:34;17418:18;;;17411:62;17509:4;17489:18;;;17482:32;17531:19;;47348:164:0;17158:398:1;47348:164:0;47531:1;:7;;47536:2;47531:7;:18;;;;47542:1;:7;;47547:2;47542:7;47531:18;47523:65;;;;;;;21676:2:1;47523:65:0;;;21658:21:1;21715:2;21695:18;;;21688:30;21754:34;21734:18;;;21727:62;21825:4;21805:18;;;21798:32;21847:19;;47523:65:0;21474:398:1;47523:65:0;47703:24;;;47686:14;47703:24;;;;;;;;;10654:25:1;;;10727:4;10715:17;;10695:18;;;10688:45;;;;10749:18;;;10742:34;;;10792:18;;;10785:34;;;47703:24:0;;10626:19:1;;47703:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;47703:24:0;;;;;;-1:-1:-1;;47746:20:0;;;47738:57;;;;;;;11710:2:1;47738:57:0;;;11692:21:1;11749:2;11729:18;;;11722:30;11788:26;11768:18;;;11761:54;11832:18;;47738:57:0;11508:348:1;47738:57:0;47815:6;46317:1512;-1:-1:-1;;;;;46317:1512:0:o;45815:371::-;45926:7;46021:66;46013:75;;46115:3;46111:12;;;46125:2;46107:21;46156:22;46164:4;46107:21;46173:1;46013:75;46156:7;:22::i;:::-;46149:29;45815:371;-1:-1:-1;;;;;;45815:371:0:o;29957:321::-;30087:18;30093:2;30097:7;30087:5;:18::i;:::-;30138:54;30169:1;30173:2;30177:7;30186:5;30138:22;:54::i;:::-;30116:154;;;;;;;14355:2:1;30116:154:0;;;14337:21:1;14394:2;14374:18;;;14367:30;14433:34;14413:18;;;14406:62;14504:20;14484:18;;;14477:48;14542:19;;30116:154:0;14153:414:1;38460:589:0;38666:18;;;38662:187;;38701:40;38733:7;39876:10;:17;;39849:24;;;;:15;:24;;;;;:44;;;39904:24;;;;;;;;;;;;39772:164;38701:40;38662:187;;;38771:2;38763:10;;:4;:10;;;38759:90;;38790:47;38823:4;38829:7;38790:32;:47::i;:::-;38863:16;;;38859:183;;38896:45;38933:7;38896:36;:45::i;38859:183::-;38969:4;38963:10;;:2;:10;;;38959:83;;38990:40;39018:2;39022:7;38990:27;:40::i;33357:803::-;33512:4;33533:13;;;11593:20;11641:8;33529:624;;33569:72;;;;;:36;;;;;;:72;;741:10;;33620:4;;33626:7;;33635:5;;33569:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;33569:72:0;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;33565:533;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;33815:13:0;;33811:272;;33858:60;;;;;14355:2:1;33858:60:0;;;14337:21:1;14394:2;14374:18;;;14367:30;14433:34;14413:18;;;14406:62;14504:20;14484:18;;;14477:48;14542:19;;33858:60:0;14153:414:1;33811:272:0;34033:6;34027:13;34018:6;34014:2;34010:15;34003:38;33565:533;33692:55;;33702:45;33692:55;;-1:-1:-1;33685:62:0;;33529:624;-1:-1:-1;34137:4:0;34130:11;;30614:382;30694:16;;;30686:61;;;;;;;22438:2:1;30686:61:0;;;22420:21:1;;;22457:18;;;22450:30;22516:34;22496:18;;;22489:62;22568:18;;30686:61:0;22236:356:1;30686:61:0;28701:4;28725:16;;;:7;:16;;;;;;:30;:16;:30;30758:58;;;;;;;15181:2:1;30758:58:0;;;15163:21:1;15220:2;15200:18;;;15193:30;15259;15239:18;;;15232:58;15307:18;;30758:58:0;14979:352:1;30758:58:0;30829:45;30858:1;30862:2;30866:7;30829:20;:45::i;:::-;30887:13;;;;;;;:9;:13;;;;;:18;;30904:1;;30887:13;:18;;30904:1;;30887:18;:::i;:::-;;;;-1:-1:-1;;30916:16:0;;;;:7;:16;;;;;;:21;;;;;;;;;;;;;30955:33;;30916:16;;;30955:33;;30916:16;;30955:33;30614:382;;:::o;40563:988::-;40829:22;40879:1;40854:22;40871:4;40854:16;:22::i;:::-;:26;;;;:::i;:::-;40891:18;40912:26;;;:17;:26;;;;;;40829:51;;-1:-1:-1;41045:28:0;;;41041:328;;41112:18;;;41090:19;41112:18;;;:12;:18;;;;;;;;:34;;;;;;;;;41163:30;;;;;;:44;;;41280:30;;:17;:30;;;;;:43;;;41041:328;-1:-1:-1;41465:26:0;;;;:17;:26;;;;;;;;41458:33;;;41509:18;;;;;;:12;:18;;;;;:34;;;;;;;41502:41;40563:988::o;41846:1079::-;42124:10;:17;42099:22;;42124:21;;42144:1;;42124:21;:::i;:::-;42156:18;42177:24;;;:15;:24;;;;;;42550:10;:26;;42099:46;;-1:-1:-1;42177:24:0;;42099:46;;42550:26;;;;;;:::i;:::-;;;;;;;;;42528:48;;42614:11;42589:10;42600;42589:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;42694:28;;;:15;:28;;;;;;;:41;;;42866:24;;;;;42859:31;42901:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;41917:1008;;;41846:1079;:::o;39350:221::-;39435:14;39452:20;39469:2;39452:16;:20::i;:::-;39483:16;;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;39528:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;39350:221:0:o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:160:1;79:20;;135:13;;128:21;118:32;;108:60;;164:1;161;154:12;108:60;14:160;;;:::o;179:347::-;230:8;240:6;294:3;287:4;279:6;275:17;271:27;261:55;;312:1;309;302:12;261:55;-1:-1:-1;335:20:1;;378:18;367:30;;364:50;;;410:1;407;400:12;364:50;447:4;439:6;435:17;423:29;;499:3;492:4;483:6;475;471:19;467:30;464:39;461:59;;;516:1;513;506:12;461:59;179:347;;;;;:::o;531:247::-;590:6;643:2;631:9;622:7;618:23;614:32;611:52;;;659:1;656;649:12;611:52;698:9;685:23;717:31;742:5;717:31;:::i;1043:388::-;1111:6;1119;1172:2;1160:9;1151:7;1147:23;1143:32;1140:52;;;1188:1;1185;1178:12;1140:52;1227:9;1214:23;1246:31;1271:5;1246:31;:::i;:::-;1296:5;-1:-1:-1;1353:2:1;1338:18;;1325:32;1366:33;1325:32;1366:33;:::i;:::-;1418:7;1408:17;;;1043:388;;;;;:::o;1436:456::-;1513:6;1521;1529;1582:2;1570:9;1561:7;1557:23;1553:32;1550:52;;;1598:1;1595;1588:12;1550:52;1637:9;1624:23;1656:31;1681:5;1656:31;:::i;:::-;1706:5;-1:-1:-1;1763:2:1;1748:18;;1735:32;1776:33;1735:32;1776:33;:::i;:::-;1436:456;;1828:7;;-1:-1:-1;;;1882:2:1;1867:18;;;;1854:32;;1436:456::o;1897:1325::-;1992:6;2000;2008;2016;2069:3;2057:9;2048:7;2044:23;2040:33;2037:53;;;2086:1;2083;2076:12;2037:53;2125:9;2112:23;2144:31;2169:5;2144:31;:::i;:::-;2194:5;-1:-1:-1;2251:2:1;2236:18;;2223:32;2264:33;2223:32;2264:33;:::i;:::-;2316:7;-1:-1:-1;2370:2:1;2355:18;;2342:32;;-1:-1:-1;2425:2:1;2410:18;;2397:32;2448:18;2478:14;;;2475:34;;;2505:1;2502;2495:12;2475:34;2543:6;2532:9;2528:22;2518:32;;2588:7;2581:4;2577:2;2573:13;2569:27;2559:55;;2610:1;2607;2600:12;2559:55;2646:2;2633:16;2668:2;2664;2661:10;2658:36;;;2674:18;;:::i;:::-;2808:2;2802:9;2870:4;2862:13;;2713:66;2858:22;;;2882:2;2854:31;2850:40;2838:53;;;2906:18;;;2926:22;;;2903:46;2900:72;;;2952:18;;:::i;:::-;2992:10;2988:2;2981:22;3027:2;3019:6;3012:18;3067:7;3062:2;3057;3053;3049:11;3045:20;3042:33;3039:53;;;3088:1;3085;3078:12;3039:53;3144:2;3139;3135;3131:11;3126:2;3118:6;3114:15;3101:46;3189:1;3184:2;3179;3171:6;3167:15;3163:24;3156:35;3210:6;3200:16;;;;;;;1897:1325;;;;;;;:::o;3227:315::-;3292:6;3300;3353:2;3341:9;3332:7;3328:23;3324:32;3321:52;;;3369:1;3366;3359:12;3321:52;3408:9;3395:23;3427:31;3452:5;3427:31;:::i;:::-;3477:5;-1:-1:-1;3501:35:1;3532:2;3517:18;;3501:35;:::i;:::-;3491:45;;3227:315;;;;;:::o;3547:::-;3615:6;3623;3676:2;3664:9;3655:7;3651:23;3647:32;3644:52;;;3692:1;3689;3682:12;3644:52;3731:9;3718:23;3750:31;3775:5;3750:31;:::i;:::-;3800:5;3852:2;3837:18;;;;3824:32;;-1:-1:-1;;;3547:315:1:o;3867:383::-;3944:6;3952;3960;4013:2;4001:9;3992:7;3988:23;3984:32;3981:52;;;4029:1;4026;4019:12;3981:52;4068:9;4055:23;4087:31;4112:5;4087:31;:::i;:::-;4137:5;4189:2;4174:18;;4161:32;;-1:-1:-1;4240:2:1;4225:18;;;4212:32;;3867:383;-1:-1:-1;;;3867:383:1:o;4255:180::-;4311:6;4364:2;4352:9;4343:7;4339:23;4335:32;4332:52;;;4380:1;4377;4370:12;4332:52;4403:26;4419:9;4403:26;:::i;4440:245::-;4498:6;4551:2;4539:9;4530:7;4526:23;4522:32;4519:52;;;4567:1;4564;4557:12;4519:52;4606:9;4593:23;4625:30;4649:5;4625:30;:::i;4690:249::-;4759:6;4812:2;4800:9;4791:7;4787:23;4783:32;4780:52;;;4828:1;4825;4818:12;4780:52;4860:9;4854:16;4879:30;4903:5;4879:30;:::i;4944:410::-;5015:6;5023;5076:2;5064:9;5055:7;5051:23;5047:32;5044:52;;;5092:1;5089;5082:12;5044:52;5132:9;5119:23;5165:18;5157:6;5154:30;5151:50;;;5197:1;5194;5187:12;5151:50;5236:58;5286:7;5277:6;5266:9;5262:22;5236:58;:::i;:::-;5313:8;;5210:84;;-1:-1:-1;4944:410:1;-1:-1:-1;;;;4944:410:1:o;5359:180::-;5418:6;5471:2;5459:9;5450:7;5446:23;5442:32;5439:52;;;5487:1;5484;5477:12;5439:52;-1:-1:-1;5510:23:1;;5359:180;-1:-1:-1;5359:180:1:o;5544:545::-;5632:6;5640;5648;5656;5709:2;5697:9;5688:7;5684:23;5680:32;5677:52;;;5725:1;5722;5715:12;5677:52;5761:9;5748:23;5738:33;;5818:2;5807:9;5803:18;5790:32;5780:42;;5873:2;5862:9;5858:18;5845:32;5900:18;5892:6;5889:30;5886:50;;;5932:1;5929;5922:12;5886:50;5971:58;6021:7;6012:6;6001:9;5997:22;5971:58;:::i;:::-;5544:545;;;;-1:-1:-1;6048:8:1;-1:-1:-1;;;;5544:545:1:o;6094:385::-;6180:6;6188;6196;6204;6257:3;6245:9;6236:7;6232:23;6228:33;6225:53;;;6274:1;6271;6264:12;6225:53;-1:-1:-1;;6297:23:1;;;6367:2;6352:18;;6339:32;;-1:-1:-1;6418:2:1;6403:18;;6390:32;;6469:2;6454:18;6441:32;;-1:-1:-1;6094:385:1;-1:-1:-1;6094:385:1:o;6484:316::-;6525:3;6563:5;6557:12;6590:6;6585:3;6578:19;6606:63;6662:6;6655:4;6650:3;6646:14;6639:4;6632:5;6628:16;6606:63;:::i;:::-;6714:2;6702:15;6719:66;6698:88;6689:98;;;;6789:4;6685:109;;6484:316;-1:-1:-1;;6484:316:1:o;6805:470::-;6984:3;7022:6;7016:13;7038:53;7084:6;7079:3;7072:4;7064:6;7060:17;7038:53;:::i;:::-;7154:13;;7113:16;;;;7176:57;7154:13;7113:16;7210:4;7198:17;;7176:57;:::i;:::-;7249:20;;6805:470;-1:-1:-1;;;;6805:470:1:o;8446:511::-;8640:4;8669:42;8750:2;8742:6;8738:15;8727:9;8720:34;8802:2;8794:6;8790:15;8785:2;8774:9;8770:18;8763:43;;8842:6;8837:2;8826:9;8822:18;8815:34;8885:3;8880:2;8869:9;8865:18;8858:31;8906:45;8946:3;8935:9;8931:19;8923:6;8906:45;:::i;10830:449::-;10989:2;10978:9;10971:21;11028:6;11023:2;11012:9;11008:18;11001:34;11085:6;11077;11072:2;11061:9;11057:18;11044:48;11141:1;11112:22;;;11136:2;11108:31;;;11101:42;;;;11195:2;11183:15;;;11200:66;11179:88;11164:104;11160:113;;10830:449;-1:-1:-1;10830:449:1:o;11284:219::-;11433:2;11422:9;11415:21;11396:4;11453:44;11493:2;11482:9;11478:18;11470:6;11453:44;:::i;28301:128::-;28341:3;28372:1;28368:6;28365:1;28362:13;28359:39;;;28378:18;;:::i;:::-;-1:-1:-1;28414:9:1;;28301:128::o;28434:120::-;28474:1;28500;28490:35;;28505:18;;:::i;:::-;-1:-1:-1;28539:9:1;;28434:120::o;28559:228::-;28599:7;28725:1;28657:66;28653:74;28650:1;28647:81;28642:1;28635:9;28628:17;28624:105;28621:131;;;28732:18;;:::i;:::-;-1:-1:-1;28772:9:1;;28559:228::o;28792:125::-;28832:4;28860:1;28857;28854:8;28851:34;;;28865:18;;:::i;:::-;-1:-1:-1;28902:9:1;;28792:125::o;28922:258::-;28994:1;29004:113;29018:6;29015:1;29012:13;29004:113;;;29094:11;;;29088:18;29075:11;;;29068:39;29040:2;29033:10;29004:113;;;29135:6;29132:1;29129:13;29126:48;;;-1:-1:-1;;29170:1:1;29152:16;;29145:27;28922:258::o;29185:437::-;29264:1;29260:12;;;;29307;;;29328:61;;29382:4;29374:6;29370:17;29360:27;;29328:61;29435:2;29427:6;29424:14;29404:18;29401:38;29398:218;;;29472:77;29469:1;29462:88;29573:4;29570:1;29563:15;29601:4;29598:1;29591:15;29398:218;;29185:437;;;:::o;29627:195::-;29666:3;29697:66;29690:5;29687:77;29684:103;;;29767:18;;:::i;:::-;-1:-1:-1;29814:1:1;29803:13;;29627:195::o;29827:112::-;29859:1;29885;29875:35;;29890:18;;:::i;:::-;-1:-1:-1;29924:9:1;;29827:112::o;29944:184::-;29996:77;29993:1;29986:88;30093:4;30090:1;30083:15;30117:4;30114:1;30107:15;30133:184;30185:77;30182:1;30175:88;30282:4;30279:1;30272:15;30306:4;30303:1;30296:15;30322:184;30374:77;30371:1;30364:88;30471:4;30468:1;30461:15;30495:4;30492:1;30485:15;30511:184;30563:77;30560:1;30553:88;30660:4;30657:1;30650:15;30684:4;30681:1;30674:15;30700:184;30752:77;30749:1;30742:88;30849:4;30846:1;30839:15;30873:4;30870:1;30863:15;30889:154;30975:42;30968:5;30964:54;30957:5;30954:65;30944:93;;31033:1;31030;31023:12;31048:177;31133:66;31126:5;31122:78;31115:5;31112:89;31102:117;;31215:1;31212;31205:12

Swarm Source

ipfs://0879ddd20c10c505d2ee41ece4554495b9fea91701064358340ece2741ba0b11
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.