ETH Price: $3,380.31 (-8.09%)

Token

VTuberNft (VTUBE)
 

Overview

Max Total Supply

43 VTUBE

Holders

19

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Filtered by Token Holder
hatoyashi.eth
Balance
1 VTUBE
0x088e25e6027816c753d01d7f243c367710f20497
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
VTuberNft

Compiler Version
v0.8.1+commit.df193b15

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

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

// File openzeppelin-solidity/contracts/utils/introspection/[email protected]

// SPDX-License-Identifier: MIT

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-solidity/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-solidity/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-solidity/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-solidity/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;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

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

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

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

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

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

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

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

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

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

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

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

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

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

    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

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


// File openzeppelin-solidity/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) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}


// File openzeppelin-solidity/contracts/utils/[email protected]


pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant alphabet = "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] = alphabet[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

}


// File openzeppelin-solidity/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 contracts/erc/ERC721.sol


pragma solidity ^0.8.0;







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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: 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}. 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 || ERC721.isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

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

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _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 || ERC721.isApprovedForAll(owner, spender));
    }

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

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

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

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

        _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 {
                    // solhint-disable-next-line no-inline-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

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


// File contracts/roles/Roles.sol


pragma solidity ^0.8.0;

library Roles {
    struct Role {
        mapping(address => bool) bearer;
    }

    function add(Role storage role, address account) internal {
        require(!has(role, account), "role already has the account");
        role.bearer[account] = true;
    }

    function remove(Role storage role, address account) internal {
        require(has(role, account), "role dosen't have the account");
        role.bearer[account] = false;
    }

    function has(Role storage role, address account)
        internal
        view
        returns (bool)
    {
        return role.bearer[account];
    }
}


// File contracts/roles/ERC173.sol


pragma solidity ^0.8.0;

//import "openzeppelin-solidity/contracts/utils/introspection/ERC165.sol";

/// @title ERC-173 Contract Ownership Standard
/// @dev See https://github.com/ethereum/EIPs/blob/master/EIPS/eip-173.md
///  Note: the ERC-165 identifier for this interface is 0x7f5828d0
interface IERC173 /* is ERC165 */ {
    /// @dev This emits when ownership of a contract changes.
    event OwnershipTransferred(address indexed previousOwner, address indexed newOwner);

    /// @notice Get the address of the owner
    /// @return The address of the owner.
    function owner() external view returns (address);

    /// @notice Set the address of the new owner of the contract
    /// @param _newOwner The address of the new owner of the contract
    function transferOwnership(address _newOwner) external;
}

abstract contract ERC173 is IERC173 {
    address private _owner;

    constructor() {
        _transferOwnership(msg.sender);
    }

    modifier onlyOwner() {
        require(msg.sender == owner(), "Must be owner");
        _;
    }

    function owner() override public view returns (address) {
        return _owner;
    }

    function transferOwnership(address _newOwner) virtual override public onlyOwner() {
        _transferOwnership(_newOwner);
    }

    function _transferOwnership(address _newOwner) internal {
        address previousOwner = owner();
	_owner = _newOwner;
        emit OwnershipTransferred(previousOwner, _newOwner);
    }
}


// File contracts/roles/Operatable.sol


pragma solidity ^0.8.0;


abstract contract Operatable is ERC173 {
    using Roles for Roles.Role;

    event OperatorAdded(address indexed account);
    event OperatorRemoved(address indexed account);

    event Paused(address account);
    event Unpaused(address account);

    bool private _paused;
    Roles.Role private operators;

    constructor() {
        operators.add(msg.sender);
        _paused = false;
    }

    modifier onlyOperator() {
        require(isOperator(msg.sender), "Must be operator");
        _;
    }

    modifier whenNotPaused() {
        require(!_paused, "Pausable: paused");
        _;
    }

    modifier whenPaused() {
        require(_paused, "Pausable: not paused");
        _;
    }

    function transferOwnership(address _newOwner)
        public
        override
        onlyOperator()
    {
        _transferOwnership(_newOwner);
    }

    function isOperator(address account) public view returns (bool) {
        return operators.has(account);
    }

    function addOperator(address account) public onlyOperator() {
        operators.add(account);
        emit OperatorAdded(account);
    }

    function removeOperator(address account) public onlyOperator() {
        operators.remove(account);
        emit OperatorRemoved(account);
    }

    function paused() public view returns (bool) {
        return _paused;
    }

    function pause() public onlyOperator() whenNotPaused() {
        _paused = true;
        emit Paused(msg.sender);
    }

    function unpause() public onlyOperator() whenPaused() {
        _paused = false;
        emit Unpaused(msg.sender);
    }
}


// File contracts/erc/ERC721Mintable.sol


pragma solidity ^0.8.0;


interface IERC721Mintable {
    event MinterAdded(address indexed account);
    event MinterRemoved(address indexed account);
    function exists(uint256 _tokenId) external view returns (bool);
    function mint(address _to, uint256 _tokenId) external;
    function isMinter(address account) external view returns (bool);
    function addMinter(address account) external;
    function removeMinter(address account) external;
}

abstract contract ERC721Mintable is ERC721, IERC721Mintable, Operatable {
    using Roles for Roles.Role;
    Roles.Role private minters;

    constructor () {
        addMinter(msg.sender);
    }

    modifier onlyMinter() {
        require(isMinter(msg.sender), "Must be minter");
        _;
    }

    function isMinter(address account) override public view returns (bool) {
        return minters.has(account);
    }

    function addMinter(address account) override public onlyOperator() {
        minters.add(account);
        emit MinterAdded(account);
    }

    function removeMinter(address account) override public onlyOperator() {
        minters.remove(account);
        emit MinterRemoved(account);
    }
    
    function exists(uint256 tokenId) override public view returns (bool) {
        return super._exists(tokenId);
    }

    function mint(address to, uint256 tokenId) virtual override public onlyMinter() {
        super._mint(to, tokenId);
    }

}


// File contracts/erc/ERC721Burnable.sol


pragma solidity ^0.8.0;


abstract contract ERC721Burnable is ERC721, Operatable {
    using Address for address;
    using Roles for Roles.Role;
    Roles.Role private burners;

    modifier onlyBurner() {
        require(isBurner(msg.sender), "Must be burner");
        _;
    }

    event BurnerAdded(address indexed account);
    event BurnerRemoved(address indexed account);

    constructor () {}

    function isBurner(address account) public view returns (bool) {
        return burners.has(account);
    }

    function addBurner(address account) public onlyOperator() {
        require(account.isContract(), "Burner must be contract");
        burners.add(account);
        emit BurnerAdded(account);
    }

    function removeBurner(address account) public onlyOperator() {
        burners.remove(account);
        emit BurnerRemoved(account);
    }

    function burn(uint256 tokenId) virtual public onlyBurner {
        require(_isApprovedOrOwner(msg.sender, tokenId), "ERC721Burnable: caller is not owner nor approved");
        _burn(tokenId);
    }
}


// File openzeppelin-solidity/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.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        // Check the signature length
        if (signature.length != 65) {
            revert("ECDSA: invalid signature length");
        }

        // Divide the signature in r, s and v variables
        bytes32 r;
        bytes32 s;
        uint8 v;

        // ecrecover takes the signature parameters, and the only way to get them
        // currently is to use assembly.
        // solhint-disable-next-line no-inline-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);
    }

    /**
     * @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-solidity/contracts/utils/[email protected]


pragma solidity ^0.8.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented or decremented by one. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }
}


// File openzeppelin-solidity/contracts/utils/cryptography/[email protected]


pragma solidity ^0.8.0;

/**
 * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
 *
 * The encoding specified in the EIP is very generic, and such a generic implementation in Solidity is not feasible,
 * thus this contract does not implement the encoding itself. Protocols need to implement the type-specific encoding
 * they need in their contracts using a combination of `abi.encode` and `keccak256`.
 *
 * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
 * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
 * ({_hashTypedDataV4}).
 *
 * The implementation of the domain separator was designed to be as efficient as possible while still properly updating
 * the chain id to protect against replay attacks on an eventual fork of the chain.
 *
 * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
 * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
 *
 * _Available since v3.4._
 */
abstract contract EIP712 {
    /* solhint-disable var-name-mixedcase */
    // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to
    // invalidate the cached domain separator if the chain id changes.
    bytes32 private immutable _CACHED_DOMAIN_SEPARATOR;
    uint256 private immutable _CACHED_CHAIN_ID;

    bytes32 private immutable _HASHED_NAME;
    bytes32 private immutable _HASHED_VERSION;
    bytes32 private immutable _TYPE_HASH;
    /* solhint-enable var-name-mixedcase */

    /**
     * @dev Initializes the domain separator and parameter caches.
     *
     * The meaning of `name` and `version` is specified in
     * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:
     *
     * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.
     * - `version`: the current major version of the signing domain.
     *
     * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
     * contract upgrade].
     */
    constructor(string memory name, string memory version) {
        bytes32 hashedName = keccak256(bytes(name));
        bytes32 hashedVersion = keccak256(bytes(version));
        bytes32 typeHash = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
        _HASHED_NAME = hashedName;
        _HASHED_VERSION = hashedVersion;
        _CACHED_CHAIN_ID = block.chainid;
        _CACHED_DOMAIN_SEPARATOR = _buildDomainSeparator(typeHash, hashedName, hashedVersion);
        _TYPE_HASH = typeHash;
    }

    /**
     * @dev Returns the domain separator for the current chain.
     */
    function _domainSeparatorV4() internal view returns (bytes32) {
        if (block.chainid == _CACHED_CHAIN_ID) {
            return _CACHED_DOMAIN_SEPARATOR;
        } else {
            return _buildDomainSeparator(_TYPE_HASH, _HASHED_NAME, _HASHED_VERSION);
        }
    }

    function _buildDomainSeparator(bytes32 typeHash, bytes32 name, bytes32 version) private view returns (bytes32) {
        return keccak256(
            abi.encode(
                typeHash,
                name,
                version,
                block.chainid,
                address(this)
            )
        );
    }

    /**
     * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
     * function returns the hash of the fully encoded EIP712 message for this domain.
     *
     * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:
     *
     * ```solidity
     * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
     *     keccak256("Mail(address to,string contents)"),
     *     mailTo,
     *     keccak256(bytes(mailContents))
     * )));
     * address signer = ECDSA.recover(digest, signature);
     * ```
     */
    function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
        return ECDSA.toTypedDataHash(_domainSeparatorV4(), structHash);
    }
}


// File contracts/erc/ERC721Permit.sol


pragma solidity ^0.8.0;




interface IERC721Permit {
    function permit(address owner, address spender, uint256 amount, uint256 deadline, uint8 v, bytes32 r, bytes32 s) external;
    function nonces(address owner) external view returns (uint256);
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

/**
 * @dev Implementation of the ERC721 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC721 allowance (see {IERC721-allowance}) by
 * presenting a message signed by the account. By not relying on `{IERC721-approve}`, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
abstract contract ERC721Permit is ERC721, IERC721Permit, EIP712 {
    using Counters for Counters.Counter;

    mapping (address => Counters.Counter) private _nonces;

    // solhint-disable-next-line var-name-mixedcase
    bytes32 private immutable _PERMIT_TYPEHASH = keccak256("Permit(address owner,address spender,uint256 tokenId,uint256 nonce,uint256 deadline)");

    /**
     * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`.
     *
     * It's a good idea to use the same `name` that is defined as the ERC721 token name.
     */
    constructor(string memory name) EIP712(name, "1") {
    }

    /**
     * @dev See {IERC721Permit-permit}.
     */
    function permit(address owner, address spender, uint256 tokenId, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public virtual override {

        address tokenOwner = ownerOf(tokenId);
        require(spender != tokenOwner, "ERC721Permit: approval to current owner");
        require(tokenOwner == owner || isApprovedForAll(tokenOwner, owner),
            "ERC721Permit: approve signer is not owner nor approved for all"
        );

        // solhint-disable-next-line not-rely-on-time
        require(block.timestamp <= deadline, "ERC721Permit: expired deadline");

        bytes32 structHash = keccak256(
            abi.encode(
                _PERMIT_TYPEHASH,
                owner,
                spender,
                tokenId,
                _nonces[owner].current(),
                deadline
            )
        );

        bytes32 hash = _hashTypedDataV4(structHash);

        address signer = ECDSA.recover(hash, v, r, s);
        require(signer == owner, "ERC721Permit: invalid signature");

        _nonces[owner].increment();
        super._approve(spender, tokenId);
    }

    /**
     * @dev See {IERC721Permit-nonces}.
     */
    function nonces(address owner) public view override returns (uint256) {
        return _nonces[owner].current();
    }

    /**
     * @dev See {IERC721Permit-DOMAIN_SEPARATOR}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view override returns (bytes32) {
        return _domainSeparatorV4();
    }

    function getDigest(bytes32 structHash) public view returns (bytes32) {
        return _hashTypedDataV4(structHash);
    }
}


// File contracts/erc/ERC721Metadata.sol


pragma solidity ^0.8.0;




abstract contract ERC721Metadata is IERC721Metadata, ERC721, Operatable {
    using Strings for uint256;

    string private _defaultURI;
    string private baseURI;

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

    event UpdateDefaultURI(string defaultURI);
    event UpdateBaseURI(string baseURI);
    event UpdateTokenURI(uint256 tokenId, string tokenURI);

    constructor(string memory name_, string memory symbol_, string memory defaultURI_) 
        ERC721(name_, symbol_) {
        setDefaultURI(defaultURI_);
    }

    function setDefaultURI(string memory defaultURI_) public onlyOperator() {
        _defaultURI = defaultURI_;
        emit UpdateDefaultURI(_defaultURI);
    }

    function setBaseURI(string memory baseURI_) public onlyOperator() {
        baseURI = baseURI_;
        emit UpdateBaseURI(baseURI_);
    }

    function getTokenURI(uint256 tokenId) public view returns (string memory) {
        require(_exists(tokenId), "getTokenURI query for nonexistent token");

        return _tokenURIs[tokenId];
    }

    // set specific uri by tokenID
    function setTokenURI(uint256 tokenId, string memory _tokenURI) public onlyOperator() {
        require(_exists(tokenId), "setTokenURI query for nonexistent token");
        _tokenURIs[tokenId] = _tokenURI;
        emit UpdateTokenURI(tokenId, _tokenURI);
    }

    function tokenURI(uint256 tokenId) virtual public view override(IERC721Metadata, ERC721) returns (string memory) {
        string memory _tokenURI = getTokenURI(tokenId);

        // baseURI + sepecific _tokenURI
        if (bytes(_tokenURI).length > 0) {
            return string(abi.encodePacked(baseURI, tokenId.toString()));
        }

        // If there is no tokenURI, defaultURI + tokenID
        return string(abi.encodePacked(_defaultURI, tokenId.toString()));
    }

}


// File contracts/VTuberNft.sol


pragma solidity 0.8.1;




contract VTuberNft is
    ERC721Mintable,
    ERC721Burnable,
    ERC721Permit("VTuberNft"),
    ERC721Metadata(
        "VTuberNft",
        "VTUBE",
        "https://vtubernft.herokuapp.com/api/metadata/"
    )
{

    uint256 private totalCount = 0;

    constructor() {}

    function mint(address to, uint256 tokenId) public override onlyMinter() {
        totalCount++;
        super.mint(to, tokenId);
    }

    function bulkMint(address[] memory _tos, uint256[] memory _tokenIds) public onlyMinter {
        require(_tos.length == _tokenIds.length);
        uint8 i;
        for (i = 0; i < _tos.length; i++) {
          mint(_tos[i], _tokenIds[i]);
        }
    }

    function burn(uint256 _tokenId) override public onlyBurner() {
        totalCount--;
        super.burn(_tokenId);
    }

    function totalSupply() public view returns (uint256) {
        return totalCount;
    }

    function tokenURI(uint256 tokenId) public view override(ERC721Metadata, ERC721) returns (string memory) {
        return super.tokenURI(tokenId);
    }

}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"BurnerAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"BurnerRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"MinterAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"MinterRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"OperatorAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"}],"name":"OperatorRemoved","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"baseURI","type":"string"}],"name":"UpdateBaseURI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"defaultURI","type":"string"}],"name":"UpdateDefaultURI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"string","name":"tokenURI","type":"string"}],"name":"UpdateTokenURI","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addBurner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_tos","type":"address[]"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"bulkMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"exists","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"structHash","type":"bytes32"}],"name":"getDigest","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isBurner","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isMinter","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isOperator","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeBurner","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeMinter","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeOperator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI_","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"defaultURI_","type":"string"}],"name":"setDefaultURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"_tokenURI","type":"string"}],"name":"setTokenURI","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":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6101406040527f48d39b37a35214940203bbbd4f383519797769b13d936f387d89430afef27688610120526000600e553480156200003c57600080fd5b506040518060400160405280600981526020016815951d58995c93999d60ba1b81525060405180604001604052806005815260200164565455424560d81b8152506040518060600160405280602d8152602001620034ce602d91396040518060400160405280600981526020016815951d58995c93999d60ba1b81525080604051806040016040528060018152602001603160f81b81525085858160009080519060200190620000ee929190620003fe565b50805162000104906001906020840190620003fe565b5050506200011833620001be60201b60201c565b620001333360076200021e60201b620012b01790919060201c565b6006805460ff60a01b191690556200014b3362000278565b815160208084019190912082519183019190912060c082905260e08190524660a0527f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f6200019b818484620002f4565b6080526101005250620001b5935084925050620003309050565b50505062000639565b6000620001ca620003ad565b600680546001600160a01b0319166001600160a01b0385811691821790925560405192935091908316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6200022a8282620003bc565b15620002535760405162461bcd60e51b81526004016200024a90620005b0565b60405180910390fd5b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b6200028333620003db565b620002a25760405162461bcd60e51b81526004016200024a9062000586565b620002bd8160086200021e60201b620012b01790919060201c565b6040516001600160a01b038216907f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f690600090a250565b6000838383463060405160200162000311959493929190620004a4565b6040516020818303038152906040528051906020012090509392505050565b6200033b33620003db565b6200035a5760405162461bcd60e51b81526004016200024a9062000586565b80516200036f90600b906020840190620003fe565b507f2405b30cce1d59580c3cc7fbdce2d552bd8e943d5dc4f66a37053027fc7ce880600b604051620003a29190620004d0565b60405180910390a150565b6006546001600160a01b031690565b6001600160a01b03166000908152602091909152604090205460ff1690565b6000620003f8826007620003bc60201b620012fc1790919060201c565b92915050565b8280546200040c90620005fc565b90600052602060002090601f0160209004810192826200043057600085556200047b565b82601f106200044b57805160ff19168380011785556200047b565b828001600101855582156200047b579182015b828111156200047b5782518255916020019190600101906200045e565b50620004899291506200048d565b5090565b5b808211156200048957600081556001016200048e565b9485526020850193909352604084019190915260608301526001600160a01b0316608082015260a00190565b6000602080835281845483600282049050600180831680620004f357607f831692505b8583108114156200051257634e487b7160e01b87526022600452602487fd5b6200052083878a01620005f3565b818015620005375760018114620005495762000577565b60ff1986168252878201965062000577565b620005548b620005e7565b895b86811015620005715781548482015290850190890162000556565b83019750505b50949998505050505050505050565b60208082526010908201526f26bab9ba1031329037b832b930ba37b960811b604082015260600190565b6020808252601c908201527f726f6c6520616c72656164792068617320746865206163636f756e7400000000604082015260600190565b60009081526020902090565b90815260200190565b6002810460018216806200061157607f821691505b602082108114156200063357634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05160c05160e0516101005161012051612e45620006896000396000611068015260006116130152600061165501526000611634015260006115c1015260006115ea0152612e456000f3fe608060405234801561001057600080fd5b50600436106102485760003560e01c80636ae459bd1161013b578063aa271e1a116100b8578063da1b9e081161007c578063da1b9e08146104cd578063e985e9c5146104e0578063f2fde38b146104f3578063f44637ba14610506578063f9613ab21461051957610248565b8063aa271e1a1461046e578063ac8a584a14610481578063b88d4fde14610494578063c87b56dd146104a7578063d505accf146104ba57610248565b80638da5cb5b116100ff5780638da5cb5b1461042557806395d89b411461042d578063983b2d56146104355780639870d7fe14610448578063a22cb4651461045b57610248565b80636ae459bd146103d15780636d70f7ae146103e457806370a08231146103f75780637ecebe001461040a5780638456cb591461041d57610248565b80633bb3a24d116101c95780634334614a1161018d5780634334614a1461037d5780634f558e791461039057806355f804b3146103a35780635c975abb146103b65780636352211e146103be57610248565b80633bb3a24d146103295780633f4ba83a1461033c57806340c10f191461034457806342842e0e1461035757806342966c681461036a57610248565b8063162094c411610210578063162094c4146102d357806318160ddd146102e657806323b872dd146102fb5780633092afd51461030e5780633644e5151461032157610248565b806301ffc9a71461024d578063028468581461027657806306fdde031461028b578063081812fc146102a0578063095ea7b3146102c0575b600080fd5b61026061025b366004612197565b61052c565b60405161026d9190612355565b60405180910390f35b610289610284366004611eed565b610574565b005b6102936105e4565b60405161026d91906123e7565b6102b36102ae36600461217f565b610677565b60405161026d9190612304565b6102896102ce366004612098565b6106ba565b6102896102e1366004612202565b610752565b6102ee6107f9565b60405161026d9190612360565b610289610309366004611f39565b6107ff565b61028961031c366004611eed565b610837565b6102ee61089e565b61029361033736600461217f565b6108ad565b610289610972565b610289610352366004612098565b610a07565b610289610365366004611f39565b610a4f565b61028961037836600461217f565b610a6a565b61026061038b366004611eed565b610ab0565b61026061039e36600461217f565b610abd565b6102896103b13660046121cf565b610ac8565b610260610b3b565b6102b36103cc36600461217f565b610b4b565b6102896103df3660046120c1565b610b80565b6102606103f2366004611eed565b610c32565b6102ee610405366004611eed565b610c3f565b6102ee610418366004611eed565b610c83565b610289610ca4565b6102b3610d36565b610293610d45565b610289610443366004611eed565b610d54565b610289610456366004611eed565b610dbb565b61028961046936600461205e565b610e22565b61026061047c366004611eed565b610ef0565b61028961048f366004611eed565b610efd565b6102896104a2366004611f74565b610f64565b6102936104b536600461217f565b610fa3565b6102896104c8366004611fed565b610fae565b6102896104db3660046121cf565b61114b565b6102606104ee366004611f07565b6111b4565b610289610501366004611eed565b6111e2565b610289610514366004611eed565b611210565b6102ee61052736600461217f565b6112a5565b60006001600160e01b031982166380ac58cd60e01b148061055d57506001600160e01b03198216635b5e139f60e01b145b8061056c575061056c8261131b565b90505b919050565b61057d33610c32565b6105a25760405162461bcd60e51b8152600401610599906124e0565b60405180910390fd5b6105ad600982611334565b6040516001600160a01b038216907f90eabbc0c667db2a5029ed6bc0f5fe9f356d11684a4ca9fcfaec0e53f12b9c8e90600090a250565b6060600080546105f390612d2d565b80601f016020809104026020016040519081016040528092919081815260200182805461061f90612d2d565b801561066c5780601f106106415761010080835404028352916020019161066c565b820191906000526020600020905b81548152906001019060200180831161064f57829003601f168201915b505050505090505b90565b60006106828261137c565b61069e5760405162461bcd60e51b81526004016105999061294f565b506000908152600460205260409020546001600160a01b031690565b60006106c582610b4b565b9050806001600160a01b0316836001600160a01b031614156106f95760405162461bcd60e51b815260040161059990612ac1565b806001600160a01b031661070b611399565b6001600160a01b031614806107275750610727816104ee611399565b6107435760405162461bcd60e51b8152600401610599906127a1565b61074d838361139d565b505050565b61075b33610c32565b6107775760405162461bcd60e51b8152600401610599906124e0565b6107808261137c565b61079c5760405162461bcd60e51b815260040161059990612a1b565b6000828152600d6020908152604090912082516107bb92840190611d53565b507f0418254f69edc41d3d2b429767526234e99f60018e7e21cda80307bf3ef28cc482826040516107ed929190612c39565b60405180910390a15050565b600e5490565b61081061080a611399565b8261140b565b61082c5760405162461bcd60e51b815260040161059990612b02565b61074d838383611490565b61084033610c32565b61085c5760405162461bcd60e51b8152600401610599906124e0565b610867600882611334565b6040516001600160a01b038216907fe94479a9f7e1952cc78f2d6baab678adc1b772d936c6583def489e524cb6669290600090a250565b60006108a86115bd565b905090565b60606108b88261137c565b6108d45760405162461bcd60e51b815260040161059990612891565b6000828152600d6020526040902080546108ed90612d2d565b80601f016020809104026020016040519081016040528092919081815260200182805461091990612d2d565b80156109665780601f1061093b57610100808354040283529160200191610966565b820191906000526020600020905b81548152906001019060200180831161094957829003601f168201915b50505050509050919050565b61097b33610c32565b6109975760405162461bcd60e51b8152600401610599906124e0565b600654600160a01b900460ff166109c05760405162461bcd60e51b8152600401610599906124b2565b6006805460ff60a01b191690556040517f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906109fd903390612304565b60405180910390a1565b610a1033610ef0565b610a2c5760405162461bcd60e51b815260040161059990612b53565b600e8054906000610a3c83612d68565b9190505550610a4b8282611680565b5050565b61074d83838360405180602001604052806000815250610f64565b610a7333610ab0565b610a8f5760405162461bcd60e51b815260040161059990612a62565b600e8054906000610a9f83612d16565b9190505550610aad816116af565b50565b600061056c6009836112fc565b600061056c8261137c565b610ad133610c32565b610aed5760405162461bcd60e51b8152600401610599906124e0565b8051610b0090600c906020840190611d53565b507f157d450c8fb1377294d9db75af1de2753efc52d8e5578551d70d2c7d9cd74df981604051610b3091906123e7565b60405180910390a150565b600654600160a01b900460ff1690565b6000818152600260205260408120546001600160a01b03168061056c5760405162461bcd60e51b815260040161059990612848565b610b8933610ef0565b610ba55760405162461bcd60e51b815260040161059990612b53565b8051825114610bb357600080fd5b60005b82518160ff16101561074d57610c20838260ff1681518110610be857634e487b7160e01b600052603260045260246000fd5b6020026020010151838360ff1681518110610c1357634e487b7160e01b600052603260045260246000fd5b6020026020010151610a07565b80610c2a81612d83565b915050610bb6565b600061056c6007836112fc565b60006001600160a01b038216610c675760405162461bcd60e51b8152600401610599906127fe565b506001600160a01b031660009081526003602052604090205490565b6001600160a01b0381166000908152600a6020526040812061056c90611703565b610cad33610c32565b610cc95760405162461bcd60e51b8152600401610599906124e0565b600654600160a01b900460ff1615610cf35760405162461bcd60e51b815260040161059990612777565b6006805460ff60a01b1916600160a01b1790556040517f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258906109fd903390612304565b6006546001600160a01b031690565b6060600180546105f390612d2d565b610d5d33610c32565b610d795760405162461bcd60e51b8152600401610599906124e0565b610d846008826112b0565b6040516001600160a01b038216907f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f690600090a250565b610dc433610c32565b610de05760405162461bcd60e51b8152600401610599906124e0565b610deb6007826112b0565b6040516001600160a01b038216907fac6fa858e9350a46cec16539926e0fde25b7629f84b5a72bffaae4df888ae86d90600090a250565b610e2a611399565b6001600160a01b0316826001600160a01b03161415610e5b5760405162461bcd60e51b81526004016105999061261e565b8060056000610e68611399565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155610eac611399565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610ee49190612355565b60405180910390a35050565b600061056c6008836112fc565b610f0633610c32565b610f225760405162461bcd60e51b8152600401610599906124e0565b610f2d600782611334565b6040516001600160a01b038216907f80c0b871b97b595b16a7741c1b06fed0c6f6f558639f18ccbce50724325dc40d90600090a250565b610f75610f6f611399565b8361140b565b610f915760405162461bcd60e51b815260040161059990612b02565b610f9d84848484611707565b50505050565b606061056c8261173a565b6000610fb986610b4b565b9050806001600160a01b0316876001600160a01b03161415610fed5760405162461bcd60e51b815260040161059990612593565b876001600160a01b0316816001600160a01b03161480611012575061101281896111b4565b61102e5760405162461bcd60e51b8152600401610599906126ce565b8442111561104e5760405162461bcd60e51b81526004016105999061299b565b6001600160a01b0388166000908152600a602052604081207f0000000000000000000000000000000000000000000000000000000000000000908a908a908a9061109790611703565b8a6040516020016110ad96959493929190612369565b60405160208183030381529060405280519060200120905060006110d0826117b7565b905060006110e0828888886117ca565b90508a6001600160a01b0316816001600160a01b0316146111135760405162461bcd60e51b815260040161059990612655565b6001600160a01b038b166000908152600a60205260409020611134906118c0565b61113e8a8a61139d565b5050505050505050505050565b61115433610c32565b6111705760405162461bcd60e51b8152600401610599906124e0565b805161118390600b906020840190611d53565b507f2405b30cce1d59580c3cc7fbdce2d552bd8e943d5dc4f66a37053027fc7ce880600b604051610b3091906123fa565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6111eb33610c32565b6112075760405162461bcd60e51b8152600401610599906124e0565b610aad816118c9565b61121933610c32565b6112355760405162461bcd60e51b8152600401610599906124e0565b611247816001600160a01b0316611927565b6112635760405162461bcd60e51b815260040161059990612b7b565b61126e6009826112b0565b6040516001600160a01b038216907f86e57fd2b90329052917118de7c3f521f400d439b9650deaa906a25b08b9456090600090a250565b600061056c826117b7565b6112ba82826112fc565b156112d75760405162461bcd60e51b815260040161059990612a8a565b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b6001600160a01b03166000908152602091909152604090205460ff1690565b6001600160e01b031981166301ffc9a760e01b14919050565b61133e82826112fc565b61135a5760405162461bcd60e51b815260040161059990612c02565b6001600160a01b0316600090815260209190915260409020805460ff19169055565b6000908152600260205260409020546001600160a01b0316151590565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906113d282610b4b565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006114168261137c565b6114325760405162461bcd60e51b81526004016105999061272b565b600061143d83610b4b565b9050806001600160a01b0316846001600160a01b031614806114785750836001600160a01b031661146d84610677565b6001600160a01b0316145b80611488575061148881856111b4565b949350505050565b826001600160a01b03166114a382610b4b565b6001600160a01b0316146114c95760405162461bcd60e51b8152600401610599906129d2565b6001600160a01b0382166114ef5760405162461bcd60e51b8152600401610599906125da565b6114fa83838361074d565b61150560008261139d565b6001600160a01b038316600090815260036020526040812080546001929061152e908490612cd3565b90915550506001600160a01b038216600090815260036020526040812080546001929061155c908490612ca7565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b60007f000000000000000000000000000000000000000000000000000000000000000046141561160e57507f0000000000000000000000000000000000000000000000000000000000000000610674565b6116797f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000061192d565b9050610674565b61168933610ef0565b6116a55760405162461bcd60e51b815260040161059990612b53565b610a4b8282611967565b6116b833610ab0565b6116d45760405162461bcd60e51b815260040161059990612a62565b6116de338261140b565b6116fa5760405162461bcd60e51b815260040161059990612bb2565b610aad81611a46565b5490565b611712848484611490565b61171e84848484611aed565b610f9d5760405162461bcd60e51b81526004016105999061250a565b60606000611747836108ad565b80519091501561178457600c61175c84611c05565b60405160200161176d929190612269565b60405160208183030381529060405291505061056f565b600b61178f84611c05565b6040516020016117a0929190612269565b604051602081830303815290604052915050919050565b600061056c6117c46115bd565b83611d20565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a082111561180c5760405162461bcd60e51b81526004016105999061268c565b8360ff16601b148061182157508360ff16601c145b61183d5760405162461bcd60e51b8152600401610599906128d8565b60006001868686866040516000815260200160405260405161186294939291906123c9565b6020604051602081039080840390855afa158015611884573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166118b75760405162461bcd60e51b81526004016105999061247b565b95945050505050565b80546001019055565b60006118d3610d36565b600680546001600160a01b0319166001600160a01b0385811691821790925560405192935091908316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b3b151590565b6000838383463060405160200161194895949392919061239d565b6040516020818303038152906040528051906020012090509392505050565b6001600160a01b03821661198d5760405162461bcd60e51b81526004016105999061291a565b6119968161137c565b156119b35760405162461bcd60e51b81526004016105999061255c565b6119bf6000838361074d565b6001600160a01b03821660009081526003602052604081208054600192906119e8908490612ca7565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000611a5182610b4b565b9050611a5f8160008461074d565b611a6a60008361139d565b6001600160a01b0381166000908152600360205260408120805460019290611a93908490612cd3565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6000611b01846001600160a01b0316611927565b15611bfd57836001600160a01b031663150b7a02611b1d611399565b8786866040518563ffffffff1660e01b8152600401611b3f9493929190612318565b602060405180830381600087803b158015611b5957600080fd5b505af1925050508015611b89575060408051601f3d908101601f19168201909252611b86918101906121b3565b60015b611be3573d808015611bb7576040519150601f19603f3d011682016040523d82523d6000602084013e611bbc565b606091505b508051611bdb5760405162461bcd60e51b81526004016105999061250a565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611488565b506001611488565b606081611c2a57506040805180820190915260018152600360fc1b602082015261056f565b8160005b8115611c545780611c3e81612d68565b9150611c4d9050600a83612cbf565b9150611c2e565b60008167ffffffffffffffff811115611c7d57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611ca7576020820181803683370190505b5090505b841561148857611cbc600183612cd3565b9150611cc9600a86612da3565b611cd4906030612ca7565b60f81b818381518110611cf757634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350611d19600a86612cbf565b9450611cab565b60008282604051602001611d359291906122e9565b60405160208183030381529060405280519060200120905092915050565b828054611d5f90612d2d565b90600052602060002090601f016020900481019282611d815760008555611dc7565b82601f10611d9a57805160ff1916838001178555611dc7565b82800160010185558215611dc7579182015b82811115611dc7578251825591602001919060010190611dac565b50611dd3929150611dd7565b5090565b5b80821115611dd35760008155600101611dd8565b600067ffffffffffffffff831115611e0657611e06612de3565b611e19601f8401601f1916602001612c52565b9050828152838383011115611e2d57600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b038116811461056f57600080fd5b600082601f830112611e6b578081fd5b81356020611e80611e7b83612c83565b612c52565b8281528181019085830183850287018401881015611e9c578586fd5b855b85811015611eba57813584529284019290840190600101611e9e565b5090979650505050505050565b600082601f830112611ed7578081fd5b611ee683833560208501611dec565b9392505050565b600060208284031215611efe578081fd5b611ee682611e44565b60008060408385031215611f19578081fd5b611f2283611e44565b9150611f3060208401611e44565b90509250929050565b600080600060608486031215611f4d578081fd5b611f5684611e44565b9250611f6460208501611e44565b9150604084013590509250925092565b60008060008060808587031215611f89578081fd5b611f9285611e44565b9350611fa060208601611e44565b925060408501359150606085013567ffffffffffffffff811115611fc2578182fd5b8501601f81018713611fd2578182fd5b611fe187823560208401611dec565b91505092959194509250565b600080600080600080600060e0888a031215612007578283fd5b61201088611e44565b965061201e60208901611e44565b95506040880135945060608801359350608088013560ff81168114612041578384fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215612070578182fd5b61207983611e44565b91506020830135801515811461208d578182fd5b809150509250929050565b600080604083850312156120aa578182fd5b6120b383611e44565b946020939093013593505050565b600080604083850312156120d3578182fd5b823567ffffffffffffffff808211156120ea578384fd5b818501915085601f8301126120fd578384fd5b8135602061210d611e7b83612c83565b82815281810190858301838502870184018b1015612129578889fd5b8896505b848710156121525761213e81611e44565b83526001969096019591830191830161212d565b5096505086013592505080821115612168578283fd5b5061217585828601611e5b565b9150509250929050565b600060208284031215612190578081fd5b5035919050565b6000602082840312156121a8578081fd5b8135611ee681612df9565b6000602082840312156121c4578081fd5b8151611ee681612df9565b6000602082840312156121e0578081fd5b813567ffffffffffffffff8111156121f6578182fd5b61148884828501611ec7565b60008060408385031215612214578182fd5b82359150602083013567ffffffffffffffff811115612231578182fd5b61217585828601611ec7565b60008151808452612255816020860160208601612cea565b601f01601f19169290920160200192915050565b600080845461227781612d2d565b6001828116801561228f57600181146122a0576122cc565b60ff198416875282870194506122cc565b8886526020808720875b858110156122c35781548a8201529084019082016122aa565b50505082870194505b5050505083516122e0818360208801612cea565b01949350505050565b61190160f01b81526002810192909252602282015260420190565b6001600160a01b0391909116815260200190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061234b9083018461223d565b9695505050505050565b901515815260200190565b90815260200190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b9485526020850193909352604084019190915260608301526001600160a01b0316608082015260a00190565b93845260ff9290921660208401526040830152606082015260800190565b600060208252611ee6602083018461223d565b6000602080835281845461240d81612d2d565b8084870152604060018084166000811461242e57600181146124425761246d565b60ff1985168984015260608901955061246d565b898852868820885b858110156124655781548b820186015290830190880161244a565b8a0184019650505b509398975050505050505050565b60208082526018908201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604082015260600190565b60208082526014908201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604082015260600190565b60208082526010908201526f26bab9ba1031329037b832b930ba37b960811b604082015260600190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252601c908201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604082015260600190565b60208082526027908201527f4552433732315065726d69743a20617070726f76616c20746f2063757272656e6040820152663a1037bbb732b960c91b606082015260800190565b60208082526024908201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526019908201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604082015260600190565b6020808252601f908201527f4552433732315065726d69743a20696e76616c6964207369676e617475726500604082015260600190565b60208082526022908201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604082015261756560f01b606082015260800190565b6020808252603e908201527f4552433732315065726d69743a20617070726f7665207369676e65722069732060408201527f6e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c0000606082015260800190565b6020808252602c908201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b60208082526038908201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760408201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606082015260800190565b6020808252602a908201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604082015269726f206164647265737360b01b606082015260800190565b60208082526029908201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460408201526832b73a103a37b5b2b760b91b606082015260800190565b60208082526027908201527f676574546f6b656e55524920717565727920666f72206e6f6e6578697374656e6040820152663a103a37b5b2b760c91b606082015260800190565b60208082526022908201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604082015261756560f01b606082015260800190565b6020808252818101527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b6020808252602c908201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252601e908201527f4552433732315065726d69743a206578706972656420646561646c696e650000604082015260600190565b60208082526029908201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960408201526839903737ba1037bbb760b91b606082015260800190565b60208082526027908201527f736574546f6b656e55524920717565727920666f72206e6f6e6578697374656e6040820152663a103a37b5b2b760c91b606082015260800190565b6020808252600e908201526d26bab9ba10313290313ab93732b960911b604082015260600190565b6020808252601c908201527f726f6c6520616c72656164792068617320746865206163636f756e7400000000604082015260600190565b60208082526021908201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656040820152603960f91b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252600e908201526d26bab9ba1031329036b4b73a32b960911b604082015260600190565b60208082526017908201527f4275726e6572206d75737420626520636f6e7472616374000000000000000000604082015260600190565b60208082526030908201527f4552433732314275726e61626c653a2063616c6c6572206973206e6f74206f7760408201526f1b995c881b9bdc88185c1c1c9bdd995960821b606082015260800190565b6020808252601d908201527f726f6c6520646f73656e2774206861766520746865206163636f756e74000000604082015260600190565b600083825260406020830152611488604083018461223d565b604051601f8201601f1916810167ffffffffffffffff81118282101715612c7b57612c7b612de3565b604052919050565b600067ffffffffffffffff821115612c9d57612c9d612de3565b5060209081020190565b60008219821115612cba57612cba612db7565b500190565b600082612cce57612cce612dcd565b500490565b600082821015612ce557612ce5612db7565b500390565b60005b83811015612d05578181015183820152602001612ced565b83811115610f9d5750506000910152565b600081612d2557612d25612db7565b506000190190565b600281046001821680612d4157607f821691505b60208210811415612d6257634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415612d7c57612d7c612db7565b5060010190565b600060ff821660ff811415612d9a57612d9a612db7565b60010192915050565b600082612db257612db2612dcd565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114610aad57600080fdfea264697066735822122034e908cd6ddb0582d7570667294786cdd2e311f0822435b9e27f02e40aa6350c64736f6c6343000801003368747470733a2f2f7674756265726e66742e6865726f6b756170702e636f6d2f6170692f6d657461646174612f

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102485760003560e01c80636ae459bd1161013b578063aa271e1a116100b8578063da1b9e081161007c578063da1b9e08146104cd578063e985e9c5146104e0578063f2fde38b146104f3578063f44637ba14610506578063f9613ab21461051957610248565b8063aa271e1a1461046e578063ac8a584a14610481578063b88d4fde14610494578063c87b56dd146104a7578063d505accf146104ba57610248565b80638da5cb5b116100ff5780638da5cb5b1461042557806395d89b411461042d578063983b2d56146104355780639870d7fe14610448578063a22cb4651461045b57610248565b80636ae459bd146103d15780636d70f7ae146103e457806370a08231146103f75780637ecebe001461040a5780638456cb591461041d57610248565b80633bb3a24d116101c95780634334614a1161018d5780634334614a1461037d5780634f558e791461039057806355f804b3146103a35780635c975abb146103b65780636352211e146103be57610248565b80633bb3a24d146103295780633f4ba83a1461033c57806340c10f191461034457806342842e0e1461035757806342966c681461036a57610248565b8063162094c411610210578063162094c4146102d357806318160ddd146102e657806323b872dd146102fb5780633092afd51461030e5780633644e5151461032157610248565b806301ffc9a71461024d578063028468581461027657806306fdde031461028b578063081812fc146102a0578063095ea7b3146102c0575b600080fd5b61026061025b366004612197565b61052c565b60405161026d9190612355565b60405180910390f35b610289610284366004611eed565b610574565b005b6102936105e4565b60405161026d91906123e7565b6102b36102ae36600461217f565b610677565b60405161026d9190612304565b6102896102ce366004612098565b6106ba565b6102896102e1366004612202565b610752565b6102ee6107f9565b60405161026d9190612360565b610289610309366004611f39565b6107ff565b61028961031c366004611eed565b610837565b6102ee61089e565b61029361033736600461217f565b6108ad565b610289610972565b610289610352366004612098565b610a07565b610289610365366004611f39565b610a4f565b61028961037836600461217f565b610a6a565b61026061038b366004611eed565b610ab0565b61026061039e36600461217f565b610abd565b6102896103b13660046121cf565b610ac8565b610260610b3b565b6102b36103cc36600461217f565b610b4b565b6102896103df3660046120c1565b610b80565b6102606103f2366004611eed565b610c32565b6102ee610405366004611eed565b610c3f565b6102ee610418366004611eed565b610c83565b610289610ca4565b6102b3610d36565b610293610d45565b610289610443366004611eed565b610d54565b610289610456366004611eed565b610dbb565b61028961046936600461205e565b610e22565b61026061047c366004611eed565b610ef0565b61028961048f366004611eed565b610efd565b6102896104a2366004611f74565b610f64565b6102936104b536600461217f565b610fa3565b6102896104c8366004611fed565b610fae565b6102896104db3660046121cf565b61114b565b6102606104ee366004611f07565b6111b4565b610289610501366004611eed565b6111e2565b610289610514366004611eed565b611210565b6102ee61052736600461217f565b6112a5565b60006001600160e01b031982166380ac58cd60e01b148061055d57506001600160e01b03198216635b5e139f60e01b145b8061056c575061056c8261131b565b90505b919050565b61057d33610c32565b6105a25760405162461bcd60e51b8152600401610599906124e0565b60405180910390fd5b6105ad600982611334565b6040516001600160a01b038216907f90eabbc0c667db2a5029ed6bc0f5fe9f356d11684a4ca9fcfaec0e53f12b9c8e90600090a250565b6060600080546105f390612d2d565b80601f016020809104026020016040519081016040528092919081815260200182805461061f90612d2d565b801561066c5780601f106106415761010080835404028352916020019161066c565b820191906000526020600020905b81548152906001019060200180831161064f57829003601f168201915b505050505090505b90565b60006106828261137c565b61069e5760405162461bcd60e51b81526004016105999061294f565b506000908152600460205260409020546001600160a01b031690565b60006106c582610b4b565b9050806001600160a01b0316836001600160a01b031614156106f95760405162461bcd60e51b815260040161059990612ac1565b806001600160a01b031661070b611399565b6001600160a01b031614806107275750610727816104ee611399565b6107435760405162461bcd60e51b8152600401610599906127a1565b61074d838361139d565b505050565b61075b33610c32565b6107775760405162461bcd60e51b8152600401610599906124e0565b6107808261137c565b61079c5760405162461bcd60e51b815260040161059990612a1b565b6000828152600d6020908152604090912082516107bb92840190611d53565b507f0418254f69edc41d3d2b429767526234e99f60018e7e21cda80307bf3ef28cc482826040516107ed929190612c39565b60405180910390a15050565b600e5490565b61081061080a611399565b8261140b565b61082c5760405162461bcd60e51b815260040161059990612b02565b61074d838383611490565b61084033610c32565b61085c5760405162461bcd60e51b8152600401610599906124e0565b610867600882611334565b6040516001600160a01b038216907fe94479a9f7e1952cc78f2d6baab678adc1b772d936c6583def489e524cb6669290600090a250565b60006108a86115bd565b905090565b60606108b88261137c565b6108d45760405162461bcd60e51b815260040161059990612891565b6000828152600d6020526040902080546108ed90612d2d565b80601f016020809104026020016040519081016040528092919081815260200182805461091990612d2d565b80156109665780601f1061093b57610100808354040283529160200191610966565b820191906000526020600020905b81548152906001019060200180831161094957829003601f168201915b50505050509050919050565b61097b33610c32565b6109975760405162461bcd60e51b8152600401610599906124e0565b600654600160a01b900460ff166109c05760405162461bcd60e51b8152600401610599906124b2565b6006805460ff60a01b191690556040517f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa906109fd903390612304565b60405180910390a1565b610a1033610ef0565b610a2c5760405162461bcd60e51b815260040161059990612b53565b600e8054906000610a3c83612d68565b9190505550610a4b8282611680565b5050565b61074d83838360405180602001604052806000815250610f64565b610a7333610ab0565b610a8f5760405162461bcd60e51b815260040161059990612a62565b600e8054906000610a9f83612d16565b9190505550610aad816116af565b50565b600061056c6009836112fc565b600061056c8261137c565b610ad133610c32565b610aed5760405162461bcd60e51b8152600401610599906124e0565b8051610b0090600c906020840190611d53565b507f157d450c8fb1377294d9db75af1de2753efc52d8e5578551d70d2c7d9cd74df981604051610b3091906123e7565b60405180910390a150565b600654600160a01b900460ff1690565b6000818152600260205260408120546001600160a01b03168061056c5760405162461bcd60e51b815260040161059990612848565b610b8933610ef0565b610ba55760405162461bcd60e51b815260040161059990612b53565b8051825114610bb357600080fd5b60005b82518160ff16101561074d57610c20838260ff1681518110610be857634e487b7160e01b600052603260045260246000fd5b6020026020010151838360ff1681518110610c1357634e487b7160e01b600052603260045260246000fd5b6020026020010151610a07565b80610c2a81612d83565b915050610bb6565b600061056c6007836112fc565b60006001600160a01b038216610c675760405162461bcd60e51b8152600401610599906127fe565b506001600160a01b031660009081526003602052604090205490565b6001600160a01b0381166000908152600a6020526040812061056c90611703565b610cad33610c32565b610cc95760405162461bcd60e51b8152600401610599906124e0565b600654600160a01b900460ff1615610cf35760405162461bcd60e51b815260040161059990612777565b6006805460ff60a01b1916600160a01b1790556040517f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258906109fd903390612304565b6006546001600160a01b031690565b6060600180546105f390612d2d565b610d5d33610c32565b610d795760405162461bcd60e51b8152600401610599906124e0565b610d846008826112b0565b6040516001600160a01b038216907f6ae172837ea30b801fbfcdd4108aa1d5bf8ff775444fd70256b44e6bf3dfc3f690600090a250565b610dc433610c32565b610de05760405162461bcd60e51b8152600401610599906124e0565b610deb6007826112b0565b6040516001600160a01b038216907fac6fa858e9350a46cec16539926e0fde25b7629f84b5a72bffaae4df888ae86d90600090a250565b610e2a611399565b6001600160a01b0316826001600160a01b03161415610e5b5760405162461bcd60e51b81526004016105999061261e565b8060056000610e68611399565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155610eac611399565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610ee49190612355565b60405180910390a35050565b600061056c6008836112fc565b610f0633610c32565b610f225760405162461bcd60e51b8152600401610599906124e0565b610f2d600782611334565b6040516001600160a01b038216907f80c0b871b97b595b16a7741c1b06fed0c6f6f558639f18ccbce50724325dc40d90600090a250565b610f75610f6f611399565b8361140b565b610f915760405162461bcd60e51b815260040161059990612b02565b610f9d84848484611707565b50505050565b606061056c8261173a565b6000610fb986610b4b565b9050806001600160a01b0316876001600160a01b03161415610fed5760405162461bcd60e51b815260040161059990612593565b876001600160a01b0316816001600160a01b03161480611012575061101281896111b4565b61102e5760405162461bcd60e51b8152600401610599906126ce565b8442111561104e5760405162461bcd60e51b81526004016105999061299b565b6001600160a01b0388166000908152600a602052604081207f48d39b37a35214940203bbbd4f383519797769b13d936f387d89430afef27688908a908a908a9061109790611703565b8a6040516020016110ad96959493929190612369565b60405160208183030381529060405280519060200120905060006110d0826117b7565b905060006110e0828888886117ca565b90508a6001600160a01b0316816001600160a01b0316146111135760405162461bcd60e51b815260040161059990612655565b6001600160a01b038b166000908152600a60205260409020611134906118c0565b61113e8a8a61139d565b5050505050505050505050565b61115433610c32565b6111705760405162461bcd60e51b8152600401610599906124e0565b805161118390600b906020840190611d53565b507f2405b30cce1d59580c3cc7fbdce2d552bd8e943d5dc4f66a37053027fc7ce880600b604051610b3091906123fa565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6111eb33610c32565b6112075760405162461bcd60e51b8152600401610599906124e0565b610aad816118c9565b61121933610c32565b6112355760405162461bcd60e51b8152600401610599906124e0565b611247816001600160a01b0316611927565b6112635760405162461bcd60e51b815260040161059990612b7b565b61126e6009826112b0565b6040516001600160a01b038216907f86e57fd2b90329052917118de7c3f521f400d439b9650deaa906a25b08b9456090600090a250565b600061056c826117b7565b6112ba82826112fc565b156112d75760405162461bcd60e51b815260040161059990612a8a565b6001600160a01b0316600090815260209190915260409020805460ff19166001179055565b6001600160a01b03166000908152602091909152604090205460ff1690565b6001600160e01b031981166301ffc9a760e01b14919050565b61133e82826112fc565b61135a5760405162461bcd60e51b815260040161059990612c02565b6001600160a01b0316600090815260209190915260409020805460ff19169055565b6000908152600260205260409020546001600160a01b0316151590565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906113d282610b4b565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006114168261137c565b6114325760405162461bcd60e51b81526004016105999061272b565b600061143d83610b4b565b9050806001600160a01b0316846001600160a01b031614806114785750836001600160a01b031661146d84610677565b6001600160a01b0316145b80611488575061148881856111b4565b949350505050565b826001600160a01b03166114a382610b4b565b6001600160a01b0316146114c95760405162461bcd60e51b8152600401610599906129d2565b6001600160a01b0382166114ef5760405162461bcd60e51b8152600401610599906125da565b6114fa83838361074d565b61150560008261139d565b6001600160a01b038316600090815260036020526040812080546001929061152e908490612cd3565b90915550506001600160a01b038216600090815260036020526040812080546001929061155c908490612ca7565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b60007f000000000000000000000000000000000000000000000000000000000000000146141561160e57507f88a643e671e977470b7613a460b50483186b0f2ba1e660905f784979a927720b610674565b6116797f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7ff56451c4bcdaabcf976fde029fc45f81ab32fd5dfc636408fba3922d2e7dc3567fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc661192d565b9050610674565b61168933610ef0565b6116a55760405162461bcd60e51b815260040161059990612b53565b610a4b8282611967565b6116b833610ab0565b6116d45760405162461bcd60e51b815260040161059990612a62565b6116de338261140b565b6116fa5760405162461bcd60e51b815260040161059990612bb2565b610aad81611a46565b5490565b611712848484611490565b61171e84848484611aed565b610f9d5760405162461bcd60e51b81526004016105999061250a565b60606000611747836108ad565b80519091501561178457600c61175c84611c05565b60405160200161176d929190612269565b60405160208183030381529060405291505061056f565b600b61178f84611c05565b6040516020016117a0929190612269565b604051602081830303815290604052915050919050565b600061056c6117c46115bd565b83611d20565b60007f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a082111561180c5760405162461bcd60e51b81526004016105999061268c565b8360ff16601b148061182157508360ff16601c145b61183d5760405162461bcd60e51b8152600401610599906128d8565b60006001868686866040516000815260200160405260405161186294939291906123c9565b6020604051602081039080840390855afa158015611884573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b0381166118b75760405162461bcd60e51b81526004016105999061247b565b95945050505050565b80546001019055565b60006118d3610d36565b600680546001600160a01b0319166001600160a01b0385811691821790925560405192935091908316907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b3b151590565b6000838383463060405160200161194895949392919061239d565b6040516020818303038152906040528051906020012090509392505050565b6001600160a01b03821661198d5760405162461bcd60e51b81526004016105999061291a565b6119968161137c565b156119b35760405162461bcd60e51b81526004016105999061255c565b6119bf6000838361074d565b6001600160a01b03821660009081526003602052604081208054600192906119e8908490612ca7565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000611a5182610b4b565b9050611a5f8160008461074d565b611a6a60008361139d565b6001600160a01b0381166000908152600360205260408120805460019290611a93908490612cd3565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6000611b01846001600160a01b0316611927565b15611bfd57836001600160a01b031663150b7a02611b1d611399565b8786866040518563ffffffff1660e01b8152600401611b3f9493929190612318565b602060405180830381600087803b158015611b5957600080fd5b505af1925050508015611b89575060408051601f3d908101601f19168201909252611b86918101906121b3565b60015b611be3573d808015611bb7576040519150601f19603f3d011682016040523d82523d6000602084013e611bbc565b606091505b508051611bdb5760405162461bcd60e51b81526004016105999061250a565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611488565b506001611488565b606081611c2a57506040805180820190915260018152600360fc1b602082015261056f565b8160005b8115611c545780611c3e81612d68565b9150611c4d9050600a83612cbf565b9150611c2e565b60008167ffffffffffffffff811115611c7d57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611ca7576020820181803683370190505b5090505b841561148857611cbc600183612cd3565b9150611cc9600a86612da3565b611cd4906030612ca7565b60f81b818381518110611cf757634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350611d19600a86612cbf565b9450611cab565b60008282604051602001611d359291906122e9565b60405160208183030381529060405280519060200120905092915050565b828054611d5f90612d2d565b90600052602060002090601f016020900481019282611d815760008555611dc7565b82601f10611d9a57805160ff1916838001178555611dc7565b82800160010185558215611dc7579182015b82811115611dc7578251825591602001919060010190611dac565b50611dd3929150611dd7565b5090565b5b80821115611dd35760008155600101611dd8565b600067ffffffffffffffff831115611e0657611e06612de3565b611e19601f8401601f1916602001612c52565b9050828152838383011115611e2d57600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b038116811461056f57600080fd5b600082601f830112611e6b578081fd5b81356020611e80611e7b83612c83565b612c52565b8281528181019085830183850287018401881015611e9c578586fd5b855b85811015611eba57813584529284019290840190600101611e9e565b5090979650505050505050565b600082601f830112611ed7578081fd5b611ee683833560208501611dec565b9392505050565b600060208284031215611efe578081fd5b611ee682611e44565b60008060408385031215611f19578081fd5b611f2283611e44565b9150611f3060208401611e44565b90509250929050565b600080600060608486031215611f4d578081fd5b611f5684611e44565b9250611f6460208501611e44565b9150604084013590509250925092565b60008060008060808587031215611f89578081fd5b611f9285611e44565b9350611fa060208601611e44565b925060408501359150606085013567ffffffffffffffff811115611fc2578182fd5b8501601f81018713611fd2578182fd5b611fe187823560208401611dec565b91505092959194509250565b600080600080600080600060e0888a031215612007578283fd5b61201088611e44565b965061201e60208901611e44565b95506040880135945060608801359350608088013560ff81168114612041578384fd5b9699959850939692959460a0840135945060c09093013592915050565b60008060408385031215612070578182fd5b61207983611e44565b91506020830135801515811461208d578182fd5b809150509250929050565b600080604083850312156120aa578182fd5b6120b383611e44565b946020939093013593505050565b600080604083850312156120d3578182fd5b823567ffffffffffffffff808211156120ea578384fd5b818501915085601f8301126120fd578384fd5b8135602061210d611e7b83612c83565b82815281810190858301838502870184018b1015612129578889fd5b8896505b848710156121525761213e81611e44565b83526001969096019591830191830161212d565b5096505086013592505080821115612168578283fd5b5061217585828601611e5b565b9150509250929050565b600060208284031215612190578081fd5b5035919050565b6000602082840312156121a8578081fd5b8135611ee681612df9565b6000602082840312156121c4578081fd5b8151611ee681612df9565b6000602082840312156121e0578081fd5b813567ffffffffffffffff8111156121f6578182fd5b61148884828501611ec7565b60008060408385031215612214578182fd5b82359150602083013567ffffffffffffffff811115612231578182fd5b61217585828601611ec7565b60008151808452612255816020860160208601612cea565b601f01601f19169290920160200192915050565b600080845461227781612d2d565b6001828116801561228f57600181146122a0576122cc565b60ff198416875282870194506122cc565b8886526020808720875b858110156122c35781548a8201529084019082016122aa565b50505082870194505b5050505083516122e0818360208801612cea565b01949350505050565b61190160f01b81526002810192909252602282015260420190565b6001600160a01b0391909116815260200190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061234b9083018461223d565b9695505050505050565b901515815260200190565b90815260200190565b9586526001600160a01b0394851660208701529290931660408501526060840152608083019190915260a082015260c00190565b9485526020850193909352604084019190915260608301526001600160a01b0316608082015260a00190565b93845260ff9290921660208401526040830152606082015260800190565b600060208252611ee6602083018461223d565b6000602080835281845461240d81612d2d565b8084870152604060018084166000811461242e57600181146124425761246d565b60ff1985168984015260608901955061246d565b898852868820885b858110156124655781548b820186015290830190880161244a565b8a0184019650505b509398975050505050505050565b60208082526018908201527f45434453413a20696e76616c6964207369676e61747572650000000000000000604082015260600190565b60208082526014908201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b604082015260600190565b60208082526010908201526f26bab9ba1031329037b832b930ba37b960811b604082015260600190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252601c908201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604082015260600190565b60208082526027908201527f4552433732315065726d69743a20617070726f76616c20746f2063757272656e6040820152663a1037bbb732b960c91b606082015260800190565b60208082526024908201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526019908201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604082015260600190565b6020808252601f908201527f4552433732315065726d69743a20696e76616c6964207369676e617475726500604082015260600190565b60208082526022908201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604082015261756560f01b606082015260800190565b6020808252603e908201527f4552433732315065726d69743a20617070726f7665207369676e65722069732060408201527f6e6f74206f776e6572206e6f7220617070726f76656420666f7220616c6c0000606082015260800190565b6020808252602c908201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b60208082526010908201526f14185d5cd8589b194e881c185d5cd95960821b604082015260600190565b60208082526038908201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760408201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606082015260800190565b6020808252602a908201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604082015269726f206164647265737360b01b606082015260800190565b60208082526029908201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460408201526832b73a103a37b5b2b760b91b606082015260800190565b60208082526027908201527f676574546f6b656e55524920717565727920666f72206e6f6e6578697374656e6040820152663a103a37b5b2b760c91b606082015260800190565b60208082526022908201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604082015261756560f01b606082015260800190565b6020808252818101527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b6020808252602c908201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252601e908201527f4552433732315065726d69743a206578706972656420646561646c696e650000604082015260600190565b60208082526029908201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960408201526839903737ba1037bbb760b91b606082015260800190565b60208082526027908201527f736574546f6b656e55524920717565727920666f72206e6f6e6578697374656e6040820152663a103a37b5b2b760c91b606082015260800190565b6020808252600e908201526d26bab9ba10313290313ab93732b960911b604082015260600190565b6020808252601c908201527f726f6c6520616c72656164792068617320746865206163636f756e7400000000604082015260600190565b60208082526021908201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656040820152603960f91b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252600e908201526d26bab9ba1031329036b4b73a32b960911b604082015260600190565b60208082526017908201527f4275726e6572206d75737420626520636f6e7472616374000000000000000000604082015260600190565b60208082526030908201527f4552433732314275726e61626c653a2063616c6c6572206973206e6f74206f7760408201526f1b995c881b9bdc88185c1c1c9bdd995960821b606082015260800190565b6020808252601d908201527f726f6c6520646f73656e2774206861766520746865206163636f756e74000000604082015260600190565b600083825260406020830152611488604083018461223d565b604051601f8201601f1916810167ffffffffffffffff81118282101715612c7b57612c7b612de3565b604052919050565b600067ffffffffffffffff821115612c9d57612c9d612de3565b5060209081020190565b60008219821115612cba57612cba612db7565b500190565b600082612cce57612cce612dcd565b500490565b600082821015612ce557612ce5612db7565b500390565b60005b83811015612d05578181015183820152602001612ced565b83811115610f9d5750506000910152565b600081612d2557612d25612db7565b506000190190565b600281046001821680612d4157607f821691505b60208210811415612d6257634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415612d7c57612d7c612db7565b5060010190565b600060ff821660ff811415612d9a57612d9a612db7565b60010192915050565b600082612db257612db2612dcd565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114610aad57600080fdfea264697066735822122034e908cd6ddb0582d7570667294786cdd2e311f0822435b9e27f02e40aa6350c64736f6c63430008010033

Deployed Bytecode Sourcemap

55048:1093:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20741:292;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;38883:141;;;;;;:::i;:::-;;:::i;:::-;;21673:100;;;:::i;:::-;;;;;;;:::i;23140:221::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;22670:404::-;;;;;;:::i;:::-;;:::i;54209:264::-;;;;;;:::i;:::-;;:::i;55886:89::-;;;:::i;:::-;;;;;;;:::i;24030:305::-;;;;;;:::i;:::-;;:::i;37666:150::-;;;;;;:::i;:::-;;:::i;52718:115::-;;;:::i;53965:200::-;;;;;;:::i;:::-;;:::i;36427:124::-;;;:::i;55342:137::-;;;;;;:::i;:::-;;:::i;24406:151::-;;;;;;:::i;:::-;;:::i;55755:123::-;;;;;;:::i;:::-;;:::i;38559:108::-;;;;;;:::i;:::-;;:::i;37828:117::-;;;;;;:::i;:::-;;:::i;53815:142::-;;;;;;:::i;:::-;;:::i;36211:78::-;;;:::i;21367:239::-;;;;;;:::i;:::-;;:::i;55487:260::-;;;;;;:::i;:::-;;:::i;35789:112::-;;;;;;:::i;:::-;;:::i;21097:208::-;;;;;;:::i;:::-;;:::i;52467:120::-;;;;;;:::i;:::-;;:::i;36297:122::-;;;:::i;34383:88::-;;;:::i;21842:104::-;;;:::i;37516:142::-;;;;;;:::i;:::-;;:::i;35909:139::-;;;;;;:::i;:::-;;:::i;23433:295::-;;;;;;:::i;:::-;;:::i;37391:117::-;;;;;;:::i;:::-;;:::i;36056:147::-;;;;;;:::i;:::-;;:::i;24628:285::-;;;;;;:::i;:::-;;:::i;55983:153::-;;;;;;:::i;:::-;;:::i;51274:1126::-;;;;;;:::i;:::-;;:::i;53646:161::-;;;;;;:::i;:::-;;:::i;23799:164::-;;;;;;:::i;:::-;;:::i;35624:157::-;;;;;;:::i;:::-;;:::i;38675:200::-;;;;;;:::i;:::-;;:::i;52841:123::-;;;;;;:::i;:::-;;:::i;20741:292::-;20843:4;-1:-1:-1;;;;;;20867:40:0;;-1:-1:-1;;;20867:40:0;;:105;;-1:-1:-1;;;;;;;20924:48:0;;-1:-1:-1;;;20924:48:0;20867:105;:158;;;;20989:36;21013:11;20989:23;:36::i;:::-;20860:165;;20741:292;;;;:::o;38883:141::-;35351:22;35362:10;35351;:22::i;:::-;35343:51;;;;-1:-1:-1;;;35343:51:0;;;;;;;:::i;:::-;;;;;;;;;38955:23:::1;:7;38970::::0;38955:14:::1;:23::i;:::-;38994:22;::::0;-1:-1:-1;;;;;38994:22:0;::::1;::::0;::::1;::::0;;;::::1;38883:141:::0;:::o;21673:100::-;21727:13;21760:5;21753:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21673:100;;:::o;23140:221::-;23216:7;23244:16;23252:7;23244;:16::i;:::-;23236:73;;;;-1:-1:-1;;;23236:73:0;;;;;;;:::i;:::-;-1:-1:-1;23329:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;23329:24:0;;23140:221::o;22670:404::-;22751:13;22767:23;22782:7;22767:14;:23::i;:::-;22751:39;;22815:5;-1:-1:-1;;;;;22809:11:0;:2;-1:-1:-1;;;;;22809:11:0;;;22801:57;;;;-1:-1:-1;;;22801:57:0;;;;;;;:::i;:::-;22895:5;-1:-1:-1;;;;;22879:21:0;:12;:10;:12::i;:::-;-1:-1:-1;;;;;22879:21:0;;:69;;;;22904:44;22928:5;22935:12;:10;:12::i;22904:44::-;22871:161;;;;-1:-1:-1;;;22871:161:0;;;;;;;:::i;:::-;23045:21;23054:2;23058:7;23045:8;:21::i;:::-;22670:404;;;:::o;54209:264::-;35351:22;35362:10;35351;:22::i;:::-;35343:51;;;;-1:-1:-1;;;35343:51:0;;;;;;;:::i;:::-;54313:16:::1;54321:7;54313;:16::i;:::-;54305:68;;;;-1:-1:-1::0;;;54305:68:0::1;;;;;;;:::i;:::-;54384:19;::::0;;;:10:::1;:19;::::0;;;;;;;:31;;::::1;::::0;;::::1;::::0;::::1;:::i;:::-;;54431:34;54446:7;54455:9;54431:34;;;;;;;:::i;:::-;;;;;;;;54209:264:::0;;:::o;55886:89::-;55957:10;;55886:89;:::o;24030:305::-;24191:41;24210:12;:10;:12::i;:::-;24224:7;24191:18;:41::i;:::-;24183:103;;;;-1:-1:-1;;;24183:103:0;;;;;;;:::i;:::-;24299:28;24309:4;24315:2;24319:7;24299:9;:28::i;37666:150::-;35351:22;35362:10;35351;:22::i;:::-;35343:51;;;;-1:-1:-1;;;35343:51:0;;;;;;;:::i;:::-;37747:23:::1;:7;37762::::0;37747:14:::1;:23::i;:::-;37786:22;::::0;-1:-1:-1;;;;;37786:22:0;::::1;::::0;::::1;::::0;;;::::1;37666:150:::0;:::o;52718:115::-;52778:7;52805:20;:18;:20::i;:::-;52798:27;;52718:115;:::o;53965:200::-;54024:13;54058:16;54066:7;54058;:16::i;:::-;54050:68;;;;-1:-1:-1;;;54050:68:0;;;;;;;:::i;:::-;54138:19;;;;:10;:19;;;;;54131:26;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53965:200;;;:::o;36427:124::-;35351:22;35362:10;35351;:22::i;:::-;35343:51;;;;-1:-1:-1;;;35343:51:0;;;;;;;:::i;:::-;35564:7:::1;::::0;-1:-1:-1;;;35564:7:0;::::1;;;35556:40;;;;-1:-1:-1::0;;;35556:40:0::1;;;;;;;:::i;:::-;36492:7:::2;:15:::0;;-1:-1:-1;;;;36492:15:0::2;::::0;;36523:20:::2;::::0;::::2;::::0;::::2;::::0;36532:10:::2;::::0;36523:20:::2;:::i;:::-;;;;;;;;36427:124::o:0;55342:137::-;37324:20;37333:10;37324:8;:20::i;:::-;37316:47;;;;-1:-1:-1;;;37316:47:0;;;;;;;:::i;:::-;55425:10:::1;:12:::0;;;:10:::1;:12;::::0;::::1;:::i;:::-;;;;;;55448:23;55459:2;55463:7;55448:10;:23::i;:::-;55342:137:::0;;:::o;24406:151::-;24510:39;24527:4;24533:2;24537:7;24510:39;;;;;;;;;;;;:16;:39::i;55755:123::-;38365:20;38374:10;38365:8;:20::i;:::-;38357:47;;;;-1:-1:-1;;;38357:47:0;;;;;;;:::i;:::-;55827:10:::1;:12:::0;;;:10:::1;:12;::::0;::::1;:::i;:::-;;;;;;55850:20;55861:8;55850:10;:20::i;:::-;55755:123:::0;:::o;38559:108::-;38615:4;38639:20;:7;38651;38639:11;:20::i;37828:117::-;37891:4;37915:22;37929:7;37915:13;:22::i;53815:142::-;35351:22;35362:10;35351;:22::i;:::-;35343:51;;;;-1:-1:-1;;;35343:51:0;;;;;;;:::i;:::-;53892:18;;::::1;::::0;:7:::1;::::0;:18:::1;::::0;::::1;::::0;::::1;:::i;:::-;;53926:23;53940:8;53926:23;;;;;;:::i;:::-;;;;;;;;53815:142:::0;:::o;36211:78::-;36274:7;;-1:-1:-1;;;36274:7:0;;;;;36211:78::o;21367:239::-;21439:7;21475:16;;;:7;:16;;;;;;-1:-1:-1;;;;;21475:16:0;21510:19;21502:73;;;;-1:-1:-1;;;21502:73:0;;;;;;;:::i;55487:260::-;37324:20;37333:10;37324:8;:20::i;:::-;37316:47;;;;-1:-1:-1;;;37316:47:0;;;;;;;:::i;:::-;55608:9:::1;:16;55593:4;:11;:31;55585:40;;;::::0;::::1;;55636:7;55654:86;55670:4;:11;55666:1;:15;;;55654:86;;;55701:27;55706:4;55711:1;55706:7;;;;;;;;-1:-1:-1::0;;;55706:7:0::1;;;;;;;;;;;;;;;55715:9;55725:1;55715:12;;;;;;;;-1:-1:-1::0;;;55715:12:0::1;;;;;;;;;;;;;;;55701:4;:27::i;:::-;55683:3:::0;::::1;::::0;::::1;:::i;:::-;;;;55654:86;;35789:112:::0;35847:4;35871:22;:9;35885:7;35871:13;:22::i;21097:208::-;21169:7;-1:-1:-1;;;;;21197:19:0;;21189:74;;;;-1:-1:-1;;;21189:74:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;;21281:16:0;;;;;:9;:16;;;;;;;21097:208::o;52467:120::-;-1:-1:-1;;;;;52555:14:0;;52528:7;52555:14;;;:7;:14;;;;;:24;;:22;:24::i;36297:122::-;35351:22;35362:10;35351;:22::i;:::-;35343:51;;;;-1:-1:-1;;;35343:51:0;;;;;;;:::i;:::-;35467:7:::1;::::0;-1:-1:-1;;;35467:7:0;::::1;;;35466:8;35458:37;;;;-1:-1:-1::0;;;35458:37:0::1;;;;;;;:::i;:::-;36363:7:::2;:14:::0;;-1:-1:-1;;;;36363:14:0::2;-1:-1:-1::0;;;36363:14:0::2;::::0;;36393:18:::2;::::0;::::2;::::0;::::2;::::0;36400:10:::2;::::0;36393:18:::2;:::i;34383:88::-:0;34457:6;;-1:-1:-1;;;;;34457:6:0;34383:88;:::o;21842:104::-;21898:13;21931:7;21924:14;;;;;:::i;37516:142::-;35351:22;35362:10;35351;:22::i;:::-;35343:51;;;;-1:-1:-1;;;35343:51:0;;;;;;;:::i;:::-;37594:20:::1;:7;37606::::0;37594:11:::1;:20::i;:::-;37630;::::0;-1:-1:-1;;;;;37630:20:0;::::1;::::0;::::1;::::0;;;::::1;37516:142:::0;:::o;35909:139::-;35351:22;35362:10;35351;:22::i;:::-;35343:51;;;;-1:-1:-1;;;35343:51:0;;;;;;;:::i;:::-;35980:22:::1;:9;35994:7:::0;35980:13:::1;:22::i;:::-;36018;::::0;-1:-1:-1;;;;;36018:22:0;::::1;::::0;::::1;::::0;;;::::1;35909:139:::0;:::o;23433:295::-;23548:12;:10;:12::i;:::-;-1:-1:-1;;;;;23536:24:0;:8;-1:-1:-1;;;;;23536:24:0;;;23528:62;;;;-1:-1:-1;;;23528:62:0;;;;;;;:::i;:::-;23648:8;23603:18;:32;23622:12;:10;:12::i;:::-;-1:-1:-1;;;;;23603:32:0;;;;;;;;;;;;;;;;;-1:-1:-1;23603:32:0;;;:42;;;;;;;;;;;;:53;;-1:-1:-1;;23603:53:0;;;;;;;;;;;23687:12;:10;:12::i;:::-;-1:-1:-1;;;;;23672:48:0;;23711:8;23672:48;;;;;;:::i;:::-;;;;;;;;23433:295;;:::o;37391:117::-;37456:4;37480:20;:7;37492;37480:11;:20::i;36056:147::-;35351:22;35362:10;35351;:22::i;:::-;35343:51;;;;-1:-1:-1;;;35343:51:0;;;;;;;:::i;:::-;36130:25:::1;:9;36147:7:::0;36130:16:::1;:25::i;:::-;36171:24;::::0;-1:-1:-1;;;;;36171:24:0;::::1;::::0;::::1;::::0;;;::::1;36056:147:::0;:::o;24628:285::-;24760:41;24779:12;:10;:12::i;:::-;24793:7;24760:18;:41::i;:::-;24752:103;;;;-1:-1:-1;;;24752:103:0;;;;;;;:::i;:::-;24866:39;24880:4;24886:2;24890:7;24899:5;24866:13;:39::i;:::-;24628:285;;;;:::o;55983:153::-;56072:13;56105:23;56120:7;56105:14;:23::i;51274:1126::-;51425:18;51446:16;51454:7;51446;:16::i;:::-;51425:37;;51492:10;-1:-1:-1;;;;;51481:21:0;:7;-1:-1:-1;;;;;51481:21:0;;;51473:73;;;;-1:-1:-1;;;51473:73:0;;;;;;;:::i;:::-;51579:5;-1:-1:-1;;;;;51565:19:0;:10;-1:-1:-1;;;;;51565:19:0;;:58;;;;51588:35;51605:10;51617:5;51588:16;:35::i;:::-;51557:156;;;;-1:-1:-1;;;51557:156:0;;;;;;;:::i;:::-;51808:8;51789:15;:27;;51781:70;;;;-1:-1:-1;;;51781:70:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;52049:14:0;;51864:18;52049:14;;;:7;:14;;;;;51938:16;;51973:5;;51997:7;;52023;;52049:24;;:22;:24::i;:::-;52092:8;51909:206;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;51885:241;;;;;;51864:262;;52139:12;52154:28;52171:10;52154:16;:28::i;:::-;52139:43;;52195:14;52212:28;52226:4;52232:1;52235;52238;52212:13;:28::i;:::-;52195:45;;52269:5;-1:-1:-1;;;;;52259:15:0;:6;-1:-1:-1;;;;;52259:15:0;;52251:59;;;;-1:-1:-1;;;52251:59:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;52323:14:0;;;;;;:7;:14;;;;;:26;;:24;:26::i;:::-;52360:32;52375:7;52384;52360:14;:32::i;:::-;51274:1126;;;;;;;;;;;:::o;53646:161::-;35351:22;35362:10;35351;:22::i;:::-;35343:51;;;;-1:-1:-1;;;35343:51:0;;;;;;;:::i;:::-;53729:25;;::::1;::::0;:11:::1;::::0;:25:::1;::::0;::::1;::::0;::::1;:::i;:::-;;53770:29;53787:11;53770:29;;;;;;:::i;23799:164::-:0;-1:-1:-1;;;;;23920:25:0;;;23896:4;23920:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;23799:164::o;35624:157::-;35351:22;35362:10;35351;:22::i;:::-;35343:51;;;;-1:-1:-1;;;35343:51:0;;;;;;;:::i;:::-;35744:29:::1;35763:9;35744:18;:29::i;38675:200::-:0;35351:22;35362:10;35351;:22::i;:::-;35343:51;;;;-1:-1:-1;;;35343:51:0;;;;;;;:::i;:::-;38752:20:::1;:7;-1:-1:-1::0;;;;;38752:18:0::1;;:20::i;:::-;38744:56;;;;-1:-1:-1::0;;;38744:56:0::1;;;;;;;:::i;:::-;38811:20;:7;38823::::0;38811:11:::1;:20::i;:::-;38847;::::0;-1:-1:-1;;;;;38847:20:0;::::1;::::0;::::1;::::0;;;::::1;38675:200:::0;:::o;52841:123::-;52901:7;52928:28;52945:10;52928:16;:28::i;32719:175::-;32797:18;32801:4;32807:7;32797:3;:18::i;:::-;32796:19;32788:60;;;;-1:-1:-1;;;32788:60:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;32859:20:0;:11;:20;;;;;;;;;;;:27;;-1:-1:-1;;32859:27:0;32882:4;32859:27;;;32719:175::o;33089:156::-;-1:-1:-1;;;;;33217:20:0;33188:4;33217:20;;;;;;;;;;;;;;;33089:156::o;19265:157::-;-1:-1:-1;;;;;;19374:40:0;;-1:-1:-1;;;19374:40:0;19265:157;;;:::o;32902:179::-;32982:18;32986:4;32992:7;32982:3;:18::i;:::-;32974:60;;;;-1:-1:-1;;;32974:60:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;33045:20:0;33068:5;33045:20;;;;;;;;;;;:28;;-1:-1:-1;;33045:28:0;;;32902:179::o;26380:127::-;26445:4;26469:16;;;:7;:16;;;;;;-1:-1:-1;;;;;26469:16:0;:30;;;26380:127::o;16029:98::-;16109:10;16029:98;:::o;30265:174::-;30340:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;30340:29:0;-1:-1:-1;;;;;30340:29:0;;;;;;;;:24;;30394:23;30340:24;30394:14;:23::i;:::-;-1:-1:-1;;;;;30385:46:0;;;;;;;;;;;30265:174;;:::o;26674:355::-;26767:4;26792:16;26800:7;26792;:16::i;:::-;26784:73;;;;-1:-1:-1;;;26784:73:0;;;;;;;:::i;:::-;26868:13;26884:23;26899:7;26884:14;:23::i;:::-;26868:39;;26937:5;-1:-1:-1;;;;;26926:16:0;:7;-1:-1:-1;;;;;26926:16:0;;:51;;;;26970:7;-1:-1:-1;;;;;26946:31:0;:20;26958:7;26946:11;:20::i;:::-;-1:-1:-1;;;;;26946:31:0;;26926:51;:94;;;;26981:39;27005:5;27012:7;26981:23;:39::i;:::-;26918:103;26674:355;-1:-1:-1;;;;26674:355:0:o;29603:544::-;29728:4;-1:-1:-1;;;;;29701:31:0;:23;29716:7;29701:14;:23::i;:::-;-1:-1:-1;;;;;29701:31:0;;29693:85;;;;-1:-1:-1;;;29693:85:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;29797:16:0;;29789:65;;;;-1:-1:-1;;;29789:65:0;;;;;;;:::i;:::-;29867:39;29888:4;29894:2;29898:7;29867:20;:39::i;:::-;29971:29;29988:1;29992:7;29971:8;:29::i;:::-;-1:-1:-1;;;;;30013:15:0;;;;;;:9;:15;;;;;:20;;30032:1;;30013:15;:20;;30032:1;;30013:20;:::i;:::-;;;;-1:-1:-1;;;;;;;30044:13:0;;;;;;:9;:13;;;;;:18;;30061:1;;30044:13;:18;;30061:1;;30044:18;:::i;:::-;;;;-1:-1:-1;;30073:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;30073:21:0;-1:-1:-1;;;;;30073:21:0;;;;;;;;;30112:27;;30073:16;;30112:27;;;;;;;29603:544;;;:::o;48221:281::-;48274:7;48315:16;48298:13;:33;48294:201;;;-1:-1:-1;48355:24:0;48348:31;;48294:201;48419:64;48441:10;48453:12;48467:15;48419:21;:64::i;:::-;48412:71;;;;37953:123;37324:20;37333:10;37324:8;:20::i;:::-;37316:47;;;;-1:-1:-1;;;37316:47:0;;;;;;;:::i;:::-;38044:24:::1;38056:2;38060:7;38044:11;:24::i;39032:201::-:0;38365:20;38374:10;38365:8;:20::i;:::-;38357:47;;;;-1:-1:-1;;;38357:47:0;;;;;;;:::i;:::-;39108:39:::1;39127:10;39139:7;39108:18;:39::i;:::-;39100:100;;;;-1:-1:-1::0;;;39100:100:0::1;;;;;;;:::i;:::-;39211:14;39217:7;39211:5;:14::i;44662:114::-:0;44754:14;;44662:114::o;25795:272::-;25909:28;25919:4;25925:2;25929:7;25909:9;:28::i;:::-;25956:48;25979:4;25985:2;25989:7;25998:5;25956:22;:48::i;:::-;25948:111;;;;-1:-1:-1;;;25948:111:0;;;;;;;:::i;54481:487::-;54579:13;54605:23;54631:20;54643:7;54631:11;:20::i;:::-;54710:23;;54605:46;;-1:-1:-1;54710:27:0;54706:120;;54785:7;54794:18;:7;:16;:18::i;:::-;54768:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;54754:60;;;;;54706:120;54927:11;54940:18;:7;:16;:18::i;:::-;54910:49;;;;;;;;;:::i;:::-;;;;;;;;;;;;;54896:64;;;54481:487;;;:::o;49489:167::-;49566:7;49593:55;49615:20;:18;:20::i;:::-;49637:10;49593:21;:55::i;41277:1432::-;41362:7;42287:66;42273:80;;;42265:127;;;;-1:-1:-1;;;42265:127:0;;;;;;;:::i;:::-;42411:1;:7;;42416:2;42411:7;:18;;;;42422:1;:7;;42427:2;42422:7;42411:18;42403:65;;;;-1:-1:-1;;;42403:65:0;;;;;;;:::i;:::-;42566:14;42583:24;42593:4;42599:1;42602;42605;42583:24;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;42583:24:0;;-1:-1:-1;;42583:24:0;;;-1:-1:-1;;;;;;;42626:20:0;;42618:57;;;;-1:-1:-1;;;42618:57:0;;;;;;;:::i;:::-;42695:6;41277:1432;-1:-1:-1;;;;;41277:1432:0:o;44784:127::-;44873:19;;44891:1;44873:19;;;44784:127::o;34617:190::-;34684:21;34708:7;:5;:7::i;:::-;34719:6;:18;;-1:-1:-1;;;;;;34719:18:0;-1:-1:-1;;;;;34719:18:0;;;;;;;;;34753:46;;34684:31;;-1:-1:-1;34719:18:0;34753:46;;;;;;-1:-1:-1;;34753:46:0;34617:190;;:::o;8132:422::-;8499:20;8538:8;;;8132:422::o;48510:337::-;48612:7;48692:8;48719:4;48742:7;48768:13;48808:4;48663:165;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;48639:200;;;;;;48632:207;;48510:337;;;;;:::o;28295:382::-;-1:-1:-1;;;;;28375:16:0;;28367:61;;;;-1:-1:-1;;;28367:61:0;;;;;;;:::i;:::-;28448:16;28456:7;28448;:16::i;:::-;28447:17;28439:58;;;;-1:-1:-1;;;28439:58:0;;;;;;;:::i;:::-;28510:45;28539:1;28543:2;28547:7;28510:20;:45::i;:::-;-1:-1:-1;;;;;28568:13:0;;;;;;:9;:13;;;;;:18;;28585:1;;28568:13;:18;;28585:1;;28568:18;:::i;:::-;;;;-1:-1:-1;;28597:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;28597:21:0;-1:-1:-1;;;;;28597:21:0;;;;;;;;28636:33;;28597:16;;;28636:33;;28597:16;;28636:33;28295:382;;:::o;28906:360::-;28966:13;28982:23;28997:7;28982:14;:23::i;:::-;28966:39;;29018:48;29039:5;29054:1;29058:7;29018:20;:48::i;:::-;29107:29;29124:1;29128:7;29107:8;:29::i;:::-;-1:-1:-1;;;;;29149:16:0;;;;;;:9;:16;;;;;:21;;29169:1;;29149:16;:21;;29169:1;;29149:21;:::i;:::-;;;;-1:-1:-1;;29188:16:0;;;;:7;:16;;;;;;29181:23;;-1:-1:-1;;;;;;29181:23:0;;;29222:36;29196:7;;29188:16;-1:-1:-1;;;;;29222:36:0;;;;;29188:16;;29222:36;28906:360;;:::o;31004:843::-;31125:4;31151:15;:2;-1:-1:-1;;;;;31151:13:0;;:15::i;:::-;31147:693;;;31203:2;-1:-1:-1;;;;;31187:36:0;;31224:12;:10;:12::i;:::-;31238:4;31244:7;31253:5;31187:72;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;31187:72:0;;;;;;;;-1:-1:-1;;31187:72:0;;;;;;;;;;;;:::i;:::-;;;31183:602;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;31433:13:0;;31429:341;;31476:60;;-1:-1:-1;;;31476:60:0;;;;;;;:::i;31429:341::-;31720:6;31714:13;31705:6;31701:2;31697:15;31690:38;31183:602;-1:-1:-1;;;;;;31310:55:0;-1:-1:-1;;;31310:55:0;;-1:-1:-1;31303:62:0;;31147:693;-1:-1:-1;31824:4:0;31817:11;;16698:723;16754:13;16975:10;16971:53;;-1:-1:-1;17002:10:0;;;;;;;;;;;;-1:-1:-1;;;17002:10:0;;;;;;16971:53;17049:5;17034:12;17090:78;17097:9;;17090:78;;17123:8;;;;:::i;:::-;;-1:-1:-1;17146:10:0;;-1:-1:-1;17154:2:0;17146:10;;:::i;:::-;;;17090:78;;;17178:19;17210:6;17200:17;;;;;;-1:-1:-1;;;17200:17:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;17200:17:0;;17178:39;;17228:154;17235:10;;17228:154;;17262:11;17272:1;17262:11;;:::i;:::-;;-1:-1:-1;17331:10:0;17339:2;17331:5;:10;:::i;:::-;17318:24;;:2;:24;:::i;:::-;17305:39;;17288:6;17295;17288:14;;;;;;-1:-1:-1;;;17288:14:0;;;;;;;;;;;;:56;-1:-1:-1;;;;;17288:56:0;;;;;;;;-1:-1:-1;17359:11:0;17368:2;17359:11;;:::i;:::-;;;17228:154;;43628:196;43721:7;43787:15;43804:10;43758:57;;;;;;;;;:::i;:::-;;;;;;;;;;;;;43748:68;;;;;;43741:75;;43628:196;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:408:1;;114:18;106:6;103:30;100:2;;;136:18;;:::i;:::-;174:57;219:2;198:15;;-1:-1:-1;;194:29:1;225:4;190:40;174:57;:::i;:::-;165:66;;254:6;247:5;240:21;294:3;285:6;280:3;276:16;273:25;270:2;;;311:1;308;301:12;270:2;360:6;355:3;348:4;341:5;337:16;324:43;414:1;407:4;398:6;391:5;387:18;383:29;376:40;90:332;;;;;:::o;427:175::-;497:20;;-1:-1:-1;;;;;546:31:1;;536:42;;526:2;;592:1;589;582:12;607:706;;720:3;713:4;705:6;701:17;697:27;687:2;;742:5;735;728:20;687:2;782:6;769:20;808:4;832:66;848:49;894:2;848:49;:::i;:::-;832:66;:::i;:::-;932:15;;;963:12;;;;995:15;;;1041:11;;;1029:24;;1025:33;;1022:42;-1:-1:-1;1019:2:1;;;1081:5;1074;1067:20;1019:2;1107:5;1121:163;1135:2;1132:1;1129:9;1121:163;;;1192:17;;1180:30;;1230:12;;;;1262;;;;1153:1;1146:9;1121:163;;;-1:-1:-1;1302:5:1;;677:636;-1:-1:-1;;;;;;;677:636:1:o;1318:233::-;;1416:3;1409:4;1401:6;1397:17;1393:27;1383:2;;1438:5;1431;1424:20;1383:2;1464:81;1541:3;1532:6;1519:20;1512:4;1504:6;1500:17;1464:81;:::i;:::-;1455:90;1373:178;-1:-1:-1;;;1373:178:1:o;1556:198::-;;1668:2;1656:9;1647:7;1643:23;1639:32;1636:2;;;1689:6;1681;1674:22;1636:2;1717:31;1738:9;1717:31;:::i;1759:274::-;;;1888:2;1876:9;1867:7;1863:23;1859:32;1856:2;;;1909:6;1901;1894:22;1856:2;1937:31;1958:9;1937:31;:::i;:::-;1927:41;;1987:40;2023:2;2012:9;2008:18;1987:40;:::i;:::-;1977:50;;1846:187;;;;;:::o;2038:342::-;;;;2184:2;2172:9;2163:7;2159:23;2155:32;2152:2;;;2205:6;2197;2190:22;2152:2;2233:31;2254:9;2233:31;:::i;:::-;2223:41;;2283:40;2319:2;2308:9;2304:18;2283:40;:::i;:::-;2273:50;;2370:2;2359:9;2355:18;2342:32;2332:42;;2142:238;;;;;:::o;2385:702::-;;;;;2557:3;2545:9;2536:7;2532:23;2528:33;2525:2;;;2579:6;2571;2564:22;2525:2;2607:31;2628:9;2607:31;:::i;:::-;2597:41;;2657:40;2693:2;2682:9;2678:18;2657:40;:::i;:::-;2647:50;;2744:2;2733:9;2729:18;2716:32;2706:42;;2799:2;2788:9;2784:18;2771:32;2826:18;2818:6;2815:30;2812:2;;;2863:6;2855;2848:22;2812:2;2891:22;;2944:4;2936:13;;2932:27;-1:-1:-1;2922:2:1;;2978:6;2970;2963:22;2922:2;3006:75;3073:7;3068:2;3055:16;3050:2;3046;3042:11;3006:75;:::i;:::-;2996:85;;;2515:572;;;;;;;:::o;3092:717::-;;;;;;;;3304:3;3292:9;3283:7;3279:23;3275:33;3272:2;;;3326:6;3318;3311:22;3272:2;3354:31;3375:9;3354:31;:::i;:::-;3344:41;;3404:40;3440:2;3429:9;3425:18;3404:40;:::i;:::-;3394:50;;3491:2;3480:9;3476:18;3463:32;3453:42;;3542:2;3531:9;3527:18;3514:32;3504:42;;3596:3;3585:9;3581:19;3568:33;3641:4;3634:5;3630:16;3623:5;3620:27;3610:2;;3666:6;3658;3651:22;3610:2;3262:547;;;;-1:-1:-1;3262:547:1;;;;3694:5;3746:3;3731:19;;3718:33;;-1:-1:-1;3798:3:1;3783:19;;;3770:33;;3262:547;-1:-1:-1;;3262:547:1:o;3814:369::-;;;3940:2;3928:9;3919:7;3915:23;3911:32;3908:2;;;3961:6;3953;3946:22;3908:2;3989:31;4010:9;3989:31;:::i;:::-;3979:41;;4070:2;4059:9;4055:18;4042:32;4117:5;4110:13;4103:21;4096:5;4093:32;4083:2;;4144:6;4136;4129:22;4083:2;4172:5;4162:15;;;3898:285;;;;;:::o;4188:266::-;;;4317:2;4305:9;4296:7;4292:23;4288:32;4285:2;;;4338:6;4330;4323:22;4285:2;4366:31;4387:9;4366:31;:::i;:::-;4356:41;4444:2;4429:18;;;;4416:32;;-1:-1:-1;;;4275:179:1:o;4459:1227::-;;;4638:2;4626:9;4617:7;4613:23;4609:32;4606:2;;;4659:6;4651;4644:22;4606:2;4704:9;4691:23;4733:18;4774:2;4766:6;4763:14;4760:2;;;4795:6;4787;4780:22;4760:2;4838:6;4827:9;4823:22;4813:32;;4883:7;4876:4;4872:2;4868:13;4864:27;4854:2;;4910:6;4902;4895:22;4854:2;4951;4938:16;4973:4;4997:66;5013:49;5059:2;5013:49;:::i;4997:66::-;5097:15;;;5128:12;;;;5160:11;;;5198;;;5190:20;;5186:29;;5183:42;-1:-1:-1;5180:2:1;;;5243:6;5235;5228:22;5180:2;5270:6;5261:15;;5285:171;5299:2;5296:1;5293:9;5285:171;;;5356:25;5377:3;5356:25;:::i;:::-;5344:38;;5317:1;5310:9;;;;;5402:12;;;;5434;;5285:171;;;-1:-1:-1;5475:5:1;-1:-1:-1;;5518:18:1;;5505:32;;-1:-1:-1;;5549:16:1;;;5546:2;;;5583:6;5575;5568:22;5546:2;;5611:69;5672:7;5661:8;5650:9;5646:24;5611:69;:::i;:::-;5601:79;;;4596:1090;;;;;:::o;5691:190::-;;5803:2;5791:9;5782:7;5778:23;5774:32;5771:2;;;5824:6;5816;5809:22;5771:2;-1:-1:-1;5852:23:1;;5761:120;-1:-1:-1;5761:120:1:o;5886:257::-;;5997:2;5985:9;5976:7;5972:23;5968:32;5965:2;;;6018:6;6010;6003:22;5965:2;6062:9;6049:23;6081:32;6107:5;6081:32;:::i;6148:261::-;;6270:2;6258:9;6249:7;6245:23;6241:32;6238:2;;;6291:6;6283;6276:22;6238:2;6328:9;6322:16;6347:32;6373:5;6347:32;:::i;6414:344::-;;6536:2;6524:9;6515:7;6511:23;6507:32;6504:2;;;6557:6;6549;6542:22;6504:2;6602:9;6589:23;6635:18;6627:6;6624:30;6621:2;;;6672:6;6664;6657:22;6621:2;6700:52;6744:7;6735:6;6724:9;6720:22;6700:52;:::i;6958:412::-;;;7097:2;7085:9;7076:7;7072:23;7068:32;7065:2;;;7118:6;7110;7103:22;7065:2;7159:9;7146:23;7136:33;;7220:2;7209:9;7205:18;7192:32;7247:18;7239:6;7236:30;7233:2;;;7284:6;7276;7269:22;7233:2;7312:52;7356:7;7347:6;7336:9;7332:22;7312:52;:::i;7375:259::-;;7456:5;7450:12;7483:6;7478:3;7471:19;7499:63;7555:6;7548:4;7543:3;7539:14;7532:4;7525:5;7521:16;7499:63;:::i;:::-;7616:2;7595:15;-1:-1:-1;;7591:29:1;7582:39;;;;7623:4;7578:50;;7426:208;-1:-1:-1;;7426:208:1:o;7639:986::-;;7844:3;7879:6;7873:13;7909:36;7935:9;7909:36;:::i;:::-;7964:1;7981:18;;;8008:104;;;;8126:1;8121:362;;;;7974:509;;8008:104;-1:-1:-1;;8041:24:1;;8029:37;;8086:16;;;;-1:-1:-1;8008:104:1;;8121:362;8154:6;8149:3;8142:19;8184:4;8231:2;8226:3;8216:18;8256:3;8272:165;8286:6;8283:1;8280:13;8272:165;;;8364:14;;8351:11;;;8344:35;8407:16;;;;8301:10;;8272:165;;;8276:3;;;8466:6;8461:3;8457:16;8450:23;;7974:509;;;;;8514:6;8508:13;8530:55;8576:8;8571:3;8564:4;8556:6;8552:17;8530:55;:::i;:::-;8601:18;;7823:802;-1:-1:-1;;;;7823:802:1:o;8630:392::-;-1:-1:-1;;;8888:27:1;;8940:1;8931:11;;8924:27;;;;8976:2;8967:12;;8960:28;9013:2;9004:12;;8878:144::o;9027:203::-;-1:-1:-1;;;;;9191:32:1;;;;9173:51;;9161:2;9146:18;;9128:102::o;9235:490::-;-1:-1:-1;;;;;9504:15:1;;;9486:34;;9556:15;;9551:2;9536:18;;9529:43;9603:2;9588:18;;9581:34;;;9651:3;9646:2;9631:18;;9624:31;;;9235:490;;9672:47;;9699:19;;9691:6;9672:47;:::i;:::-;9664:55;9438:287;-1:-1:-1;;;;;;9438:287:1:o;9730:187::-;9895:14;;9888:22;9870:41;;9858:2;9843:18;;9825:92::o;9922:177::-;10068:25;;;10056:2;10041:18;;10023:76::o;10104:591::-;10391:25;;;-1:-1:-1;;;;;10490:15:1;;;10485:2;10470:18;;10463:43;10542:15;;;;10537:2;10522:18;;10515:43;10589:2;10574:18;;10567:34;10632:3;10617:19;;10610:35;;;;10443:3;10661:19;;10654:35;10378:3;10363:19;;10345:350::o;10700:489::-;10959:25;;;11015:2;11000:18;;10993:34;;;;11058:2;11043:18;;11036:34;;;;11101:2;11086:18;;11079:34;-1:-1:-1;;;;;11150:32:1;11144:3;11129:19;;11122:61;10946:3;10931:19;;10913:276::o;11194:398::-;11421:25;;;11494:4;11482:17;;;;11477:2;11462:18;;11455:45;11531:2;11516:18;;11509:34;11574:2;11559:18;;11552:34;11408:3;11393:19;;11375:217::o;11597:221::-;;11746:2;11735:9;11728:21;11766:46;11808:2;11797:9;11793:18;11785:6;11766:46;:::i;11823:938::-;;11961:2;11990;11979:9;11972:21;12013:4;12049:6;12043:13;12079:36;12105:9;12079:36;:::i;:::-;12151:6;12146:2;12135:9;12131:18;12124:34;12177:2;12198:1;12230:2;12219:9;12215:18;12247:1;12242:121;;;;12377:1;12372:363;;;;12208:527;;12242:121;-1:-1:-1;;12290:24:1;;12270:18;;;12263:52;12350:2;12335:18;;;-1:-1:-1;12242:121:1;;12372:363;12406:6;12400:4;12393:20;12457:2;12451:4;12441:19;12482:4;12499:180;12513:6;12510:1;12507:13;12499:180;;;12606:14;;12582:17;;;12578:26;;12571:50;12649:16;;;;12528:10;;12499:180;;;12703:17;;12699:26;;;-1:-1:-1;;12208:527:1;-1:-1:-1;12752:3:1;;11941:820;-1:-1:-1;;;;;;;;11941:820:1:o;12766:348::-;12968:2;12950:21;;;13007:2;12987:18;;;12980:30;13046:26;13041:2;13026:18;;13019:54;13105:2;13090:18;;12940:174::o;13119:344::-;13321:2;13303:21;;;13360:2;13340:18;;;13333:30;-1:-1:-1;;;13394:2:1;13379:18;;13372:50;13454:2;13439:18;;13293:170::o;13468:340::-;13670:2;13652:21;;;13709:2;13689:18;;;13682:30;-1:-1:-1;;;13743:2:1;13728:18;;13721:46;13799:2;13784:18;;13642:166::o;13813:414::-;14015:2;13997:21;;;14054:2;14034:18;;;14027:30;14093:34;14088:2;14073:18;;14066:62;-1:-1:-1;;;14159:2:1;14144:18;;14137:48;14217:3;14202:19;;13987:240::o;14232:352::-;14434:2;14416:21;;;14473:2;14453:18;;;14446:30;14512;14507:2;14492:18;;14485:58;14575:2;14560:18;;14406:178::o;14589:403::-;14791:2;14773:21;;;14830:2;14810:18;;;14803:30;14869:34;14864:2;14849:18;;14842:62;-1:-1:-1;;;14935:2:1;14920:18;;14913:37;14982:3;14967:19;;14763:229::o;14997:400::-;15199:2;15181:21;;;15238:2;15218:18;;;15211:30;15277:34;15272:2;15257:18;;15250:62;-1:-1:-1;;;15343:2:1;15328:18;;15321:34;15387:3;15372:19;;15171:226::o;15402:349::-;15604:2;15586:21;;;15643:2;15623:18;;;15616:30;15682:27;15677:2;15662:18;;15655:55;15742:2;15727:18;;15576:175::o;15756:355::-;15958:2;15940:21;;;15997:2;15977:18;;;15970:30;16036:33;16031:2;16016:18;;16009:61;16102:2;16087:18;;15930:181::o;16116:398::-;16318:2;16300:21;;;16357:2;16337:18;;;16330:30;16396:34;16391:2;16376:18;;16369:62;-1:-1:-1;;;16462:2:1;16447:18;;16440:32;16504:3;16489:19;;16290:224::o;16519:426::-;16721:2;16703:21;;;16760:2;16740:18;;;16733:30;16799:34;16794:2;16779:18;;16772:62;16870:32;16865:2;16850:18;;16843:60;16935:3;16920:19;;16693:252::o;16950:408::-;17152:2;17134:21;;;17191:2;17171:18;;;17164:30;17230:34;17225:2;17210:18;;17203:62;-1:-1:-1;;;17296:2:1;17281:18;;17274:42;17348:3;17333:19;;17124:234::o;17363:340::-;17565:2;17547:21;;;17604:2;17584:18;;;17577:30;-1:-1:-1;;;17638:2:1;17623:18;;17616:46;17694:2;17679:18;;17537:166::o;17708:420::-;17910:2;17892:21;;;17949:2;17929:18;;;17922:30;17988:34;17983:2;17968:18;;17961:62;18059:26;18054:2;18039:18;;18032:54;18118:3;18103:19;;17882:246::o;18133:406::-;18335:2;18317:21;;;18374:2;18354:18;;;18347:30;18413:34;18408:2;18393:18;;18386:62;-1:-1:-1;;;18479:2:1;18464:18;;18457:40;18529:3;18514:19;;18307:232::o;18544:405::-;18746:2;18728:21;;;18785:2;18765:18;;;18758:30;18824:34;18819:2;18804:18;;18797:62;-1:-1:-1;;;18890:2:1;18875:18;;18868:39;18939:3;18924:19;;18718:231::o;18954:403::-;19156:2;19138:21;;;19195:2;19175:18;;;19168:30;19234:34;19229:2;19214:18;;19207:62;-1:-1:-1;;;19300:2:1;19285:18;;19278:37;19347:3;19332:19;;19128:229::o;19362:398::-;19564:2;19546:21;;;19603:2;19583:18;;;19576:30;19642:34;19637:2;19622:18;;19615:62;-1:-1:-1;;;19708:2:1;19693:18;;19686:32;19750:3;19735:19;;19536:224::o;19765:356::-;19967:2;19949:21;;;19986:18;;;19979:30;20045:34;20040:2;20025:18;;20018:62;20112:2;20097:18;;19939:182::o;20126:408::-;20328:2;20310:21;;;20367:2;20347:18;;;20340:30;20406:34;20401:2;20386:18;;20379:62;-1:-1:-1;;;20472:2:1;20457:18;;20450:42;20524:3;20509:19;;20300:234::o;20539:354::-;20741:2;20723:21;;;20780:2;20760:18;;;20753:30;20819:32;20814:2;20799:18;;20792:60;20884:2;20869:18;;20713:180::o;20898:405::-;21100:2;21082:21;;;21139:2;21119:18;;;21112:30;21178:34;21173:2;21158:18;;21151:62;-1:-1:-1;;;21244:2:1;21229:18;;21222:39;21293:3;21278:19;;21072:231::o;21308:403::-;21510:2;21492:21;;;21549:2;21529:18;;;21522:30;21588:34;21583:2;21568:18;;21561:62;-1:-1:-1;;;21654:2:1;21639:18;;21632:37;21701:3;21686:19;;21482:229::o;21716:338::-;21918:2;21900:21;;;21957:2;21937:18;;;21930:30;-1:-1:-1;;;21991:2:1;21976:18;;21969:44;22045:2;22030:18;;21890:164::o;22059:352::-;22261:2;22243:21;;;22300:2;22280:18;;;22273:30;22339;22334:2;22319:18;;22312:58;22402:2;22387:18;;22233:178::o;22416:397::-;22618:2;22600:21;;;22657:2;22637:18;;;22630:30;22696:34;22691:2;22676:18;;22669:62;-1:-1:-1;;;22762:2:1;22747:18;;22740:31;22803:3;22788:19;;22590:223::o;22818:413::-;23020:2;23002:21;;;23059:2;23039:18;;;23032:30;23098:34;23093:2;23078:18;;23071:62;-1:-1:-1;;;23164:2:1;23149:18;;23142:47;23221:3;23206:19;;22992:239::o;23236:338::-;23438:2;23420:21;;;23477:2;23457:18;;;23450:30;-1:-1:-1;;;23511:2:1;23496:18;;23489:44;23565:2;23550:18;;23410:164::o;23579:347::-;23781:2;23763:21;;;23820:2;23800:18;;;23793:30;23859:25;23854:2;23839:18;;23832:53;23917:2;23902:18;;23753:173::o;23931:412::-;24133:2;24115:21;;;24172:2;24152:18;;;24145:30;24211:34;24206:2;24191:18;;24184:62;-1:-1:-1;;;24277:2:1;24262:18;;24255:46;24333:3;24318:19;;24105:238::o;24348:353::-;24550:2;24532:21;;;24589:2;24569:18;;;24562:30;24628:31;24623:2;24608:18;;24601:59;24692:2;24677:18;;24522:179::o;24888:292::-;;25065:6;25054:9;25047:25;25108:2;25103;25092:9;25088:18;25081:30;25128:46;25170:2;25159:9;25155:18;25147:6;25128:46;:::i;25185:275::-;25256:2;25250:9;25321:2;25302:13;;-1:-1:-1;;25298:27:1;25286:40;;25356:18;25341:34;;25377:22;;;25338:62;25335:2;;;25403:18;;:::i;:::-;25439:2;25432:22;25230:230;;-1:-1:-1;25230:230:1:o;25465:192::-;;25564:18;25556:6;25553:30;25550:2;;;25586:18;;:::i;:::-;-1:-1:-1;25646:4:1;25627:17;;;25623:28;;25540:117::o;25662:128::-;;25733:1;25729:6;25726:1;25723:13;25720:2;;;25739:18;;:::i;:::-;-1:-1:-1;25775:9:1;;25710:80::o;25795:120::-;;25861:1;25851:2;;25866:18;;:::i;:::-;-1:-1:-1;25900:9:1;;25841:74::o;25920:125::-;;25988:1;25985;25982:8;25979:2;;;25993:18;;:::i;:::-;-1:-1:-1;26030:9:1;;25969:76::o;26050:258::-;26122:1;26132:113;26146:6;26143:1;26140:13;26132:113;;;26222:11;;;26216:18;26203:11;;;26196:39;26168:2;26161:10;26132:113;;;26263:6;26260:1;26257:13;26254:2;;;-1:-1:-1;;26298:1:1;26280:16;;26273:27;26103:205::o;26313:136::-;;26380:5;26370:2;;26389:18;;:::i;:::-;-1:-1:-1;;;26425:18:1;;26360:89::o;26454:380::-;26539:1;26529:12;;26586:1;26576:12;;;26597:2;;26651:4;26643:6;26639:17;26629:27;;26597:2;26704;26696:6;26693:14;26673:18;26670:38;26667:2;;;26750:10;26745:3;26741:20;26738:1;26731:31;26785:4;26782:1;26775:15;26813:4;26810:1;26803:15;26667:2;;26509:325;;;:::o;26839:135::-;;-1:-1:-1;;26899:17:1;;26896:2;;;26919:18;;:::i;:::-;-1:-1:-1;26966:1:1;26955:13;;26886:88::o;26979:175::-;;27060:4;27053:5;27049:16;27089:4;27080:7;27077:17;27074:2;;;27097:18;;:::i;:::-;27146:1;27133:15;;27024:130;-1:-1:-1;;27024:130:1:o;27159:112::-;;27217:1;27207:2;;27222:18;;:::i;:::-;-1:-1:-1;27256:9:1;;27197:74::o;27276:127::-;27337:10;27332:3;27328:20;27325:1;27318:31;27368:4;27365:1;27358:15;27392:4;27389:1;27382:15;27408:127;27469:10;27464:3;27460:20;27457:1;27450:31;27500:4;27497:1;27490:15;27524:4;27521:1;27514:15;27540:127;27601:10;27596:3;27592:20;27589:1;27582:31;27632:4;27629:1;27622:15;27656:4;27653:1;27646:15;27672:133;-1:-1:-1;;;;;;27748:32:1;;27738:43;;27728:2;;27795:1;27792;27785:12

Swarm Source

ipfs://34e908cd6ddb0582d7570667294786cdd2e311f0822435b9e27f02e40aa6350c
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.