MATIC Price: $0.727663 (-2.74%)
Gas: 30 GWei
 

Overview

Max Total Supply

799 ERC721_STANDARD

Holders

210

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Filtered by Token Holder
Null: 0x000…000
Balance
0 ERC721_STANDARD
0x0000000000000000000000000000000000000000
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information

Contract Source Code Verified (Exact Match)

Contract Name:
Tatum721

Compiler Version
v0.8.0+commit.c7dfd78e

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at polygonscan.com on 2021-09-07
*/

pragma solidity ^0.8.0;
pragma experimental ABIEncoderV2;



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


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


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


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


/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {

    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

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

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


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


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


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

}


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


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


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

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

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

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

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

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

    function tokensOfOwner(address owner) public view returns (uint256[] memory) {
        uint256[] memory memoryArray = new uint256[](ERC721.balanceOf(owner));
        for(uint i = 0; i < ERC721.balanceOf(owner); i++) {
            memoryArray[i] = _ownedTokens[owner][i];
        }
        return memoryArray;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


/**
 * @dev ERC721 token with storage based token uri management.
 */
abstract contract ERC721URIStorage is ERC721 {
    using Strings for uint256;

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

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

        string memory _tokenURI = _tokenURIs[tokenId];
        string memory base = _baseURI();

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

        return super.tokenURI(tokenId);
    }

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

    /**
     * @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 override {
        super._burn(tokenId);

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


/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    function hasRole(bytes32 role, address account) external view returns (bool);
    function getRoleAdmin(bytes32 role) external view returns (bytes32);
    function grantRole(bytes32 role, address account) external;
    function revokeRole(bytes32 role, address account) external;
    function renounceRole(bytes32 role, address account) external;
}

/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping (address => bool) members;
        bytes32 adminRole;
    }

    mapping (bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

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

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view override returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) public virtual override {
        require(hasRole(getRoleAdmin(role), _msgSender()), "AccessControl: sender must be an admin to grant");

        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) public virtual override {
        require(hasRole(getRoleAdmin(role), _msgSender()), "AccessControl: sender must be an admin to revoke");

        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) public virtual override {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        emit RoleAdminChanged(role, getRoleAdmin(role), adminRole);
        _roles[role].adminRole = adminRole;
    }

    function _grantRole(bytes32 role, address account) private {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    function _revokeRole(bytes32 role, address account) private {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}


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

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

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

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

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

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

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

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

            bytes32 lastvalue = set._values[lastIndex];

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

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

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

            return true;
        } else {
            return false;
        }
    }

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

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

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

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

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

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

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

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

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

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

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

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

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

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

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


    // UintSet

    struct UintSet {
        Set _inner;
    }

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

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

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

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

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


/**
 * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.
 */
interface IAccessControlEnumerable {
    function getRoleMember(bytes32 role, uint256 index) external view returns (address);
    function getRoleMemberCount(bytes32 role) external view returns (uint256);
}

/**
 * @dev Extension of {AccessControl} that allows enumerating the members of each role.
 */
abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {
    using EnumerableSet for EnumerableSet.AddressSet;

    mapping (bytes32 => EnumerableSet.AddressSet) private _roleMembers;

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

    /**
     * @dev Returns one of the accounts that have `role`. `index` must be a
     * value between 0 and {getRoleMemberCount}, non-inclusive.
     *
     * Role bearers are not sorted in any particular way, and their ordering may
     * change at any point.
     *
     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
     * you perform all queries on the same block. See the following
     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
     * for more information.
     */
    function getRoleMember(bytes32 role, uint256 index) public view override returns (address) {
        return _roleMembers[role].at(index);
    }

    /**
     * @dev Returns the number of accounts that have `role`. Can be used
     * together with {getRoleMember} to enumerate all bearers of a role.
     */
    function getRoleMemberCount(bytes32 role) public view override returns (uint256) {
        return _roleMembers[role].length();
    }

    /**
     * @dev Overload {grantRole} to track enumerable memberships
     */
    function grantRole(bytes32 role, address account) public virtual override {
        super.grantRole(role, account);
        _roleMembers[role].add(account);
    }

    /**
     * @dev Overload {revokeRole} to track enumerable memberships
     */
    function revokeRole(bytes32 role, address account) public virtual override {
        super.revokeRole(role, account);
        _roleMembers[role].remove(account);
    }

    /**
     * @dev Overload {_setupRole} to track enumerable memberships
     */
    function _setupRole(bytes32 role, address account) internal virtual override {
        super._setupRole(role, account);
        _roleMembers[role].add(account);
    }
}

//SPDX-License-Identifier: MIT
contract Tatum721 is
ERC721Enumerable,
ERC721URIStorage,
AccessControlEnumerable
{
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");

    // mapping cashback to addresses and their values
    mapping(uint256 => address[]) private _cashbackRecipients;
    mapping(uint256 => uint256[]) private _cashbackValues;

    constructor (string memory name_, string memory symbol_) ERC721(name_, symbol_) {
        _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
        _setupRole(MINTER_ROLE, _msgSender());
    }

    /**
     * @dev Function to mint tokens.
     * @param to The address that will receive the minted tokens.
     * @param tokenId The token id to mint.
     * @param uri The token URI of the minted token.
     * @return A boolean that indicates if the operation was successful.
     */
    function mintWithTokenURI(
        address to,
        uint256 tokenId,
        string memory uri
    ) public returns (bool) {
        require(
            hasRole(MINTER_ROLE, _msgSender()),
            "ERC721PresetMinterPauserAutoId: must have minter role to mint"
        );
        _mint(to, tokenId);
        _setTokenURI(tokenId, uri);
        return true;
    }

    function supportsInterface(bytes4 interfaceId)
    public view virtual override(AccessControlEnumerable, ERC721, ERC721Enumerable)
    returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }

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

    function tokenCashbackValues(uint256 tokenId)
    public view virtual returns (uint256[] memory)
    {
        return _cashbackValues[tokenId];
    }

    function tokenCashbackRecipients(uint256 tokenId)
    public view virtual returns (address[] memory)
    {
        return _cashbackRecipients[tokenId];
    }

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual override(ERC721, ERC721Enumerable) {
        super._beforeTokenTransfer(from, to, tokenId);
    }

    function _burn(uint256 tokenId)
    internal virtual override(ERC721, ERC721URIStorage)
    {
        return ERC721URIStorage._burn(tokenId);
    }

    function mintMultiple(
        address[] memory to,
        uint256[] memory tokenId,
        string[] memory uri
    ) public returns (bool) {
        require(
            hasRole(MINTER_ROLE, _msgSender()),
            "ERC721PresetMinterPauserAutoId: must have minter role to mint"
        );
        for (uint256 i = 0; i < to.length; i++) {
            _mint(to[i], tokenId[i]);
            _setTokenURI(tokenId[i], uri[i]);
        }
        return true;
    }

    function updateCashbackForAuthor(
        uint256 tokenId,
        uint256 cashbackValue
    ) public returns (bool) {
        for (uint256 i = 0; i < _cashbackValues[tokenId].length; i++) {
            if (_cashbackRecipients[tokenId][i] == _msgSender()) {
                _cashbackValues[tokenId][i] = cashbackValue;
                return true;
            }
        }
        return true;
    }

    function mintMultipleCashback(
        address[] memory to,
        uint256[] memory tokenId,
        string[] memory uri,
        address[][] memory recipientAddresses,
        uint256[][] memory cashbackValues
    ) public returns (bool) {
        require(
            hasRole(MINTER_ROLE, _msgSender()),
            "ERC721PresetMinterPauserAutoId: must have minter role to mint"
        );
        for (uint256 i = 0; i < to.length; i++) {
            _mint(to[i], tokenId[i]);
            _setTokenURI(tokenId[i], uri[i]);
            _cashbackRecipients[tokenId[i]] = recipientAddresses[i];
            _cashbackValues[tokenId[i]] = cashbackValues[i];
        }
        return true;
    }

    function mintWithCashback(
        address to,
        uint256 tokenId,
        string memory uri,
        address[] memory recipientAddresses,
        uint256[] memory cashbackValues
    ) public returns (bool) {
        require(
            hasRole(MINTER_ROLE, _msgSender()),
            "ERC721PresetMinterPauserAutoId: must have minter role to mint"
        );
        _mint(to, tokenId);
        _setTokenURI(tokenId, uri);
        // saving cashback addresses and values
        _cashbackRecipients[tokenId] = recipientAddresses;
        _cashbackValues[tokenId] = cashbackValues;
        return true;
    }

    function burn(uint256 tokenId) public virtual {
        //solhint-disable-next-line max-line-length
        require(
            _isApprovedOrOwner(_msgSender(), tokenId),
            "ERC721Burnable: caller is not owner nor approved"
        );
        _burn(tokenId);
    }

    function safeTransfer(address to, uint256 tokenId) public payable {
        if (_cashbackRecipients[tokenId].length != 0) {
            // checking cashback addresses exists and sum of cashbacks
            require(
                _cashbackRecipients[tokenId].length != 0,
                "CashbackToken should be of cashback type"
            );
            uint256 sum = 0;
            for (uint256 i = 0; i < _cashbackValues[tokenId].length; i++) {
                sum += _cashbackValues[tokenId][i];
            }
            if (sum > msg.value) {
                payable(msg.sender).transfer(msg.value);
                revert("Value should be greater than or equal to cashback value");
            }
            for (uint256 i = 0; i < _cashbackRecipients[tokenId].length; i++) {
                // transferring cashback to authors
                if (_cashbackValues[tokenId][i] > 0) {
                    payable(_cashbackRecipients[tokenId][i]).transfer(
                        _cashbackValues[tokenId][i]
                    );
                }
            }
            if (msg.value > sum) {
                payable(msg.sender).transfer(msg.value - sum);
            }
            _safeTransfer(_msgSender(), to, tokenId, "");
        } else {
            if (msg.value > 0) {
                payable(msg.sender).transfer(msg.value);
            }
            _safeTransfer(_msgSender(), to, tokenId, "");
        }
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"name_","type":"string"},{"internalType":"string","name":"symbol_","type":"string"}],"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":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"to","type":"address[]"},{"internalType":"uint256[]","name":"tokenId","type":"uint256[]"},{"internalType":"string[]","name":"uri","type":"string[]"}],"name":"mintMultiple","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"to","type":"address[]"},{"internalType":"uint256[]","name":"tokenId","type":"uint256[]"},{"internalType":"string[]","name":"uri","type":"string[]"},{"internalType":"address[][]","name":"recipientAddresses","type":"address[][]"},{"internalType":"uint256[][]","name":"cashbackValues","type":"uint256[][]"}],"name":"mintMultipleCashback","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"uri","type":"string"},{"internalType":"address[]","name":"recipientAddresses","type":"address[]"},{"internalType":"uint256[]","name":"cashbackValues","type":"uint256[]"}],"name":"mintWithCashback","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"uri","type":"string"}],"name":"mintWithTokenURI","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransfer","outputs":[],"stateMutability":"payable","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":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenCashbackRecipients","outputs":[{"internalType":"address[]","name":"","type":"address[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenCashbackValues","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"cashbackValue","type":"uint256"}],"name":"updateCashbackForAuthor","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b5060405162003baf38038062003baf83398101604081905262000034916200039b565b8151829082906200004d9060009060208501906200024a565b508051620000639060019060208401906200024a565b506200007e91506000905062000078620000b5565b620000b9565b620000ad7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a662000078620000b5565b505062000455565b3390565b620000d08282620000fc60201b620015531760201c565b6000828152600c60209081526040909120620000f79183906200155d6200010c821b17901c565b505050565b6200010882826200012c565b5050565b600062000123836001600160a01b038416620001b8565b90505b92915050565b62000138828262000207565b62000108576000828152600b602090815260408083206001600160a01b03851684529091529020805460ff1916600117905562000174620000b5565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000620001c6838362000232565b620001fe5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000126565b50600062000126565b6000918252600b602090815260408084206001600160a01b0393909316845291905290205460ff1690565b60009081526001919091016020526040902054151590565b828054620002589062000402565b90600052602060002090601f0160209004810192826200027c5760008555620002c7565b82601f106200029757805160ff1916838001178555620002c7565b82800160010185558215620002c7579182015b82811115620002c7578251825591602001919060010190620002aa565b50620002d5929150620002d9565b5090565b5b80821115620002d55760008155600101620002da565b600082601f83011262000301578081fd5b81516001600160401b03808211156200031e576200031e6200043f565b6040516020601f8401601f19168201810183811183821017156200034657620003466200043f565b60405283825285840181018710156200035d578485fd5b8492505b8383101562000380578583018101518284018201529182019162000361565b838311156200039157848185840101525b5095945050505050565b60008060408385031215620003ae578182fd5b82516001600160401b0380821115620003c5578384fd5b620003d386838701620002f0565b93506020850151915080821115620003e9578283fd5b50620003f885828601620002f0565b9150509250929050565b6002810460018216806200041757607f821691505b602082108114156200043957634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b61374a80620004656000396000f3fe6080604052600436106102045760003560e01c806350bb4e7f11610118578063a217fddf116100a0578063ca15c8731161006f578063ca15c873146105e9578063d539139314610609578063d547741f1461061e578063e985e9c51461063e578063f582b9601461065e57610204565b8063a217fddf14610574578063a22cb46514610589578063b88d4fde146105a9578063c87b56dd146105c957610204565b80638462151c116100e75780638462151c146104df5780639010d07c146104ff57806391d148541461051f57806394f68d841461053f57806395d89b411461055f57610204565b806350bb4e7f1461045f5780635a9c9eb81461047f5780636352211e1461049f57806370a08231146104bf57610204565b8063248a9ca31161019b57806336568abe1161016a57806336568abe146103cc578063423f6cef146103ec57806342842e0e146103ff57806342966c681461041f5780634f6ccce71461043f57610204565b8063248a9ca31461033f5780632f2ff15d1461035f5780632f745c591461037f578063303024df1461039f57610204565b806318160ddd116101d757806318160ddd146102b057806319be9059146102d25780631c6fe816146102f257806323b872dd1461031f57610204565b806301ffc9a71461020957806306fdde031461023f578063081812fc14610261578063095ea7b31461028e575b600080fd5b34801561021557600080fd5b50610229610224366004612c42565b61067e565b6040516102369190612dab565b60405180910390f35b34801561024b57600080fd5b50610254610691565b6040516102369190612dbf565b34801561026d57600080fd5b5061028161027c366004612be7565b610723565b6040516102369190612cd5565b34801561029a57600080fd5b506102ae6102a9366004612991565b61076f565b005b3480156102bc57600080fd5b506102c5610807565b6040516102369190612db6565b3480156102de57600080fd5b506102296102ed366004612a0f565b61080d565b3480156102fe57600080fd5b5061031261030d366004612be7565b6108a5565b6040516102369190612d26565b34801561032b57600080fd5b506102ae61033a3660046128a3565b610911565b34801561034b57600080fd5b506102c561035a366004612be7565b610949565b34801561036b57600080fd5b506102ae61037a366004612bff565b61095e565b34801561038b57600080fd5b506102c561039a366004612991565b610980565b3480156103ab57600080fd5b506103bf6103ba366004612be7565b6109d5565b6040516102369190612d73565b3480156103d857600080fd5b506102ae6103e7366004612bff565b610a36565b6102ae6103fa366004612991565b610a7c565b34801561040b57600080fd5b506102ae61041a3660046128a3565b610d56565b34801561042b57600080fd5b506102ae61043a366004612be7565b610d71565b34801561044b57600080fd5b506102c561045a366004612be7565b610da4565b34801561046b57600080fd5b5061022961047a3660046129ba565b610dff565b34801561048b57600080fd5b5061022961049a366004612aae565b610e55565b3480156104ab57600080fd5b506102816104ba366004612be7565b610f66565b3480156104cb57600080fd5b506102c56104da366004612857565b610f9b565b3480156104eb57600080fd5b506103bf6104fa366004612857565b610fdf565b34801561050b57600080fd5b5061028161051a366004612c21565b6110bb565b34801561052b57600080fd5b5061022961053a366004612bff565b6110da565b34801561054b57600080fd5b5061022961055a366004612b28565b611105565b34801561056b57600080fd5b506102546112dd565b34801561058057600080fd5b506102c56112ec565b34801561059557600080fd5b506102ae6105a4366004612957565b6112f1565b3480156105b557600080fd5b506102ae6105c43660046128de565b6113bf565b3480156105d557600080fd5b506102546105e4366004612be7565b6113fe565b3480156105f557600080fd5b506102c5610604366004612be7565b611409565b34801561061557600080fd5b506102c5611420565b34801561062a57600080fd5b506102ae610639366004612bff565b611432565b34801561064a57600080fd5b50610229610659366004612871565b611454565b34801561066a57600080fd5b50610229610679366004612c21565b611482565b600061068982611572565b90505b919050565b6060600080546106a090613632565b80601f01602080910402602001604051908101604052809291908181526020018280546106cc90613632565b80156107195780601f106106ee57610100808354040283529160200191610719565b820191906000526020600020905b8154815290600101906020018083116106fc57829003601f168201915b5050505050905090565b600061072e82611597565b6107535760405162461bcd60e51b815260040161074a9061326f565b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061077a82610f66565b9050806001600160a01b0316836001600160a01b031614156107ae5760405162461bcd60e51b815260040161074a9061339b565b806001600160a01b03166107c06115b4565b6001600160a01b031614806107dc57506107dc816106596115b4565b6107f85760405162461bcd60e51b815260040161074a9061304e565b61080283836115b8565b505050565b60085490565b60006108296000805160206136f583398151915261053a6115b4565b6108455760405162461bcd60e51b815260040161074a90613479565b61084f8686611626565b6108598585611705565b6000858152600d6020908152604090912084516108789286019061249d565b506000858152600e60209081526040909120835161089892850190612502565b5060019695505050505050565b6000818152600d602090815260409182902080548351818402810184019094528084526060939283018282801561090557602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116108e7575b50505050509050919050565b61092261091c6115b4565b82611749565b61093e5760405162461bcd60e51b815260040161074a906133dc565b6108028383836117ce565b6000908152600b602052604090206001015490565b61096882826118fb565b6000828152600c60205260409020610802908261155d565b600061098b83610f9b565b82106109a95760405162461bcd60e51b815260040161074a90612e63565b506001600160a01b03821660009081526006602090815260408083208484529091529020545b92915050565b6000818152600e602090815260409182902080548351818402810184019094528084526060939283018282801561090557602002820191906000526020600020905b815481526020019060010190808311610a175750505050509050919050565b610a3e6115b4565b6001600160a01b0316816001600160a01b031614610a6e5760405162461bcd60e51b815260040161074a90613526565b610a78828261192b565b5050565b6000818152600d602052604090205415610d00576000818152600d6020526040902054610abb5760405162461bcd60e51b815260040161074a906132bb565b6000805b6000838152600e6020526040902054811015610b2d576000838152600e60205260409020805482908110610b0357634e487b7160e01b600052603260045260246000fd5b906000526020600020015482610b1991906135c3565b915080610b258161366d565b915050610abf565b5034811115610b7b5760405133903480156108fc02916000818181858888f19350505050158015610b62573d6000803e3d6000fd5b5060405162461bcd60e51b815260040161074a9061318c565b60005b6000838152600d6020526040902054811015610c97576000838152600e60205260408120805483908110610bc257634e487b7160e01b600052603260045260246000fd5b90600052602060002001541115610c85576000838152600d60205260409020805482908110610c0157634e487b7160e01b600052603260045260246000fd5b6000918252602080832090910154858352600e909152604090912080546001600160a01b03909216916108fc919084908110610c4d57634e487b7160e01b600052603260045260246000fd5b90600052602060002001549081150290604051600060405180830381858888f19350505050158015610c83573d6000803e3d6000fd5b505b80610c8f8161366d565b915050610b7e565b5080341115610cd857336108fc610cae83346135ef565b6040518115909202916000818181858888f19350505050158015610cd6573d6000803e3d6000fd5b505b610cfa610ce36115b4565b8484604051806020016040528060008152506119b0565b50610a78565b3415610d345760405133903480156108fc02916000818181858888f19350505050158015610d32573d6000803e3d6000fd5b505b610a78610d3f6115b4565b8383604051806020016040528060008152506119b0565b610802838383604051806020016040528060008152506113bf565b610d7c61091c6115b4565b610d985760405162461bcd60e51b815260040161074a906134d6565b610da1816119e3565b50565b6000610dae610807565b8210610dcc5760405162461bcd60e51b815260040161074a9061342d565b60088281548110610ded57634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050919050565b6000610e1b6000805160206136f583398151915261053a6115b4565b610e375760405162461bcd60e51b815260040161074a90613479565b610e418484611626565b610e4b8383611705565b5060019392505050565b6000610e716000805160206136f583398151915261053a6115b4565b610e8d5760405162461bcd60e51b815260040161074a90613479565b60005b8451811015610f5b57610ef1858281518110610ebc57634e487b7160e01b600052603260045260246000fd5b6020026020010151858381518110610ee457634e487b7160e01b600052603260045260246000fd5b6020026020010151611626565b610f49848281518110610f1457634e487b7160e01b600052603260045260246000fd5b6020026020010151848381518110610f3c57634e487b7160e01b600052603260045260246000fd5b6020026020010151611705565b80610f538161366d565b915050610e90565b506001949350505050565b6000818152600260205260408120546001600160a01b0316806106895760405162461bcd60e51b815260040161074a906130f5565b60006001600160a01b038216610fc35760405162461bcd60e51b815260040161074a906130ab565b506001600160a01b031660009081526003602052604090205490565b60606000610fec83610f9b565b67ffffffffffffffff81111561101257634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561103b578160200160208202803683370190505b50905060005b61104a84610f9b565b8110156110b4576001600160a01b0384166000908152600660209081526040808320848452909152902054825183908390811061109757634e487b7160e01b600052603260045260246000fd5b6020908102919091010152806110ac8161366d565b915050611041565b5092915050565b6000828152600c602052604081206110d390836119ec565b9392505050565b6000918252600b602090815260408084206001600160a01b0393909316845291905290205460ff1690565b60006111216000805160206136f583398151915261053a6115b4565b61113d5760405162461bcd60e51b815260040161074a90613479565b60005b86518110156108985761119487828151811061116c57634e487b7160e01b600052603260045260246000fd5b6020026020010151878381518110610ee457634e487b7160e01b600052603260045260246000fd5b6111df8682815181106111b757634e487b7160e01b600052603260045260246000fd5b6020026020010151868381518110610f3c57634e487b7160e01b600052603260045260246000fd5b8381815181106111ff57634e487b7160e01b600052603260045260246000fd5b6020026020010151600d600088848151811061122b57634e487b7160e01b600052603260045260246000fd5b60200260200101518152602001908152602001600020908051906020019061125492919061249d565b5082818151811061127557634e487b7160e01b600052603260045260246000fd5b6020026020010151600e60008884815181106112a157634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002090805190602001906112ca929190612502565b50806112d58161366d565b915050611140565b6060600180546106a090613632565b600081565b6112f96115b4565b6001600160a01b0316826001600160a01b0316141561132a5760405162461bcd60e51b815260040161074a90612f7b565b80600560006113376115b4565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff19169215159290921790915561137b6115b4565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516113b39190612dab565b60405180910390a35050565b6113d06113ca6115b4565b83611749565b6113ec5760405162461bcd60e51b815260040161074a906133dc565b6113f8848484846119b0565b50505050565b6060610689826119f8565b6000818152600c6020526040812061068990611b11565b6000805160206136f583398151915281565b61143c8282611b1c565b6000828152600c602052604090206108029082611b44565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6000805b6000848152600e6020526040902054811015610e4b576114a46115b4565b6001600160a01b0316600d600086815260200190815260200160002082815481106114df57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b03161415611541576000848152600e6020526040902080548491908390811061152b57634e487b7160e01b600052603260045260246000fd5b60009182526020909120015550600190506109cf565b8061154b8161366d565b915050611486565b610a788282611b59565b60006110d3836001600160a01b038416611be0565b60006001600160e01b03198216635a05180f60e01b1480610689575061068982611c2a565b6000908152600260205260409020546001600160a01b0316151590565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906115ed82610f66565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6001600160a01b03821661164c5760405162461bcd60e51b815260040161074a906131e9565b61165581611597565b156116725760405162461bcd60e51b815260040161074a90612f00565b61167e60008383611c4f565b6001600160a01b03821660009081526003602052604081208054600192906116a79084906135c3565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b61170e82611597565b61172a5760405162461bcd60e51b815260040161074a9061313e565b6000828152600a6020908152604090912082516108029284019061253d565b600061175482611597565b6117705760405162461bcd60e51b815260040161074a90612fb2565b600061177b83610f66565b9050806001600160a01b0316846001600160a01b031614806117b65750836001600160a01b03166117ab84610723565b6001600160a01b0316145b806117c657506117c68185611454565b949350505050565b826001600160a01b03166117e182610f66565b6001600160a01b0316146118075760405162461bcd60e51b815260040161074a90613303565b6001600160a01b03821661182d5760405162461bcd60e51b815260040161074a90612f37565b611838838383611c4f565b6118436000826115b8565b6001600160a01b038316600090815260036020526040812080546001929061186c9084906135ef565b90915550506001600160a01b038216600090815260036020526040812080546001929061189a9084906135c3565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b61190f61190783610949565b61053a6115b4565b6115535760405162461bcd60e51b815260040161074a90612e14565b61193582826110da565b15610a78576000828152600b602090815260408083206001600160a01b03851684529091529020805460ff1916905561196c6115b4565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6119bb8484846117ce565b6119c784848484611c5a565b6113f85760405162461bcd60e51b815260040161074a90612eae565b610da181611d6a565b60006110d38383611daa565b6060611a0382611597565b611a1f5760405162461bcd60e51b815260040161074a9061321e565b6000828152600a602052604081208054611a3890613632565b80601f0160208091040260200160405190810160405280929190818152602001828054611a6490613632565b8015611ab15780601f10611a8657610100808354040283529160200191611ab1565b820191906000526020600020905b815481529060010190602001808311611a9457829003601f168201915b505050505090506000611ac2611e03565b9050805160001415611ad65750905061068c565b815115611b08578082604051602001611af0929190612ca6565b6040516020818303038152906040529250505061068c565b6117c684611e15565b600061068982611e97565b611b2861190783610949565b610a6e5760405162461bcd60e51b815260040161074a90612ffe565b60006110d3836001600160a01b038416611e9b565b611b6382826110da565b610a78576000828152600b602090815260408083206001600160a01b03851684529091529020805460ff19166001179055611b9c6115b4565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000611bec8383611fb8565b611c22575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556109cf565b5060006109cf565b60006001600160e01b03198216637965db0b60e01b1480610689575061068982611fd0565b610802838383611ff5565b6000611c6e846001600160a01b031661207e565b15610f5b57836001600160a01b031663150b7a02611c8a6115b4565b8786866040518563ffffffff1660e01b8152600401611cac9493929190612ce9565b602060405180830381600087803b158015611cc657600080fd5b505af1925050508015611cf6575060408051601f3d908101601f19168201909252611cf391810190612c5e565b60015b611d50573d808015611d24576040519150601f19603f3d011682016040523d82523d6000602084013e611d29565b606091505b508051611d485760405162461bcd60e51b815260040161074a90612eae565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506117c6565b611d7381612084565b6000818152600a602052604090208054611d8c90613632565b159050610da1576000818152600a60205260408120610da1916125b0565b81546000908210611dcd5760405162461bcd60e51b815260040161074a90612dd2565b826000018281548110611df057634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905092915050565b60408051602081019091526000815290565b6060611e2082611597565b611e3c5760405162461bcd60e51b815260040161074a9061334c565b6000611e46611e03565b90506000815111611e6657604051806020016040528060008152506110d3565b80611e708461212b565b604051602001611e81929190612ca6565b6040516020818303038152906040529392505050565b5490565b60008181526001830160205260408120548015611fae576000611ebf6001836135ef565b8554909150600090611ed3906001906135ef565b90506000866000018281548110611efa57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905080876000018481548110611f2b57634e487b7160e01b600052603260045260246000fd5b600091825260209091200155611f428360016135c3565b60008281526001890160205260409020558654879080611f7257634e487b7160e01b600052603160045260246000fd5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506109cf565b60009150506109cf565b60009081526001919091016020526040902054151590565b60006001600160e01b0319821663780e9d6360e01b1480610689575061068982612246565b612000838383610802565b6001600160a01b03831661201c5761201781612286565b61203f565b816001600160a01b0316836001600160a01b03161461203f5761203f83826122ca565b6001600160a01b03821661205b5761205681612367565b610802565b826001600160a01b0316826001600160a01b031614610802576108028282612440565b3b151590565b600061208f82610f66565b905061209d81600084611c4f565b6120a86000836115b8565b6001600160a01b03811660009081526003602052604081208054600192906120d19084906135ef565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b60608161215057506040805180820190915260018152600360fc1b602082015261068c565b8160005b811561217a57806121648161366d565b91506121739050600a836135db565b9150612154565b60008167ffffffffffffffff8111156121a357634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156121cd576020820181803683370190505b5090505b84156117c6576121e26001836135ef565b91506121ef600a86613688565b6121fa9060306135c3565b60f81b81838151811061221d57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535061223f600a866135db565b94506121d1565b60006001600160e01b031982166380ac58cd60e01b148061227757506001600160e01b03198216635b5e139f60e01b145b80610689575061068982612484565b600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b600060016122d784610f9b565b6122e191906135ef565b600083815260076020526040902054909150808214612334576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090612379906001906135ef565b600083815260096020526040812054600880549394509092849081106123af57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905080600883815481106123de57634e487b7160e01b600052603260045260246000fd5b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061242457634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905550505050565b600061244b83610f9b565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160e01b031981166301ffc9a760e01b14919050565b8280548282559060005260206000209081019282156124f2579160200282015b828111156124f257825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906124bd565b506124fe9291506125e8565b5090565b8280548282559060005260206000209081019282156124f2579160200282015b828111156124f2578251825591602001919060010190612522565b82805461254990613632565b90600052602060002090601f01602090048101928261256b57600085556124f2565b82601f1061258457805160ff19168380011785556124f2565b828001600101855582156124f257918201828111156124f2578251825591602001919060010190612522565b5080546125bc90613632565b6000825580601f106125ce5750610da1565b601f016020900490600052602060002090810190610da191905b5b808211156124fe57600081556001016125e9565b600067ffffffffffffffff831115612617576126176136c8565b61262a601f8401601f1916602001613575565b905082815283838301111561263e57600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b038116811461068c57600080fd5b600082601f83011261267c578081fd5b8135602061269161268c8361359f565b613575565b82815281810190858301838502870184018810156126ad578586fd5b855b858110156126d2576126c082612655565b845292840192908401906001016126af565b5090979650505050505050565b600082601f8301126126ef578081fd5b813560206126ff61268c8361359f565b82815281810190858301855b858110156126d257612722898684358b010161266c565b8452928401929084019060010161270b565b600082601f830112612744578081fd5b8135602061275461268c8361359f565b82815281810190858301855b858110156126d257612777898684358b01016127de565b84529284019290840190600101612760565b600082601f830112612799578081fd5b813560206127a961268c8361359f565b82815281810190858301855b858110156126d2576127cc898684358b0101612838565b845292840192908401906001016127b5565b600082601f8301126127ee578081fd5b813560206127fe61268c8361359f565b828152818101908583018385028701840188101561281a578586fd5b855b858110156126d25781358452928401929084019060010161281c565b600082601f830112612848578081fd5b6110d3838335602085016125fd565b600060208284031215612868578081fd5b6110d382612655565b60008060408385031215612883578081fd5b61288c83612655565b915061289a60208401612655565b90509250929050565b6000806000606084860312156128b7578081fd5b6128c084612655565b92506128ce60208501612655565b9150604084013590509250925092565b600080600080608085870312156128f3578182fd5b6128fc85612655565b935061290a60208601612655565b925060408501359150606085013567ffffffffffffffff81111561292c578182fd5b8501601f8101871361293c578182fd5b61294b878235602084016125fd565b91505092959194509250565b60008060408385031215612969578182fd5b61297283612655565b915060208301358015158114612986578182fd5b809150509250929050565b600080604083850312156129a3578182fd5b6129ac83612655565b946020939093013593505050565b6000806000606084860312156129ce578081fd5b6129d784612655565b925060208401359150604084013567ffffffffffffffff8111156129f9578182fd5b612a0586828701612838565b9150509250925092565b600080600080600060a08688031215612a26578283fd5b612a2f86612655565b945060208601359350604086013567ffffffffffffffff80821115612a52578485fd5b612a5e89838a01612838565b94506060880135915080821115612a73578283fd5b612a7f89838a0161266c565b93506080880135915080821115612a94578283fd5b50612aa1888289016127de565b9150509295509295909350565b600080600060608486031215612ac2578081fd5b833567ffffffffffffffff80821115612ad9578283fd5b612ae58783880161266c565b94506020860135915080821115612afa578283fd5b612b06878388016127de565b93506040860135915080821115612b1b578283fd5b50612a0586828701612789565b600080600080600060a08688031215612b3f578283fd5b853567ffffffffffffffff80821115612b56578485fd5b612b6289838a0161266c565b96506020880135915080821115612b77578485fd5b612b8389838a016127de565b95506040880135915080821115612b98578485fd5b612ba489838a01612789565b94506060880135915080821115612bb9578283fd5b612bc589838a016126df565b93506080880135915080821115612bda578283fd5b50612aa188828901612734565b600060208284031215612bf8578081fd5b5035919050565b60008060408385031215612c11578182fd5b8235915061289a60208401612655565b60008060408385031215612c33578182fd5b50508035926020909101359150565b600060208284031215612c53578081fd5b81356110d3816136de565b600060208284031215612c6f578081fd5b81516110d3816136de565b60008151808452612c92816020860160208601613606565b601f01601f19169290920160200192915050565b60008351612cb8818460208801613606565b835190830190612ccc818360208801613606565b01949350505050565b6001600160a01b0391909116815260200190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612d1c90830184612c7a565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612d675783516001600160a01b031683529284019291840191600101612d42565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612d6757835183529284019291840191600101612d8f565b901515815260200190565b90815260200190565b6000602082526110d36020830184612c7a565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b6020808252602f908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526e0818591b5a5b881d1bc819dc985b9d608a1b606082015260800190565b6020808252602b908201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560408201526a74206f6620626f756e647360a81b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252601c908201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604082015260600190565b60208082526024908201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526019908201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604082015260600190565b6020808252602c908201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b60208082526030908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526f2061646d696e20746f207265766f6b6560801b606082015260800190565b60208082526038908201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760408201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606082015260800190565b6020808252602a908201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604082015269726f206164647265737360b01b606082015260800190565b60208082526029908201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460408201526832b73a103a37b5b2b760b91b606082015260800190565b6020808252602e908201527f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60408201526d32bc34b9ba32b73a103a37b5b2b760911b606082015260800190565b60208082526037908201527f56616c75652073686f756c642062652067726561746572207468616e206f722060408201527f657175616c20746f20636173686261636b2076616c7565000000000000000000606082015260800190565b6020808252818101527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b60208082526031908201527f45524337323155524953746f726167653a2055524920717565727920666f72206040820152703737b732bc34b9ba32b73a103a37b5b2b760791b606082015260800190565b6020808252602c908201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b60208082526028908201527f436173686261636b546f6b656e2073686f756c64206265206f6620636173686260408201526761636b207479706560c01b606082015260800190565b60208082526029908201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960408201526839903737ba1037bbb760b91b606082015260800190565b6020808252602f908201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60408201526e3732bc34b9ba32b73a103a37b5b2b760891b606082015260800190565b60208082526021908201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656040820152603960f91b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252602c908201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60408201526b7574206f6620626f756e647360a01b606082015260800190565b6020808252603d908201527f4552433732315072657365744d696e7465725061757365724175746f49643a2060408201527f6d7573742068617665206d696e74657220726f6c6520746f206d696e74000000606082015260800190565b60208082526030908201527f4552433732314275726e61626c653a2063616c6c6572206973206e6f74206f7760408201526f1b995c881b9bdc88185c1c1c9bdd995960821b606082015260800190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b60405181810167ffffffffffffffff81118282101715613597576135976136c8565b604052919050565b600067ffffffffffffffff8211156135b9576135b96136c8565b5060209081020190565b600082198211156135d6576135d661369c565b500190565b6000826135ea576135ea6136b2565b500490565b6000828210156136015761360161369c565b500390565b60005b83811015613621578181015183820152602001613609565b838111156113f85750506000910152565b60028104600182168061364657607f821691505b6020821081141561366757634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156136815761368161369c565b5060010190565b600082613697576136976136b2565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114610da157600080fdfe9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6a26469706673582212206759dfe3175285406dc33dc120b9f60db93503947770c126a83051d81cdee18e64736f6c6343000800003300000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000f4552433732315f5354414e444152440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f4552433732315f5354414e444152440000000000000000000000000000000000

Deployed Bytecode

0x6080604052600436106102045760003560e01c806350bb4e7f11610118578063a217fddf116100a0578063ca15c8731161006f578063ca15c873146105e9578063d539139314610609578063d547741f1461061e578063e985e9c51461063e578063f582b9601461065e57610204565b8063a217fddf14610574578063a22cb46514610589578063b88d4fde146105a9578063c87b56dd146105c957610204565b80638462151c116100e75780638462151c146104df5780639010d07c146104ff57806391d148541461051f57806394f68d841461053f57806395d89b411461055f57610204565b806350bb4e7f1461045f5780635a9c9eb81461047f5780636352211e1461049f57806370a08231146104bf57610204565b8063248a9ca31161019b57806336568abe1161016a57806336568abe146103cc578063423f6cef146103ec57806342842e0e146103ff57806342966c681461041f5780634f6ccce71461043f57610204565b8063248a9ca31461033f5780632f2ff15d1461035f5780632f745c591461037f578063303024df1461039f57610204565b806318160ddd116101d757806318160ddd146102b057806319be9059146102d25780631c6fe816146102f257806323b872dd1461031f57610204565b806301ffc9a71461020957806306fdde031461023f578063081812fc14610261578063095ea7b31461028e575b600080fd5b34801561021557600080fd5b50610229610224366004612c42565b61067e565b6040516102369190612dab565b60405180910390f35b34801561024b57600080fd5b50610254610691565b6040516102369190612dbf565b34801561026d57600080fd5b5061028161027c366004612be7565b610723565b6040516102369190612cd5565b34801561029a57600080fd5b506102ae6102a9366004612991565b61076f565b005b3480156102bc57600080fd5b506102c5610807565b6040516102369190612db6565b3480156102de57600080fd5b506102296102ed366004612a0f565b61080d565b3480156102fe57600080fd5b5061031261030d366004612be7565b6108a5565b6040516102369190612d26565b34801561032b57600080fd5b506102ae61033a3660046128a3565b610911565b34801561034b57600080fd5b506102c561035a366004612be7565b610949565b34801561036b57600080fd5b506102ae61037a366004612bff565b61095e565b34801561038b57600080fd5b506102c561039a366004612991565b610980565b3480156103ab57600080fd5b506103bf6103ba366004612be7565b6109d5565b6040516102369190612d73565b3480156103d857600080fd5b506102ae6103e7366004612bff565b610a36565b6102ae6103fa366004612991565b610a7c565b34801561040b57600080fd5b506102ae61041a3660046128a3565b610d56565b34801561042b57600080fd5b506102ae61043a366004612be7565b610d71565b34801561044b57600080fd5b506102c561045a366004612be7565b610da4565b34801561046b57600080fd5b5061022961047a3660046129ba565b610dff565b34801561048b57600080fd5b5061022961049a366004612aae565b610e55565b3480156104ab57600080fd5b506102816104ba366004612be7565b610f66565b3480156104cb57600080fd5b506102c56104da366004612857565b610f9b565b3480156104eb57600080fd5b506103bf6104fa366004612857565b610fdf565b34801561050b57600080fd5b5061028161051a366004612c21565b6110bb565b34801561052b57600080fd5b5061022961053a366004612bff565b6110da565b34801561054b57600080fd5b5061022961055a366004612b28565b611105565b34801561056b57600080fd5b506102546112dd565b34801561058057600080fd5b506102c56112ec565b34801561059557600080fd5b506102ae6105a4366004612957565b6112f1565b3480156105b557600080fd5b506102ae6105c43660046128de565b6113bf565b3480156105d557600080fd5b506102546105e4366004612be7565b6113fe565b3480156105f557600080fd5b506102c5610604366004612be7565b611409565b34801561061557600080fd5b506102c5611420565b34801561062a57600080fd5b506102ae610639366004612bff565b611432565b34801561064a57600080fd5b50610229610659366004612871565b611454565b34801561066a57600080fd5b50610229610679366004612c21565b611482565b600061068982611572565b90505b919050565b6060600080546106a090613632565b80601f01602080910402602001604051908101604052809291908181526020018280546106cc90613632565b80156107195780601f106106ee57610100808354040283529160200191610719565b820191906000526020600020905b8154815290600101906020018083116106fc57829003601f168201915b5050505050905090565b600061072e82611597565b6107535760405162461bcd60e51b815260040161074a9061326f565b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061077a82610f66565b9050806001600160a01b0316836001600160a01b031614156107ae5760405162461bcd60e51b815260040161074a9061339b565b806001600160a01b03166107c06115b4565b6001600160a01b031614806107dc57506107dc816106596115b4565b6107f85760405162461bcd60e51b815260040161074a9061304e565b61080283836115b8565b505050565b60085490565b60006108296000805160206136f583398151915261053a6115b4565b6108455760405162461bcd60e51b815260040161074a90613479565b61084f8686611626565b6108598585611705565b6000858152600d6020908152604090912084516108789286019061249d565b506000858152600e60209081526040909120835161089892850190612502565b5060019695505050505050565b6000818152600d602090815260409182902080548351818402810184019094528084526060939283018282801561090557602002820191906000526020600020905b81546001600160a01b031681526001909101906020018083116108e7575b50505050509050919050565b61092261091c6115b4565b82611749565b61093e5760405162461bcd60e51b815260040161074a906133dc565b6108028383836117ce565b6000908152600b602052604090206001015490565b61096882826118fb565b6000828152600c60205260409020610802908261155d565b600061098b83610f9b565b82106109a95760405162461bcd60e51b815260040161074a90612e63565b506001600160a01b03821660009081526006602090815260408083208484529091529020545b92915050565b6000818152600e602090815260409182902080548351818402810184019094528084526060939283018282801561090557602002820191906000526020600020905b815481526020019060010190808311610a175750505050509050919050565b610a3e6115b4565b6001600160a01b0316816001600160a01b031614610a6e5760405162461bcd60e51b815260040161074a90613526565b610a78828261192b565b5050565b6000818152600d602052604090205415610d00576000818152600d6020526040902054610abb5760405162461bcd60e51b815260040161074a906132bb565b6000805b6000838152600e6020526040902054811015610b2d576000838152600e60205260409020805482908110610b0357634e487b7160e01b600052603260045260246000fd5b906000526020600020015482610b1991906135c3565b915080610b258161366d565b915050610abf565b5034811115610b7b5760405133903480156108fc02916000818181858888f19350505050158015610b62573d6000803e3d6000fd5b5060405162461bcd60e51b815260040161074a9061318c565b60005b6000838152600d6020526040902054811015610c97576000838152600e60205260408120805483908110610bc257634e487b7160e01b600052603260045260246000fd5b90600052602060002001541115610c85576000838152600d60205260409020805482908110610c0157634e487b7160e01b600052603260045260246000fd5b6000918252602080832090910154858352600e909152604090912080546001600160a01b03909216916108fc919084908110610c4d57634e487b7160e01b600052603260045260246000fd5b90600052602060002001549081150290604051600060405180830381858888f19350505050158015610c83573d6000803e3d6000fd5b505b80610c8f8161366d565b915050610b7e565b5080341115610cd857336108fc610cae83346135ef565b6040518115909202916000818181858888f19350505050158015610cd6573d6000803e3d6000fd5b505b610cfa610ce36115b4565b8484604051806020016040528060008152506119b0565b50610a78565b3415610d345760405133903480156108fc02916000818181858888f19350505050158015610d32573d6000803e3d6000fd5b505b610a78610d3f6115b4565b8383604051806020016040528060008152506119b0565b610802838383604051806020016040528060008152506113bf565b610d7c61091c6115b4565b610d985760405162461bcd60e51b815260040161074a906134d6565b610da1816119e3565b50565b6000610dae610807565b8210610dcc5760405162461bcd60e51b815260040161074a9061342d565b60088281548110610ded57634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050919050565b6000610e1b6000805160206136f583398151915261053a6115b4565b610e375760405162461bcd60e51b815260040161074a90613479565b610e418484611626565b610e4b8383611705565b5060019392505050565b6000610e716000805160206136f583398151915261053a6115b4565b610e8d5760405162461bcd60e51b815260040161074a90613479565b60005b8451811015610f5b57610ef1858281518110610ebc57634e487b7160e01b600052603260045260246000fd5b6020026020010151858381518110610ee457634e487b7160e01b600052603260045260246000fd5b6020026020010151611626565b610f49848281518110610f1457634e487b7160e01b600052603260045260246000fd5b6020026020010151848381518110610f3c57634e487b7160e01b600052603260045260246000fd5b6020026020010151611705565b80610f538161366d565b915050610e90565b506001949350505050565b6000818152600260205260408120546001600160a01b0316806106895760405162461bcd60e51b815260040161074a906130f5565b60006001600160a01b038216610fc35760405162461bcd60e51b815260040161074a906130ab565b506001600160a01b031660009081526003602052604090205490565b60606000610fec83610f9b565b67ffffffffffffffff81111561101257634e487b7160e01b600052604160045260246000fd5b60405190808252806020026020018201604052801561103b578160200160208202803683370190505b50905060005b61104a84610f9b565b8110156110b4576001600160a01b0384166000908152600660209081526040808320848452909152902054825183908390811061109757634e487b7160e01b600052603260045260246000fd5b6020908102919091010152806110ac8161366d565b915050611041565b5092915050565b6000828152600c602052604081206110d390836119ec565b9392505050565b6000918252600b602090815260408084206001600160a01b0393909316845291905290205460ff1690565b60006111216000805160206136f583398151915261053a6115b4565b61113d5760405162461bcd60e51b815260040161074a90613479565b60005b86518110156108985761119487828151811061116c57634e487b7160e01b600052603260045260246000fd5b6020026020010151878381518110610ee457634e487b7160e01b600052603260045260246000fd5b6111df8682815181106111b757634e487b7160e01b600052603260045260246000fd5b6020026020010151868381518110610f3c57634e487b7160e01b600052603260045260246000fd5b8381815181106111ff57634e487b7160e01b600052603260045260246000fd5b6020026020010151600d600088848151811061122b57634e487b7160e01b600052603260045260246000fd5b60200260200101518152602001908152602001600020908051906020019061125492919061249d565b5082818151811061127557634e487b7160e01b600052603260045260246000fd5b6020026020010151600e60008884815181106112a157634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002090805190602001906112ca929190612502565b50806112d58161366d565b915050611140565b6060600180546106a090613632565b600081565b6112f96115b4565b6001600160a01b0316826001600160a01b0316141561132a5760405162461bcd60e51b815260040161074a90612f7b565b80600560006113376115b4565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff19169215159290921790915561137b6115b4565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516113b39190612dab565b60405180910390a35050565b6113d06113ca6115b4565b83611749565b6113ec5760405162461bcd60e51b815260040161074a906133dc565b6113f8848484846119b0565b50505050565b6060610689826119f8565b6000818152600c6020526040812061068990611b11565b6000805160206136f583398151915281565b61143c8282611b1c565b6000828152600c602052604090206108029082611b44565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6000805b6000848152600e6020526040902054811015610e4b576114a46115b4565b6001600160a01b0316600d600086815260200190815260200160002082815481106114df57634e487b7160e01b600052603260045260246000fd5b6000918252602090912001546001600160a01b03161415611541576000848152600e6020526040902080548491908390811061152b57634e487b7160e01b600052603260045260246000fd5b60009182526020909120015550600190506109cf565b8061154b8161366d565b915050611486565b610a788282611b59565b60006110d3836001600160a01b038416611be0565b60006001600160e01b03198216635a05180f60e01b1480610689575061068982611c2a565b6000908152600260205260409020546001600160a01b0316151590565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906115ed82610f66565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6001600160a01b03821661164c5760405162461bcd60e51b815260040161074a906131e9565b61165581611597565b156116725760405162461bcd60e51b815260040161074a90612f00565b61167e60008383611c4f565b6001600160a01b03821660009081526003602052604081208054600192906116a79084906135c3565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b61170e82611597565b61172a5760405162461bcd60e51b815260040161074a9061313e565b6000828152600a6020908152604090912082516108029284019061253d565b600061175482611597565b6117705760405162461bcd60e51b815260040161074a90612fb2565b600061177b83610f66565b9050806001600160a01b0316846001600160a01b031614806117b65750836001600160a01b03166117ab84610723565b6001600160a01b0316145b806117c657506117c68185611454565b949350505050565b826001600160a01b03166117e182610f66565b6001600160a01b0316146118075760405162461bcd60e51b815260040161074a90613303565b6001600160a01b03821661182d5760405162461bcd60e51b815260040161074a90612f37565b611838838383611c4f565b6118436000826115b8565b6001600160a01b038316600090815260036020526040812080546001929061186c9084906135ef565b90915550506001600160a01b038216600090815260036020526040812080546001929061189a9084906135c3565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b61190f61190783610949565b61053a6115b4565b6115535760405162461bcd60e51b815260040161074a90612e14565b61193582826110da565b15610a78576000828152600b602090815260408083206001600160a01b03851684529091529020805460ff1916905561196c6115b4565b6001600160a01b0316816001600160a01b0316837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45050565b6119bb8484846117ce565b6119c784848484611c5a565b6113f85760405162461bcd60e51b815260040161074a90612eae565b610da181611d6a565b60006110d38383611daa565b6060611a0382611597565b611a1f5760405162461bcd60e51b815260040161074a9061321e565b6000828152600a602052604081208054611a3890613632565b80601f0160208091040260200160405190810160405280929190818152602001828054611a6490613632565b8015611ab15780601f10611a8657610100808354040283529160200191611ab1565b820191906000526020600020905b815481529060010190602001808311611a9457829003601f168201915b505050505090506000611ac2611e03565b9050805160001415611ad65750905061068c565b815115611b08578082604051602001611af0929190612ca6565b6040516020818303038152906040529250505061068c565b6117c684611e15565b600061068982611e97565b611b2861190783610949565b610a6e5760405162461bcd60e51b815260040161074a90612ffe565b60006110d3836001600160a01b038416611e9b565b611b6382826110da565b610a78576000828152600b602090815260408083206001600160a01b03851684529091529020805460ff19166001179055611b9c6115b4565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000611bec8383611fb8565b611c22575081546001818101845560008481526020808220909301849055845484825282860190935260409020919091556109cf565b5060006109cf565b60006001600160e01b03198216637965db0b60e01b1480610689575061068982611fd0565b610802838383611ff5565b6000611c6e846001600160a01b031661207e565b15610f5b57836001600160a01b031663150b7a02611c8a6115b4565b8786866040518563ffffffff1660e01b8152600401611cac9493929190612ce9565b602060405180830381600087803b158015611cc657600080fd5b505af1925050508015611cf6575060408051601f3d908101601f19168201909252611cf391810190612c5e565b60015b611d50573d808015611d24576040519150601f19603f3d011682016040523d82523d6000602084013e611d29565b606091505b508051611d485760405162461bcd60e51b815260040161074a90612eae565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506117c6565b611d7381612084565b6000818152600a602052604090208054611d8c90613632565b159050610da1576000818152600a60205260408120610da1916125b0565b81546000908210611dcd5760405162461bcd60e51b815260040161074a90612dd2565b826000018281548110611df057634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905092915050565b60408051602081019091526000815290565b6060611e2082611597565b611e3c5760405162461bcd60e51b815260040161074a9061334c565b6000611e46611e03565b90506000815111611e6657604051806020016040528060008152506110d3565b80611e708461212b565b604051602001611e81929190612ca6565b6040516020818303038152906040529392505050565b5490565b60008181526001830160205260408120548015611fae576000611ebf6001836135ef565b8554909150600090611ed3906001906135ef565b90506000866000018281548110611efa57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905080876000018481548110611f2b57634e487b7160e01b600052603260045260246000fd5b600091825260209091200155611f428360016135c3565b60008281526001890160205260409020558654879080611f7257634e487b7160e01b600052603160045260246000fd5b600190038181906000526020600020016000905590558660010160008781526020019081526020016000206000905560019450505050506109cf565b60009150506109cf565b60009081526001919091016020526040902054151590565b60006001600160e01b0319821663780e9d6360e01b1480610689575061068982612246565b612000838383610802565b6001600160a01b03831661201c5761201781612286565b61203f565b816001600160a01b0316836001600160a01b03161461203f5761203f83826122ca565b6001600160a01b03821661205b5761205681612367565b610802565b826001600160a01b0316826001600160a01b031614610802576108028282612440565b3b151590565b600061208f82610f66565b905061209d81600084611c4f565b6120a86000836115b8565b6001600160a01b03811660009081526003602052604081208054600192906120d19084906135ef565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b60608161215057506040805180820190915260018152600360fc1b602082015261068c565b8160005b811561217a57806121648161366d565b91506121739050600a836135db565b9150612154565b60008167ffffffffffffffff8111156121a357634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156121cd576020820181803683370190505b5090505b84156117c6576121e26001836135ef565b91506121ef600a86613688565b6121fa9060306135c3565b60f81b81838151811061221d57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535061223f600a866135db565b94506121d1565b60006001600160e01b031982166380ac58cd60e01b148061227757506001600160e01b03198216635b5e139f60e01b145b80610689575061068982612484565b600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b600060016122d784610f9b565b6122e191906135ef565b600083815260076020526040902054909150808214612334576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090612379906001906135ef565b600083815260096020526040812054600880549394509092849081106123af57634e487b7160e01b600052603260045260246000fd5b9060005260206000200154905080600883815481106123de57634e487b7160e01b600052603260045260246000fd5b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061242457634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905550505050565b600061244b83610f9b565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160e01b031981166301ffc9a760e01b14919050565b8280548282559060005260206000209081019282156124f2579160200282015b828111156124f257825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906124bd565b506124fe9291506125e8565b5090565b8280548282559060005260206000209081019282156124f2579160200282015b828111156124f2578251825591602001919060010190612522565b82805461254990613632565b90600052602060002090601f01602090048101928261256b57600085556124f2565b82601f1061258457805160ff19168380011785556124f2565b828001600101855582156124f257918201828111156124f2578251825591602001919060010190612522565b5080546125bc90613632565b6000825580601f106125ce5750610da1565b601f016020900490600052602060002090810190610da191905b5b808211156124fe57600081556001016125e9565b600067ffffffffffffffff831115612617576126176136c8565b61262a601f8401601f1916602001613575565b905082815283838301111561263e57600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b038116811461068c57600080fd5b600082601f83011261267c578081fd5b8135602061269161268c8361359f565b613575565b82815281810190858301838502870184018810156126ad578586fd5b855b858110156126d2576126c082612655565b845292840192908401906001016126af565b5090979650505050505050565b600082601f8301126126ef578081fd5b813560206126ff61268c8361359f565b82815281810190858301855b858110156126d257612722898684358b010161266c565b8452928401929084019060010161270b565b600082601f830112612744578081fd5b8135602061275461268c8361359f565b82815281810190858301855b858110156126d257612777898684358b01016127de565b84529284019290840190600101612760565b600082601f830112612799578081fd5b813560206127a961268c8361359f565b82815281810190858301855b858110156126d2576127cc898684358b0101612838565b845292840192908401906001016127b5565b600082601f8301126127ee578081fd5b813560206127fe61268c8361359f565b828152818101908583018385028701840188101561281a578586fd5b855b858110156126d25781358452928401929084019060010161281c565b600082601f830112612848578081fd5b6110d3838335602085016125fd565b600060208284031215612868578081fd5b6110d382612655565b60008060408385031215612883578081fd5b61288c83612655565b915061289a60208401612655565b90509250929050565b6000806000606084860312156128b7578081fd5b6128c084612655565b92506128ce60208501612655565b9150604084013590509250925092565b600080600080608085870312156128f3578182fd5b6128fc85612655565b935061290a60208601612655565b925060408501359150606085013567ffffffffffffffff81111561292c578182fd5b8501601f8101871361293c578182fd5b61294b878235602084016125fd565b91505092959194509250565b60008060408385031215612969578182fd5b61297283612655565b915060208301358015158114612986578182fd5b809150509250929050565b600080604083850312156129a3578182fd5b6129ac83612655565b946020939093013593505050565b6000806000606084860312156129ce578081fd5b6129d784612655565b925060208401359150604084013567ffffffffffffffff8111156129f9578182fd5b612a0586828701612838565b9150509250925092565b600080600080600060a08688031215612a26578283fd5b612a2f86612655565b945060208601359350604086013567ffffffffffffffff80821115612a52578485fd5b612a5e89838a01612838565b94506060880135915080821115612a73578283fd5b612a7f89838a0161266c565b93506080880135915080821115612a94578283fd5b50612aa1888289016127de565b9150509295509295909350565b600080600060608486031215612ac2578081fd5b833567ffffffffffffffff80821115612ad9578283fd5b612ae58783880161266c565b94506020860135915080821115612afa578283fd5b612b06878388016127de565b93506040860135915080821115612b1b578283fd5b50612a0586828701612789565b600080600080600060a08688031215612b3f578283fd5b853567ffffffffffffffff80821115612b56578485fd5b612b6289838a0161266c565b96506020880135915080821115612b77578485fd5b612b8389838a016127de565b95506040880135915080821115612b98578485fd5b612ba489838a01612789565b94506060880135915080821115612bb9578283fd5b612bc589838a016126df565b93506080880135915080821115612bda578283fd5b50612aa188828901612734565b600060208284031215612bf8578081fd5b5035919050565b60008060408385031215612c11578182fd5b8235915061289a60208401612655565b60008060408385031215612c33578182fd5b50508035926020909101359150565b600060208284031215612c53578081fd5b81356110d3816136de565b600060208284031215612c6f578081fd5b81516110d3816136de565b60008151808452612c92816020860160208601613606565b601f01601f19169290920160200192915050565b60008351612cb8818460208801613606565b835190830190612ccc818360208801613606565b01949350505050565b6001600160a01b0391909116815260200190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612d1c90830184612c7a565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612d675783516001600160a01b031683529284019291840191600101612d42565b50909695505050505050565b6020808252825182820181905260009190848201906040850190845b81811015612d6757835183529284019291840191600101612d8f565b901515815260200190565b90815260200190565b6000602082526110d36020830184612c7a565b60208082526022908201527f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e604082015261647360f01b606082015260800190565b6020808252602f908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526e0818591b5a5b881d1bc819dc985b9d608a1b606082015260800190565b6020808252602b908201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560408201526a74206f6620626f756e647360a81b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252601c908201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604082015260600190565b60208082526024908201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526019908201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604082015260600190565b6020808252602c908201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b60208082526030908201527f416363657373436f6e74726f6c3a2073656e646572206d75737420626520616e60408201526f2061646d696e20746f207265766f6b6560801b606082015260800190565b60208082526038908201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760408201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606082015260800190565b6020808252602a908201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604082015269726f206164647265737360b01b606082015260800190565b60208082526029908201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460408201526832b73a103a37b5b2b760b91b606082015260800190565b6020808252602e908201527f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60408201526d32bc34b9ba32b73a103a37b5b2b760911b606082015260800190565b60208082526037908201527f56616c75652073686f756c642062652067726561746572207468616e206f722060408201527f657175616c20746f20636173686261636b2076616c7565000000000000000000606082015260800190565b6020808252818101527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b60208082526031908201527f45524337323155524953746f726167653a2055524920717565727920666f72206040820152703737b732bc34b9ba32b73a103a37b5b2b760791b606082015260800190565b6020808252602c908201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b60208082526028908201527f436173686261636b546f6b656e2073686f756c64206265206f6620636173686260408201526761636b207479706560c01b606082015260800190565b60208082526029908201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960408201526839903737ba1037bbb760b91b606082015260800190565b6020808252602f908201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60408201526e3732bc34b9ba32b73a103a37b5b2b760891b606082015260800190565b60208082526021908201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656040820152603960f91b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252602c908201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60408201526b7574206f6620626f756e647360a01b606082015260800190565b6020808252603d908201527f4552433732315072657365744d696e7465725061757365724175746f49643a2060408201527f6d7573742068617665206d696e74657220726f6c6520746f206d696e74000000606082015260800190565b60208082526030908201527f4552433732314275726e61626c653a2063616c6c6572206973206e6f74206f7760408201526f1b995c881b9bdc88185c1c1c9bdd995960821b606082015260800190565b6020808252602f908201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560408201526e103937b632b9903337b91039b2b63360891b606082015260800190565b60405181810167ffffffffffffffff81118282101715613597576135976136c8565b604052919050565b600067ffffffffffffffff8211156135b9576135b96136c8565b5060209081020190565b600082198211156135d6576135d661369c565b500190565b6000826135ea576135ea6136b2565b500490565b6000828210156136015761360161369c565b500390565b60005b83811015613621578181015183820152602001613609565b838111156113f85750506000910152565b60028104600182168061364657607f821691505b6020821081141561366757634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156136815761368161369c565b5060010190565b600082613697576136976136b2565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114610da157600080fdfe9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6a26469706673582212206759dfe3175285406dc33dc120b9f60db93503947770c126a83051d81cdee18e64736f6c63430008000033

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

00000000000000000000000000000000000000000000000000000000000000400000000000000000000000000000000000000000000000000000000000000080000000000000000000000000000000000000000000000000000000000000000f4552433732315f5354414e444152440000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000f4552433732315f5354414e444152440000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : name_ (string): ERC721_STANDARD
Arg [1] : symbol_ (string): ERC721_STANDARD

-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000080
Arg [2] : 000000000000000000000000000000000000000000000000000000000000000f
Arg [3] : 4552433732315f5354414e444152440000000000000000000000000000000000
Arg [4] : 000000000000000000000000000000000000000000000000000000000000000f
Arg [5] : 4552433732315f5354414e444152440000000000000000000000000000000000


Deployed Bytecode Sourcemap

61474:6395:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62703:219;;;;;;;;;;-1:-1:-1;62703:219:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;21594:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;23061:221::-;;;;;;;;;;-1:-1:-1;23061:221:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;22591:404::-;;;;;;;;;;-1:-1:-1;22591:404:0;;;;;:::i;:::-;;:::i;:::-;;34278:113;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;65467:631::-;;;;;;;;;;-1:-1:-1;65467:631:0;;;;;:::i;:::-;;:::i;63283:161::-;;;;;;;;;;-1:-1:-1;63283:161:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;23951:305::-;;;;;;;;;;-1:-1:-1;23951:305:0;;;;;:::i;:::-;;:::i;45725:123::-;;;;;;;;;;-1:-1:-1;45725:123:0;;;;;:::i;:::-;;:::i;60745:165::-;;;;;;;;;;-1:-1:-1;60745:165:0;;;;;:::i;:::-;;:::i;33618:256::-;;;;;;;;;;-1:-1:-1;33618:256:0;;;;;:::i;:::-;;:::i;63122:153::-;;;;;;;;;;-1:-1:-1;63122:153:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;47329:218::-;;;;;;;;;;-1:-1:-1;47329:218:0;;;;;:::i;:::-;;:::i;66396:1470::-;;;;;;:::i;:::-;;:::i;24327:151::-;;;;;;;;;;-1:-1:-1;24327:151:0;;;;;:::i;:::-;;:::i;66106:282::-;;;;;;;;;;-1:-1:-1;66106:282:0;;;;;:::i;:::-;;:::i;34468:233::-;;;;;;;;;;-1:-1:-1;34468:233:0;;;;;:::i;:::-;;:::i;62313:382::-;;;;;;;;;;-1:-1:-1;62313:382:0;;;;;:::i;:::-;;:::i;63842:480::-;;;;;;;;;;-1:-1:-1;63842:480:0;;;;;:::i;:::-;;:::i;21288:239::-;;;;;;;;;;-1:-1:-1;21288:239:0;;;;;:::i;:::-;;:::i;21018:208::-;;;;;;;;;;-1:-1:-1;21018:208:0;;;;;:::i;:::-;;:::i;33882:320::-;;;;;;;;;;-1:-1:-1;33882:320:0;;;;;:::i;:::-;;:::i;60200:145::-;;;;;;;;;;-1:-1:-1;60200:145:0;;;;;:::i;:::-;;:::i;45397:139::-;;;;;;;;;;-1:-1:-1;45397:139:0;;;;;:::i;:::-;;:::i;64747:712::-;;;;;;;;;;-1:-1:-1;64747:712:0;;;;;:::i;:::-;;:::i;21763:104::-;;;;;;;;;;;;;:::i;43853:49::-;;;;;;;;;;;;;:::i;23354:295::-;;;;;;;;;;-1:-1:-1;23354:295:0;;;;;:::i;:::-;;:::i;24549:285::-;;;;;;;;;;-1:-1:-1;24549:285:0;;;;;:::i;:::-;;:::i;62930:184::-;;;;;;;;;;-1:-1:-1;62930:184:0;;;;;:::i;:::-;;:::i;60519:134::-;;;;;;;;;;-1:-1:-1;60519:134:0;;;;;:::i;:::-;;:::i;61566:62::-;;;;;;;;;;;;;:::i;61003:170::-;;;;;;;;;;-1:-1:-1;61003:170:0;;;;;:::i;:::-;;:::i;23720:164::-;;;;;;;;;;-1:-1:-1;23720:164:0;;;;;:::i;:::-;;:::i;64330:409::-;;;;;;;;;;-1:-1:-1;64330:409:0;;;;;:::i;:::-;;:::i;62703:219::-;62849:4;62878:36;62902:11;62878:23;:36::i;:::-;62871:43;;62703:219;;;;:::o;21594:100::-;21648:13;21681:5;21674:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;21594:100;:::o;23061:221::-;23137:7;23165:16;23173:7;23165;:16::i;:::-;23157:73;;;;-1:-1:-1;;;23157:73:0;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;23250:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;23250:24:0;;23061:221::o;22591:404::-;22672:13;22688:23;22703:7;22688:14;:23::i;:::-;22672:39;;22736:5;-1:-1:-1;;;;;22730:11:0;:2;-1:-1:-1;;;;;22730:11:0;;;22722:57;;;;-1:-1:-1;;;22722:57:0;;;;;;;:::i;:::-;22816:5;-1:-1:-1;;;;;22800:21:0;:12;:10;:12::i;:::-;-1:-1:-1;;;;;22800:21:0;;:69;;;;22825:44;22849:5;22856:12;:10;:12::i;22825:44::-;22792:161;;;;-1:-1:-1;;;22792:161:0;;;;;;;:::i;:::-;22966:21;22975:2;22979:7;22966:8;:21::i;:::-;22591:404;;;:::o;34278:113::-;34366:10;:17;34278:113;:::o;65467:631::-;65679:4;65718:34;-1:-1:-1;;;;;;;;;;;65739:12:0;:10;:12::i;65718:34::-;65696:145;;;;-1:-1:-1;;;65696:145:0;;;;;;;:::i;:::-;65852:18;65858:2;65862:7;65852:5;:18::i;:::-;65881:26;65894:7;65903:3;65881:12;:26::i;:::-;65967:28;;;;:19;:28;;;;;;;;:49;;;;;;;;:::i;:::-;-1:-1:-1;66027:24:0;;;;:15;:24;;;;;;;;:41;;;;;;;;:::i;:::-;-1:-1:-1;66086:4:0;;65467:631;-1:-1:-1;;;;;;65467:631:0:o;63283:161::-;63408:28;;;;:19;:28;;;;;;;;;63401:35;;;;;;;;;;;;;;;;;63367:16;;63401:35;;;63408:28;63401:35;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;63401:35:0;;;;;;;;;;;;;;;;;;;;;;;63283:161;;;:::o;23951:305::-;24112:41;24131:12;:10;:12::i;:::-;24145:7;24112:18;:41::i;:::-;24104:103;;;;-1:-1:-1;;;24104:103:0;;;;;;;:::i;:::-;24220:28;24230:4;24236:2;24240:7;24220:9;:28::i;45725:123::-;45791:7;45818:12;;;:6;:12;;;;;:22;;;;45725:123::o;60745:165::-;60830:30;60846:4;60852:7;60830:15;:30::i;:::-;60871:18;;;;:12;:18;;;;;:31;;60894:7;60871:22;:31::i;33618:256::-;33715:7;33751:23;33768:5;33751:16;:23::i;:::-;33743:5;:31;33735:87;;;;-1:-1:-1;;;33735:87:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;;33840:19:0;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;33618:256;;;;;:::o;63122:153::-;63243:24;;;;:15;:24;;;;;;;;;63236:31;;;;;;;;;;;;;;;;;63202:16;;63236:31;;;63243:24;63236:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63122:153;;;:::o;47329:218::-;47436:12;:10;:12::i;:::-;-1:-1:-1;;;;;47425:23:0;:7;-1:-1:-1;;;;;47425:23:0;;47417:83;;;;-1:-1:-1;;;47417:83:0;;;;;;;:::i;:::-;47513:26;47525:4;47531:7;47513:11;:26::i;:::-;47329:218;;:::o;66396:1470::-;66477:28;;;;:19;:28;;;;;:35;:40;66473:1386;;66632:28;;;;:19;:28;;;;;:35;66606:142;;;;-1:-1:-1;;;66606:142:0;;;;;;;:::i;:::-;66763:11;66798:9;66793:131;66817:24;;;;:15;:24;;;;;:31;66813:35;;66793:131;;;66881:24;;;;:15;:24;;;;;:27;;66906:1;;66881:27;;;;-1:-1:-1;;;66881:27:0;;;;;;;;;;;;;;;;;66874:34;;;;;:::i;:::-;;-1:-1:-1;66850:3:0;;;;:::i;:::-;;;;66793:131;;;;66948:9;66942:3;:15;66938:179;;;66978:39;;66986:10;;67007:9;66978:39;;;;;;;;;67007:9;66986:10;66978:39;;;;;;;;;;;;;;;;;;;;;67036:65;;-1:-1:-1;;;67036:65:0;;;;;;;:::i;66938:179::-;67136:9;67131:359;67155:28;;;;:19;:28;;;;;:35;67151:39;;67131:359;;;67303:1;67273:24;;;:15;:24;;;;;:27;;67298:1;;67273:27;;;;-1:-1:-1;;;67273:27:0;;;;;;;;;;;;;;;;;:31;67269:206;;;67337:28;;;;:19;:28;;;;;:31;;67366:1;;67337:31;;;;-1:-1:-1;;;67337:31:0;;;;;;;;;;;;;;;;;;;;;67405:24;;;:15;:24;;;;;;;:27;;-1:-1:-1;;;;;67337:31:0;;;;67329:126;;67405:24;67430:1;;67405:27;;;;-1:-1:-1;;;67405:27:0;;;;;;;;;;;;;;;;;67329:126;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67269:206;67192:3;;;;:::i;:::-;;;;67131:359;;;;67520:3;67508:9;:15;67504:101;;;67552:10;67544:45;67573:15;67585:3;67573:9;:15;:::i;:::-;67544:45;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67504:101;67619:44;67633:12;:10;:12::i;:::-;67647:2;67651:7;67619:44;;;;;;;;;;;;:13;:44::i;:::-;66473:1386;;;;67700:9;:13;67696:93;;67734:39;;67742:10;;67763:9;67734:39;;;;;;;;;67763:9;67742:10;67734:39;;;;;;;;;;;;;;;;;;;;;67696:93;67803:44;67817:12;:10;:12::i;:::-;67831:2;67835:7;67803:44;;;;;;;;;;;;:13;:44::i;24327:151::-;24431:39;24448:4;24454:2;24458:7;24431:39;;;;;;;;;;;;:16;:39::i;66106:282::-;66238:41;66257:12;:10;:12::i;66238:41::-;66216:139;;;;-1:-1:-1;;;66216:139:0;;;;;;;:::i;:::-;66366:14;66372:7;66366:5;:14::i;:::-;66106:282;:::o;34468:233::-;34543:7;34579:30;:28;:30::i;:::-;34571:5;:38;34563:95;;;;-1:-1:-1;;;34563:95:0;;;;;;;:::i;:::-;34676:10;34687:5;34676:17;;;;;;-1:-1:-1;;;34676:17:0;;;;;;;;;;;;;;;;;34669:24;;34468:233;;;:::o;62313:382::-;62437:4;62476:34;-1:-1:-1;;;;;;;;;;;62497:12:0;:10;:12::i;62476:34::-;62454:145;;;;-1:-1:-1;;;62454:145:0;;;;;;;:::i;:::-;62610:18;62616:2;62620:7;62610:5;:18::i;:::-;62639:26;62652:7;62661:3;62639:12;:26::i;:::-;-1:-1:-1;62683:4:0;62313:382;;;;;:::o;63842:480::-;63982:4;64021:34;-1:-1:-1;;;;;;;;;;;64042:12:0;:10;:12::i;64021:34::-;63999:145;;;;-1:-1:-1;;;63999:145:0;;;;;;;:::i;:::-;64160:9;64155:138;64179:2;:9;64175:1;:13;64155:138;;;64210:24;64216:2;64219:1;64216:5;;;;;;-1:-1:-1;;;64216:5:0;;;;;;;;;;;;;;;64223:7;64231:1;64223:10;;;;;;-1:-1:-1;;;64223:10:0;;;;;;;;;;;;;;;64210:5;:24::i;:::-;64249:32;64262:7;64270:1;64262:10;;;;;;-1:-1:-1;;;64262:10:0;;;;;;;;;;;;;;;64274:3;64278:1;64274:6;;;;;;-1:-1:-1;;;64274:6:0;;;;;;;;;;;;;;;64249:12;:32::i;:::-;64190:3;;;;:::i;:::-;;;;64155:138;;;-1:-1:-1;64310:4:0;;63842:480;-1:-1:-1;;;;63842:480:0:o;21288:239::-;21360:7;21396:16;;;:7;:16;;;;;;-1:-1:-1;;;;;21396:16:0;21431:19;21423:73;;;;-1:-1:-1;;;21423:73:0;;;;;;;:::i;21018:208::-;21090:7;-1:-1:-1;;;;;21118:19:0;;21110:74;;;;-1:-1:-1;;;21110:74:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;;21202:16:0;;;;;:9;:16;;;;;;;21018:208::o;33882:320::-;33941:16;33970:28;34015:23;34032:5;34015:16;:23::i;:::-;34001:38;;;;;;-1:-1:-1;;;34001:38:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;34001:38:0;;33970:69;;34054:6;34050:116;34070:23;34087:5;34070:16;:23::i;:::-;34066:1;:27;34050:116;;;-1:-1:-1;;;;;34132:19:0;;;;;;:12;:19;;;;;;;;:22;;;;;;;;;34115:14;;:11;;34152:1;;34115:14;;;;-1:-1:-1;;;34115:14:0;;;;;;;;;;;;;;;;;;:39;34095:3;;;;:::i;:::-;;;;34050:116;;;-1:-1:-1;34183:11:0;33882:320;-1:-1:-1;;33882:320:0:o;60200:145::-;60282:7;60309:18;;;:12;:18;;;;;:28;;60331:5;60309:21;:28::i;:::-;60302:35;60200:145;-1:-1:-1;;;60200:145:0:o;45397:139::-;45475:4;45499:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;45499:29:0;;;;;;;;;;;;;;;45397:139::o;64747:712::-;64987:4;65026:34;-1:-1:-1;;;;;;;;;;;65047:12:0;:10;:12::i;65026:34::-;65004:145;;;;-1:-1:-1;;;65004:145:0;;;;;;;:::i;:::-;65165:9;65160:270;65184:2;:9;65180:1;:13;65160:270;;;65215:24;65221:2;65224:1;65221:5;;;;;;-1:-1:-1;;;65221:5:0;;;;;;;;;;;;;;;65228:7;65236:1;65228:10;;;;;;-1:-1:-1;;;65228:10:0;;;;;;;;65215:24;65254:32;65267:7;65275:1;65267:10;;;;;;-1:-1:-1;;;65267:10:0;;;;;;;;;;;;;;;65279:3;65283:1;65279:6;;;;;;-1:-1:-1;;;65279:6:0;;;;;;;;65254:32;65335:18;65354:1;65335:21;;;;;;-1:-1:-1;;;65335:21:0;;;;;;;;;;;;;;;65301:19;:31;65321:7;65329:1;65321:10;;;;;;-1:-1:-1;;;65321:10:0;;;;;;;;;;;;;;;65301:31;;;;;;;;;;;:55;;;;;;;;;;;;:::i;:::-;;65401:14;65416:1;65401:17;;;;;;-1:-1:-1;;;65401:17:0;;;;;;;;;;;;;;;65371:15;:27;65387:7;65395:1;65387:10;;;;;;-1:-1:-1;;;65387:10:0;;;;;;;;;;;;;;;65371:27;;;;;;;;;;;:47;;;;;;;;;;;;:::i;:::-;-1:-1:-1;65195:3:0;;;;:::i;:::-;;;;65160:270;;21763:104;21819:13;21852:7;21845:14;;;;;:::i;43853:49::-;43898:4;43853:49;:::o;23354:295::-;23469:12;:10;:12::i;:::-;-1:-1:-1;;;;;23457:24:0;:8;-1:-1:-1;;;;;23457:24:0;;;23449:62;;;;-1:-1:-1;;;23449:62:0;;;;;;;:::i;:::-;23569:8;23524:18;:32;23543:12;:10;:12::i;:::-;-1:-1:-1;;;;;23524:32:0;;;;;;;;;;;;;;;;;-1:-1:-1;23524:32:0;;;:42;;;;;;;;;;;;:53;;-1:-1:-1;;23524:53:0;;;;;;;;;;;23608:12;:10;:12::i;:::-;-1:-1:-1;;;;;23593:48:0;;23632:8;23593:48;;;;;;:::i;:::-;;;;;;;;23354:295;;:::o;24549:285::-;24681:41;24700:12;:10;:12::i;:::-;24714:7;24681:18;:41::i;:::-;24673:103;;;;-1:-1:-1;;;24673:103:0;;;;;;;:::i;:::-;24787:39;24801:4;24807:2;24811:7;24820:5;24787:13;:39::i;:::-;24549:285;;;;:::o;62930:184::-;63034:13;63072:34;63098:7;63072:25;:34::i;60519:134::-;60591:7;60618:18;;;:12;:18;;;;;:27;;:25;:27::i;61566:62::-;-1:-1:-1;;;;;;;;;;;61566:62:0;:::o;61003:170::-;61089:31;61106:4;61112:7;61089:16;:31::i;:::-;61131:18;;;;:12;:18;;;;;:34;;61157:7;61131:25;:34::i;23720:164::-;-1:-1:-1;;;;;23841:25:0;;;23817:4;23841:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;23720:164::o;64330:409::-;64444:4;;64461:249;64485:24;;;;:15;:24;;;;;:31;64481:35;;64461:249;;;64577:12;:10;:12::i;:::-;-1:-1:-1;;;;;64542:47:0;:19;:28;64562:7;64542:28;;;;;;;;;;;64571:1;64542:31;;;;;;-1:-1:-1;;;64542:31:0;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;64542:31:0;:47;64538:161;;;64610:24;;;;:15;:24;;;;;:27;;64640:13;;64610:24;64635:1;;64610:27;;;;-1:-1:-1;;;64610:27:0;;;;;;;;;;;;;;;;;;:43;-1:-1:-1;64679:4:0;;-1:-1:-1;64672:11:0;;64538:161;64518:3;;;;:::i;:::-;;;;64461:249;;48130:112;48209:25;48220:4;48226:7;48209:10;:25::i;55612:152::-;55682:4;55706:50;55711:3;-1:-1:-1;;;;;55731:23:0;;55706:4;:50::i;59374:227::-;59459:4;-1:-1:-1;;;;;;59483:57:0;;-1:-1:-1;;;59483:57:0;;:110;;;59557:36;59581:11;59557:23;:36::i;26301:127::-;26366:4;26390:16;;;:7;:16;;;;;;-1:-1:-1;;;;;26390:16:0;:30;;;26301:127::o;16234:98::-;16314:10;16234:98;:::o;30186:174::-;30261:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;30261:29:0;-1:-1:-1;;;;;30261:29:0;;;;;;;;:24;;30315:23;30261:24;30315:14;:23::i;:::-;-1:-1:-1;;;;;30306:46:0;;;;;;;;;;;30186:174;;:::o;28216:382::-;-1:-1:-1;;;;;28296:16:0;;28288:61;;;;-1:-1:-1;;;28288:61:0;;;;;;;:::i;:::-;28369:16;28377:7;28369;:16::i;:::-;28368:17;28360:58;;;;-1:-1:-1;;;28360:58:0;;;;;;;:::i;:::-;28431:45;28460:1;28464:2;28468:7;28431:20;:45::i;:::-;-1:-1:-1;;;;;28489:13:0;;;;;;:9;:13;;;;;:18;;28506:1;;28489:13;:18;;28506:1;;28489:18;:::i;:::-;;;;-1:-1:-1;;28518:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;28518:21:0;-1:-1:-1;;;;;28518:21:0;;;;;;;;28557:33;;28518:16;;;28557:33;;28518:16;;28557:33;28216:382;;:::o;40906:217::-;41006:16;41014:7;41006;:16::i;:::-;40998:75;;;;-1:-1:-1;;;40998:75:0;;;;;;;:::i;:::-;41084:19;;;;:10;:19;;;;;;;;:31;;;;;;;;:::i;26595:355::-;26688:4;26713:16;26721:7;26713;:16::i;:::-;26705:73;;;;-1:-1:-1;;;26705:73:0;;;;;;;:::i;:::-;26789:13;26805:23;26820:7;26805:14;:23::i;:::-;26789:39;;26858:5;-1:-1:-1;;;;;26847:16:0;:7;-1:-1:-1;;;;;26847:16:0;;:51;;;;26891:7;-1:-1:-1;;;;;26867:31:0;:20;26879:7;26867:11;:20::i;:::-;-1:-1:-1;;;;;26867:31:0;;26847:51;:94;;;;26902:39;26926:5;26933:7;26902:23;:39::i;:::-;26839:103;26595:355;-1:-1:-1;;;;26595:355:0:o;29524:544::-;29649:4;-1:-1:-1;;;;;29622:31:0;:23;29637:7;29622:14;:23::i;:::-;-1:-1:-1;;;;;29622:31:0;;29614:85;;;;-1:-1:-1;;;29614:85:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;29718:16:0;;29710:65;;;;-1:-1:-1;;;29710:65:0;;;;;;;:::i;:::-;29788:39;29809:4;29815:2;29819:7;29788:20;:39::i;:::-;29892:29;29909:1;29913:7;29892:8;:29::i;:::-;-1:-1:-1;;;;;29934:15:0;;;;;;:9;:15;;;;;:20;;29953:1;;29934:15;:20;;29953:1;;29934:20;:::i;:::-;;;;-1:-1:-1;;;;;;;29965:13:0;;;;;;:9;:13;;;;;:18;;29982:1;;29965:13;:18;;29982:1;;29965:18;:::i;:::-;;;;-1:-1:-1;;29994:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;29994:21:0;-1:-1:-1;;;;;29994:21:0;;;;;;;;;30033:27;;29994:16;;30033:27;;;;;;;29524:544;;;:::o;46110:232::-;46203:41;46211:18;46224:4;46211:12;:18::i;:::-;46231:12;:10;:12::i;46203:41::-;46195:101;;;;-1:-1:-1;;;46195:101:0;;;;;;;:::i;48814:230::-;48889:22;48897:4;48903:7;48889;:22::i;:::-;48885:152;;;48960:5;48928:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;48928:29:0;;;;;;;;;:37;;-1:-1:-1;;48928:37:0;;;49012:12;:10;:12::i;:::-;-1:-1:-1;;;;;48985:40:0;49003:7;-1:-1:-1;;;;;48985:40:0;48997:4;48985:40;;;;;;;;;;48814:230;;:::o;25716:272::-;25830:28;25840:4;25846:2;25850:7;25830:9;:28::i;:::-;25877:48;25900:4;25906:2;25910:7;25919:5;25877:22;:48::i;:::-;25869:111;;;;-1:-1:-1;;;25869:111:0;;;;;;;:::i;63683:151::-;63795:31;63818:7;63795:22;:31::i;56898:158::-;56972:7;57023:22;57027:3;57039:5;57023:3;:22::i;40071:679::-;40144:13;40178:16;40186:7;40178;:16::i;:::-;40170:78;;;;-1:-1:-1;;;40170:78:0;;;;;;;:::i;:::-;40261:23;40287:19;;;:10;:19;;;;;40261:45;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40317:18;40338:10;:8;:10::i;:::-;40317:31;;40430:4;40424:18;40446:1;40424:23;40420:72;;;-1:-1:-1;40471:9:0;-1:-1:-1;40464:16:0;;40420:72;40596:23;;:27;40592:108;;40671:4;40677:9;40654:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;40640:48;;;;;;40592:108;40719:23;40734:7;40719:14;:23::i;56437:117::-;56500:7;56527:19;56535:3;56527:7;:19::i;46587:235::-;46681:41;46689:18;46702:4;46689:12;:18::i;46681:41::-;46673:102;;;;-1:-1:-1;;;46673:102:0;;;;;;;:::i;55940:158::-;56013:4;56037:53;56045:3;-1:-1:-1;;;;;56065:23:0;;56037:7;:53::i;48577:229::-;48652:22;48660:4;48666:7;48652;:22::i;:::-;48647:152;;48691:12;;;;:6;:12;;;;;;;;-1:-1:-1;;;;;48691:29:0;;;;;;;;;:36;;-1:-1:-1;;48691:36:0;48723:4;48691:36;;;48774:12;:10;:12::i;:::-;-1:-1:-1;;;;;48747:40:0;48765:7;-1:-1:-1;;;;;48747:40:0;48759:4;48747:40;;;;;;;;;;48577:229;;:::o;50676:414::-;50739:4;50761:21;50771:3;50776:5;50761:9;:21::i;:::-;50756:327;;-1:-1:-1;50799:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;50982:18;;50960:19;;;:12;;;:19;;;;;;:40;;;;51015:11;;50756:327;-1:-1:-1;51066:5:0;51059:12;;45088:217;45173:4;-1:-1:-1;;;;;;45197:47:0;;-1:-1:-1;;;45197:47:0;;:100;;;45261:36;45285:11;45261:23;:36::i;63452:223::-;63622:45;63649:4;63655:2;63659:7;63622:26;:45::i;30925:843::-;31046:4;31072:15;:2;-1:-1:-1;;;;;31072:13:0;;:15::i;:::-;31068:693;;;31124:2;-1:-1:-1;;;;;31108:36:0;;31145:12;:10;:12::i;:::-;31159:4;31165:7;31174:5;31108:72;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;31108:72:0;;;;;;;;-1:-1:-1;;31108:72:0;;;;;;;;;;;;:::i;:::-;;;31104:602;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;31354:13:0;;31350:341;;31397:60;;-1:-1:-1;;;31397:60:0;;;;;;;:::i;31350:341::-;31641:6;31635:13;31626:6;31622:2;31618:15;31611:38;31104:602;-1:-1:-1;;;;;;31231:55:0;-1:-1:-1;;;31231:55:0;;-1:-1:-1;31224:62:0;;41352:206;41421:20;41433:7;41421:11;:20::i;:::-;41464:19;;;;:10;:19;;;;;41458:33;;;;;:::i;:::-;:38;;-1:-1:-1;41454:97:0;;41520:19;;;;:10;:19;;;;;41513:26;;;:::i;53564:204::-;53659:18;;53631:7;;53659:26;-1:-1:-1;53651:73:0;;;;-1:-1:-1;;;53651:73:0;;;;;;;:::i;:::-;53742:3;:11;;53754:5;53742:18;;;;;;-1:-1:-1;;;53742:18:0;;;;;;;;;;;;;;;;;53735:25;;53564:204;;;;:::o;22435:94::-;22512:9;;;;;;;;;-1:-1:-1;22512:9:0;;22435:94;:::o;21938:360::-;22011:13;22045:16;22053:7;22045;:16::i;:::-;22037:76;;;;-1:-1:-1;;;22037:76:0;;;;;;;:::i;:::-;22126:21;22150:10;:8;:10::i;:::-;22126:34;;22202:1;22184:7;22178:21;:25;:112;;;;;;;;;;;;;;;;;22243:7;22252:18;:7;:16;:18::i;:::-;22226:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;22171:119;21938:360;-1:-1:-1;;;21938:360:0:o;53111:109::-;53194:18;;53111:109::o;51266:1544::-;51332:4;51471:19;;;:12;;;:19;;;;;;51507:15;;51503:1300;;51869:21;51893:14;51906:1;51893:10;:14;:::i;:::-;51942:18;;51869:38;;-1:-1:-1;51922:17:0;;51942:22;;51963:1;;51942:22;:::i;:::-;51922:42;;52209:17;52229:3;:11;;52241:9;52229:22;;;;;;-1:-1:-1;;;52229:22:0;;;;;;;;;;;;;;;;;52209:42;;52375:9;52346:3;:11;;52358:13;52346:26;;;;;;-1:-1:-1;;;52346:26:0;;;;;;;;;;;;;;;;;;:38;52478:17;:13;52494:1;52478:17;:::i;:::-;52452:23;;;;:12;;;:23;;;;;:43;52604:17;;52452:3;;52604:17;;;-1:-1:-1;;;52604:17:0;;;;;;;;;;;;;;;;;;;;;;;;;;52699:3;:12;;:19;52712:5;52699:19;;;;;;;;;;;52692:26;;;52742:4;52735:11;;;;;;;;51503:1300;52786:5;52779:12;;;;;52896:129;52969:4;52993:19;;;:12;;;;;:19;;;;;;:24;;;52896:129::o;33297:237::-;33399:4;-1:-1:-1;;;;;;33423:50:0;;-1:-1:-1;;;33423:50:0;;:103;;;33490:36;33514:11;33490:23;:36::i;35314:555::-;35424:45;35451:4;35457:2;35461:7;35424:26;:45::i;:::-;-1:-1:-1;;;;;35486:18:0;;35482:187;;35521:40;35553:7;35521:31;:40::i;:::-;35482:187;;;35591:2;-1:-1:-1;;;;;35583:10:0;:4;-1:-1:-1;;;;;35583:10:0;;35579:90;;35610:47;35643:4;35649:7;35610:32;:47::i;:::-;-1:-1:-1;;;;;35683:16:0;;35679:183;;35716:45;35753:7;35716:36;:45::i;:::-;35679:183;;;35789:4;-1:-1:-1;;;;;35783:10:0;:2;-1:-1:-1;;;;;35783:10:0;;35779:83;;35810:40;35838:2;35842:7;35810:27;:40::i;8434:422::-;8801:20;8840:8;;;8434:422::o;28827:360::-;28887:13;28903:23;28918:7;28903:14;:23::i;:::-;28887:39;;28939:48;28960:5;28975:1;28979:7;28939:20;:48::i;:::-;29028:29;29045:1;29049:7;29028:8;:29::i;:::-;-1:-1:-1;;;;;29070:16:0;;;;;;:9;:16;;;;;:21;;29090:1;;29070:16;:21;;29090:1;;29070:21;:::i;:::-;;;;-1:-1:-1;;29109:16:0;;;;:7;:16;;;;;;29102:23;;-1:-1:-1;;;;;;29102:23:0;;;29143:36;29117:7;;29109:16;-1:-1:-1;;;;;29143:36:0;;;;;29109:16;;29143:36;28827:360;;:::o;16806:723::-;16862:13;17083:10;17079:53;;-1:-1:-1;17110:10:0;;;;;;;;;;;;-1:-1:-1;;;17110:10:0;;;;;;17079:53;17157:5;17142:12;17198:78;17205:9;;17198:78;;17231:8;;;;:::i;:::-;;-1:-1:-1;17254:10:0;;-1:-1:-1;17262:2:0;17254:10;;:::i;:::-;;;17198:78;;;17286:19;17318:6;17308:17;;;;;;-1:-1:-1;;;17308:17:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;17308:17:0;;17286:39;;17336:154;17343:10;;17336:154;;17370:11;17380:1;17370:11;;:::i;:::-;;-1:-1:-1;17439:10:0;17447:2;17439:5;:10;:::i;:::-;17426:24;;:2;:24;:::i;:::-;17413:39;;17396:6;17403;17396:14;;;;;;-1:-1:-1;;;17396:14:0;;;;;;;;;;;;:56;-1:-1:-1;;;;;17396:56:0;;;;;;;;-1:-1:-1;17467:11:0;17476:2;17467:11;;:::i;:::-;;;17336:154;;20662:292;20764:4;-1:-1:-1;;;;;;20788:40:0;;-1:-1:-1;;;20788:40:0;;:105;;-1:-1:-1;;;;;;;20845:48:0;;-1:-1:-1;;;20845:48:0;20788:105;:158;;;;20910:36;20934:11;20910:23;:36::i;36592:164::-;36696:10;:17;;36669:24;;;;:15;:24;;;;;:44;;;36724:24;;;;;;;;;;;;36592:164::o;37383:988::-;37649:22;37699:1;37674:22;37691:4;37674:16;:22::i;:::-;:26;;;;:::i;:::-;37711:18;37732:26;;;:17;:26;;;;;;37649:51;;-1:-1:-1;37865:28:0;;;37861:328;;-1:-1:-1;;;;;37932:18:0;;37910:19;37932:18;;;:12;:18;;;;;;;;:34;;;;;;;;;37983:30;;;;;;:44;;;38100:30;;:17;:30;;;;;:43;;;37861:328;-1:-1:-1;38285:26:0;;;;:17;:26;;;;;;;;38278:33;;;-1:-1:-1;;;;;38329:18:0;;;;;:12;:18;;;;;:34;;;;;;;38322:41;37383:988::o;38666:1079::-;38944:10;:17;38919:22;;38944:21;;38964:1;;38944:21;:::i;:::-;38976:18;38997:24;;;:15;:24;;;;;;39370:10;:26;;38919:46;;-1:-1:-1;38997:24:0;;38919:46;;39370:26;;;;-1:-1:-1;;;39370:26:0;;;;;;;;;;;;;;;;;39348:48;;39434:11;39409:10;39420;39409:22;;;;;;-1:-1:-1;;;39409:22:0;;;;;;;;;;;;;;;;;;;;:36;;;;39514:28;;;:15;:28;;;;;;;:41;;;39686:24;;;;;39679:31;39721:10;:16;;;;;-1:-1:-1;;;39721:16:0;;;;;;;;;;;;;;;;;;;;;;;;;;38666:1079;;;;:::o;36170:221::-;36255:14;36272:20;36289:2;36272:16;:20::i;:::-;-1:-1:-1;;;;;36303:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;36348:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;36170:221:0:o;19263:157::-;-1:-1:-1;;;;;;19372:40:0;;-1:-1:-1;;;19372:40:0;19263:157;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:409:1;;114:18;106:6;103:30;100:2;;;136:18;;:::i;:::-;174:58;220:2;197:17;;-1:-1:-1;;193:31:1;226:4;189:42;174:58;:::i;:::-;165:67;;255:6;248:5;241:21;295:3;286:6;281:3;277:16;274:25;271:2;;;312:1;309;302:12;271:2;361:6;356:3;349:4;342:5;338:16;325:43;415:1;408:4;399:6;392:5;388:18;384:29;377:40;90:333;;;;;:::o;428:175::-;498:20;;-1:-1:-1;;;;;547:31:1;;537:42;;527:2;;593:1;590;583:12;608:713;;721:3;714:4;706:6;702:17;698:27;688:2;;743:5;736;729:20;688:2;783:6;770:20;809:4;833:65;848:49;894:2;848:49;:::i;:::-;833:65;:::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:171;1135:2;1132:1;1129:9;1121:171;;;1192:25;1213:3;1192:25;:::i;:::-;1180:38;;1238:12;;;;1270;;;;1153:1;1146:9;1121:171;;;-1:-1:-1;1310:5:1;;678:643;-1:-1:-1;;;;;;;678:643:1:o;1326:703::-;;1453:3;1446:4;1438:6;1434:17;1430:27;1420:2;;1475:5;1468;1461:20;1420:2;1515:6;1502:20;1541:4;1565:65;1580:49;1626:2;1580:49;:::i;1565:65::-;1664:15;;;1695:12;;;;1727:15;;;1760:5;1774:226;1788:2;1785:1;1782:9;1774:226;;;1845:80;1921:3;1916:2;1909:3;1896:17;1888:6;1884:30;1880:39;1845:80;:::i;:::-;1833:93;;1946:12;;;;1978;;;;1806:1;1799:9;1774:226;;2034:703;;2161:3;2154:4;2146:6;2142:17;2138:27;2128:2;;2183:5;2176;2169:20;2128:2;2223:6;2210:20;2249:4;2273:65;2288:49;2334:2;2288:49;:::i;2273:65::-;2372:15;;;2403:12;;;;2435:15;;;2468:5;2482:226;2496:2;2493:1;2490:9;2482:226;;;2553:80;2629:3;2624:2;2617:3;2604:17;2596:6;2592:30;2588:39;2553:80;:::i;:::-;2541:93;;2654:12;;;;2686;;;;2514:1;2507:9;2482:226;;2742:673;;2854:3;2847:4;2839:6;2835:17;2831:27;2821:2;;2876:5;2869;2862:20;2821:2;2916:6;2903:20;2942:4;2966:65;2981:49;3027:2;2981:49;:::i;2966:65::-;3065:15;;;3096:12;;;;3128:15;;;3161:5;3175:211;3189:2;3186:1;3183:9;3175:211;;;3246:65;3307:3;3302:2;3295:3;3282:17;3274:6;3270:30;3266:39;3246:65;:::i;:::-;3234:78;;3332:12;;;;3364;;;;3207:1;3200:9;3175:211;;3420:705;;3533:3;3526:4;3518:6;3514:17;3510:27;3500:2;;3555:5;3548;3541:20;3500:2;3595:6;3582:20;3621:4;3645:65;3660:49;3706:2;3660:49;:::i;3645:65::-;3744:15;;;3775:12;;;;3807:15;;;3853:11;;;3841:24;;3837:33;;3834:42;-1:-1:-1;3831:2:1;;;3893:5;3886;3879:20;3831:2;3919:5;3933:163;3947:2;3944:1;3941:9;3933:163;;;4004:17;;3992:30;;4042:12;;;;4074;;;;3965:1;3958:9;3933:163;;4130:233;;4228:3;4221:4;4213:6;4209:17;4205:27;4195:2;;4250:5;4243;4236:20;4195:2;4276:81;4353:3;4344:6;4331:20;4324:4;4316:6;4312:17;4276:81;:::i;4368:198::-;;4480:2;4468:9;4459:7;4455:23;4451:32;4448:2;;;4501:6;4493;4486:22;4448:2;4529:31;4550:9;4529:31;:::i;4571:274::-;;;4700:2;4688:9;4679:7;4675:23;4671:32;4668:2;;;4721:6;4713;4706:22;4668:2;4749:31;4770:9;4749:31;:::i;:::-;4739:41;;4799:40;4835:2;4824:9;4820:18;4799:40;:::i;:::-;4789:50;;4658:187;;;;;:::o;4850:342::-;;;;4996:2;4984:9;4975:7;4971:23;4967:32;4964:2;;;5017:6;5009;5002:22;4964:2;5045:31;5066:9;5045:31;:::i;:::-;5035:41;;5095:40;5131:2;5120:9;5116:18;5095:40;:::i;:::-;5085:50;;5182:2;5171:9;5167:18;5154:32;5144:42;;4954:238;;;;;:::o;5197:702::-;;;;;5369:3;5357:9;5348:7;5344:23;5340:33;5337:2;;;5391:6;5383;5376:22;5337:2;5419:31;5440:9;5419:31;:::i;:::-;5409:41;;5469:40;5505:2;5494:9;5490:18;5469:40;:::i;:::-;5459:50;;5556:2;5545:9;5541:18;5528:32;5518:42;;5611:2;5600:9;5596:18;5583:32;5638:18;5630:6;5627:30;5624:2;;;5675:6;5667;5660:22;5624:2;5703:22;;5756:4;5748:13;;5744:27;-1:-1:-1;5734:2:1;;5790:6;5782;5775:22;5734:2;5818:75;5885:7;5880:2;5867:16;5862:2;5858;5854:11;5818:75;:::i;:::-;5808:85;;;5327:572;;;;;;;:::o;5904:369::-;;;6030:2;6018:9;6009:7;6005:23;6001:32;5998:2;;;6051:6;6043;6036:22;5998:2;6079:31;6100:9;6079:31;:::i;:::-;6069:41;;6160:2;6149:9;6145:18;6132:32;6207:5;6200:13;6193:21;6186:5;6183:32;6173:2;;6234:6;6226;6219:22;6173:2;6262:5;6252:15;;;5988:285;;;;;:::o;6278:266::-;;;6407:2;6395:9;6386:7;6382:23;6378:32;6375:2;;;6428:6;6420;6413:22;6375:2;6456:31;6477:9;6456:31;:::i;:::-;6446:41;6534:2;6519:18;;;;6506:32;;-1:-1:-1;;;6365:179:1:o;6549:488::-;;;;6705:2;6693:9;6684:7;6680:23;6676:32;6673:2;;;6726:6;6718;6711:22;6673:2;6754:31;6775:9;6754:31;:::i;:::-;6744:41;;6832:2;6821:9;6817:18;6804:32;6794:42;;6887:2;6876:9;6872:18;6859:32;6914:18;6906:6;6903:30;6900:2;;;6951:6;6943;6936:22;6900:2;6979:52;7023:7;7014:6;7003:9;6999:22;6979:52;:::i;:::-;6969:62;;;6663:374;;;;;:::o;7042:995::-;;;;;;7282:3;7270:9;7261:7;7257:23;7253:33;7250:2;;;7304:6;7296;7289:22;7250:2;7332:31;7353:9;7332:31;:::i;:::-;7322:41;;7410:2;7399:9;7395:18;7382:32;7372:42;;7465:2;7454:9;7450:18;7437:32;7488:18;7529:2;7521:6;7518:14;7515:2;;;7550:6;7542;7535:22;7515:2;7578:52;7622:7;7613:6;7602:9;7598:22;7578:52;:::i;:::-;7568:62;;7683:2;7672:9;7668:18;7655:32;7639:48;;7712:2;7702:8;7699:16;7696:2;;;7733:6;7725;7718:22;7696:2;7761:69;7822:7;7811:8;7800:9;7796:24;7761:69;:::i;:::-;7751:79;;7883:3;7872:9;7868:19;7855:33;7839:49;;7913:2;7903:8;7900:16;7897:2;;;7934:6;7926;7919:22;7897:2;;7962:69;8023:7;8012:8;8001:9;7997:24;7962:69;:::i;:::-;7952:79;;;7240:797;;;;;;;;:::o;8042:888::-;;;;8273:2;8261:9;8252:7;8248:23;8244:32;8241:2;;;8294:6;8286;8279:22;8241:2;8339:9;8326:23;8368:18;8409:2;8401:6;8398:14;8395:2;;;8430:6;8422;8415:22;8395:2;8458:67;8517:7;8508:6;8497:9;8493:22;8458:67;:::i;:::-;8448:77;;8578:2;8567:9;8563:18;8550:32;8534:48;;8607:2;8597:8;8594:16;8591:2;;;8628:6;8620;8613:22;8591:2;8656:69;8717:7;8706:8;8695:9;8691:24;8656:69;:::i;:::-;8646:79;;8778:2;8767:9;8763:18;8750:32;8734:48;;8807:2;8797:8;8794:16;8791:2;;;8828:6;8820;8813:22;8791:2;;8856:68;8916:7;8905:8;8894:9;8890:24;8856:68;:::i;8935:1452::-;;;;;;9300:3;9288:9;9279:7;9275:23;9271:33;9268:2;;;9322:6;9314;9307:22;9268:2;9367:9;9354:23;9396:18;9437:2;9429:6;9426:14;9423:2;;;9458:6;9450;9443:22;9423:2;9486:67;9545:7;9536:6;9525:9;9521:22;9486:67;:::i;:::-;9476:77;;9606:2;9595:9;9591:18;9578:32;9562:48;;9635:2;9625:8;9622:16;9619:2;;;9656:6;9648;9641:22;9619:2;9684:69;9745:7;9734:8;9723:9;9719:24;9684:69;:::i;:::-;9674:79;;9806:2;9795:9;9791:18;9778:32;9762:48;;9835:2;9825:8;9822:16;9819:2;;;9856:6;9848;9841:22;9819:2;9884:68;9944:7;9933:8;9922:9;9918:24;9884:68;:::i;:::-;9874:78;;10005:2;9994:9;9990:18;9977:32;9961:48;;10034:2;10024:8;10021:16;10018:2;;;10055:6;10047;10040:22;10018:2;10083:83;10158:7;10147:8;10136:9;10132:24;10083:83;:::i;:::-;10073:93;;10219:3;10208:9;10204:19;10191:33;10175:49;;10249:2;10239:8;10236:16;10233:2;;;10270:6;10262;10255:22;10233:2;;10298:83;10373:7;10362:8;10351:9;10347:24;10298:83;:::i;10392:190::-;;10504:2;10492:9;10483:7;10479:23;10475:32;10472:2;;;10525:6;10517;10510:22;10472:2;-1:-1:-1;10553:23:1;;10462:120;-1:-1:-1;10462:120:1:o;10587:266::-;;;10716:2;10704:9;10695:7;10691:23;10687:32;10684:2;;;10737:6;10729;10722:22;10684:2;10778:9;10765:23;10755:33;;10807:40;10843:2;10832:9;10828:18;10807:40;:::i;10858:258::-;;;10987:2;10975:9;10966:7;10962:23;10958:32;10955:2;;;11008:6;11000;10993:22;10955:2;-1:-1:-1;;11036:23:1;;;11106:2;11091:18;;;11078:32;;-1:-1:-1;10945:171:1:o;11121:257::-;;11232:2;11220:9;11211:7;11207:23;11203:32;11200:2;;;11253:6;11245;11238:22;11200:2;11297:9;11284:23;11316:32;11342:5;11316:32;:::i;11383:261::-;;11505:2;11493:9;11484:7;11480:23;11476:32;11473:2;;;11526:6;11518;11511:22;11473:2;11563:9;11557:16;11582:32;11608:5;11582:32;:::i;12107:259::-;;12188:5;12182:12;12215:6;12210:3;12203:19;12231:63;12287:6;12280:4;12275:3;12271:14;12264:4;12257:5;12253:16;12231:63;:::i;:::-;12348:2;12327:15;-1:-1:-1;;12323:29:1;12314:39;;;;12355:4;12310:50;;12158:208;-1:-1:-1;;12158:208:1:o;12371:470::-;;12588:6;12582:13;12604:53;12650:6;12645:3;12638:4;12630:6;12626:17;12604:53;:::i;:::-;12720:13;;12679:16;;;;12742:57;12720:13;12679:16;12776:4;12764:17;;12742:57;:::i;:::-;12815:20;;12558:283;-1:-1:-1;;;;12558:283:1:o;12846:203::-;-1:-1:-1;;;;;13010:32:1;;;;12992:51;;12980:2;12965:18;;12947:102::o;13054:490::-;-1:-1:-1;;;;;13323:15:1;;;13305:34;;13375:15;;13370:2;13355:18;;13348:43;13422:2;13407:18;;13400:34;;;13470:3;13465:2;13450:18;;13443:31;;;13054:490;;13491:47;;13518:19;;13510:6;13491:47;:::i;:::-;13483:55;13257:287;-1:-1:-1;;;;;;13257:287:1:o;13549:661::-;13720:2;13772:21;;;13842:13;;13745:18;;;13864:22;;;13549:661;;13720:2;13943:15;;;;13917:2;13902:18;;;13549:661;13989:195;14003:6;14000:1;13997:13;13989:195;;;14068:13;;-1:-1:-1;;;;;14064:39:1;14052:52;;14159:15;;;;14124:12;;;;14100:1;14018:9;13989:195;;;-1:-1:-1;14201:3:1;;13700:510;-1:-1:-1;;;;;;13700:510:1:o;14215:635::-;14386:2;14438:21;;;14508:13;;14411:18;;;14530:22;;;14215:635;;14386:2;14609:15;;;;14583:2;14568:18;;;14215:635;14655:169;14669:6;14666:1;14663:13;14655:169;;;14730:13;;14718:26;;14799:15;;;;14764:12;;;;14691:1;14684:9;14655:169;;14855:187;15020:14;;15013:22;14995:41;;14983:2;14968:18;;14950:92::o;15047:177::-;15193:25;;;15181:2;15166:18;;15148:76::o;15229:221::-;;15378:2;15367:9;15360:21;15398:46;15440:2;15429:9;15425:18;15417:6;15398:46;:::i;15455:398::-;15657:2;15639:21;;;15696:2;15676:18;;;15669:30;15735:34;15730:2;15715:18;;15708:62;-1:-1:-1;;;15801:2:1;15786:18;;15779:32;15843:3;15828:19;;15629:224::o;15858:411::-;16060:2;16042:21;;;16099:2;16079:18;;;16072:30;16138:34;16133:2;16118:18;;16111:62;-1:-1:-1;;;16204:2:1;16189:18;;16182:45;16259:3;16244:19;;16032:237::o;16274:407::-;16476:2;16458:21;;;16515:2;16495:18;;;16488:30;16554:34;16549:2;16534:18;;16527:62;-1:-1:-1;;;16620:2:1;16605:18;;16598:41;16671:3;16656:19;;16448:233::o;16686:414::-;16888:2;16870:21;;;16927:2;16907:18;;;16900:30;16966:34;16961:2;16946:18;;16939:62;-1:-1:-1;;;17032:2:1;17017:18;;17010:48;17090:3;17075:19;;16860:240::o;17105:352::-;17307:2;17289:21;;;17346:2;17326:18;;;17319:30;17385;17380:2;17365:18;;17358:58;17448:2;17433:18;;17279:178::o;17462:400::-;17664:2;17646:21;;;17703:2;17683:18;;;17676:30;17742:34;17737:2;17722:18;;17715:62;-1:-1:-1;;;17808:2:1;17793:18;;17786:34;17852:3;17837:19;;17636:226::o;17867:349::-;18069:2;18051:21;;;18108:2;18088:18;;;18081:30;18147:27;18142:2;18127:18;;18120:55;18207:2;18192:18;;18041:175::o;18221:408::-;18423:2;18405:21;;;18462:2;18442:18;;;18435:30;18501:34;18496:2;18481:18;;18474:62;-1:-1:-1;;;18567:2:1;18552:18;;18545:42;18619:3;18604:19;;18395:234::o;18634:412::-;18836:2;18818:21;;;18875:2;18855:18;;;18848:30;18914:34;18909:2;18894:18;;18887:62;-1:-1:-1;;;18980:2:1;18965:18;;18958:46;19036:3;19021:19;;18808:238::o;19051:420::-;19253:2;19235:21;;;19292:2;19272:18;;;19265:30;19331:34;19326:2;19311:18;;19304:62;19402:26;19397:2;19382:18;;19375:54;19461:3;19446:19;;19225:246::o;19476:406::-;19678:2;19660:21;;;19717:2;19697:18;;;19690:30;19756:34;19751:2;19736:18;;19729:62;-1:-1:-1;;;19822:2:1;19807:18;;19800:40;19872:3;19857:19;;19650:232::o;19887:405::-;20089:2;20071:21;;;20128:2;20108:18;;;20101:30;20167:34;20162:2;20147:18;;20140:62;-1:-1:-1;;;20233:2:1;20218:18;;20211:39;20282:3;20267:19;;20061:231::o;20297:410::-;20499:2;20481:21;;;20538:2;20518:18;;;20511:30;20577:34;20572:2;20557:18;;20550:62;-1:-1:-1;;;20643:2:1;20628:18;;20621:44;20697:3;20682:19;;20471:236::o;20712:419::-;20914:2;20896:21;;;20953:2;20933:18;;;20926:30;20992:34;20987:2;20972:18;;20965:62;21063:25;21058:2;21043:18;;21036:53;21121:3;21106:19;;20886:245::o;21136:356::-;21338:2;21320:21;;;21357:18;;;21350:30;21416:34;21411:2;21396:18;;21389:62;21483:2;21468:18;;21310:182::o;21497:413::-;21699:2;21681:21;;;21738:2;21718:18;;;21711:30;21777:34;21772:2;21757:18;;21750:62;-1:-1:-1;;;21843:2:1;21828:18;;21821:47;21900:3;21885:19;;21671:239::o;21915:408::-;22117:2;22099:21;;;22156:2;22136:18;;;22129:30;22195:34;22190:2;22175:18;;22168:62;-1:-1:-1;;;22261:2:1;22246:18;;22239:42;22313:3;22298:19;;22089:234::o;22328:404::-;22530:2;22512:21;;;22569:2;22549:18;;;22542:30;22608:34;22603:2;22588:18;;22581:62;-1:-1:-1;;;22674:2:1;22659:18;;22652:38;22722:3;22707:19;;22502:230::o;22737:405::-;22939:2;22921:21;;;22978:2;22958:18;;;22951:30;23017:34;23012:2;22997:18;;22990:62;-1:-1:-1;;;23083:2:1;23068:18;;23061:39;23132:3;23117:19;;22911:231::o;23147:411::-;23349:2;23331:21;;;23388:2;23368:18;;;23361:30;23427:34;23422:2;23407:18;;23400:62;-1:-1:-1;;;23493:2:1;23478:18;;23471:45;23548:3;23533:19;;23321:237::o;23563:397::-;23765:2;23747:21;;;23804:2;23784:18;;;23777:30;23843:34;23838:2;23823:18;;23816:62;-1:-1:-1;;;23909:2:1;23894:18;;23887:31;23950:3;23935:19;;23737:223::o;23965:413::-;24167:2;24149:21;;;24206:2;24186:18;;;24179:30;24245:34;24240:2;24225:18;;24218:62;-1:-1:-1;;;24311:2:1;24296:18;;24289:47;24368:3;24353:19;;24139:239::o;24383:408::-;24585:2;24567:21;;;24624:2;24604:18;;;24597:30;24663:34;24658:2;24643:18;;24636:62;-1:-1:-1;;;24729:2:1;24714:18;;24707:42;24781:3;24766:19;;24557:234::o;24796:425::-;24998:2;24980:21;;;25037:2;25017:18;;;25010:30;25076:34;25071:2;25056:18;;25049:62;25147:31;25142:2;25127:18;;25120:59;25211:3;25196:19;;24970:251::o;25226:412::-;25428:2;25410:21;;;25467:2;25447:18;;;25440:30;25506:34;25501:2;25486:18;;25479:62;-1:-1:-1;;;25572:2:1;25557:18;;25550:46;25628:3;25613:19;;25400:238::o;25643:411::-;25845:2;25827:21;;;25884:2;25864:18;;;25857:30;25923:34;25918:2;25903:18;;25896:62;-1:-1:-1;;;25989:2:1;25974:18;;25967:45;26044:3;26029:19;;25817:237::o;26241:251::-;26311:2;26305:9;26341:17;;;26388:18;26373:34;;26409:22;;;26370:62;26367:2;;;26435:18;;:::i;:::-;26471:2;26464:22;26285:207;;-1:-1:-1;26285:207:1:o;26497:192::-;;26596:18;26588:6;26585:30;26582:2;;;26618:18;;:::i;:::-;-1:-1:-1;26678:4:1;26659:17;;;26655:28;;26572:117::o;26694:128::-;;26765:1;26761:6;26758:1;26755:13;26752:2;;;26771:18;;:::i;:::-;-1:-1:-1;26807:9:1;;26742:80::o;26827:120::-;;26893:1;26883:2;;26898:18;;:::i;:::-;-1:-1:-1;26932:9:1;;26873:74::o;26952:125::-;;27020:1;27017;27014:8;27011:2;;;27025:18;;:::i;:::-;-1:-1:-1;27062:9:1;;27001:76::o;27082:258::-;27154:1;27164:113;27178:6;27175:1;27172:13;27164:113;;;27254:11;;;27248:18;27235:11;;;27228:39;27200:2;27193:10;27164:113;;;27295:6;27292:1;27289:13;27286:2;;;-1:-1:-1;;27330:1:1;27312:16;;27305:27;27135:205::o;27345:380::-;27430:1;27420:12;;27477:1;27467:12;;;27488:2;;27542:4;27534:6;27530:17;27520:27;;27488:2;27595;27587:6;27584:14;27564:18;27561:38;27558:2;;;27641:10;27636:3;27632:20;27629:1;27622:31;27676:4;27673:1;27666:15;27704:4;27701:1;27694:15;27558:2;;27400:325;;;:::o;27730:135::-;;-1:-1:-1;;27790:17:1;;27787:2;;;27810:18;;:::i;:::-;-1:-1:-1;27857:1:1;27846:13;;27777:88::o;27870:112::-;;27928:1;27918:2;;27933:18;;:::i;:::-;-1:-1:-1;27967:9:1;;27908:74::o;27987:127::-;28048:10;28043:3;28039:20;28036:1;28029:31;28079:4;28076:1;28069:15;28103:4;28100:1;28093:15;28119:127;28180:10;28175:3;28171:20;28168:1;28161:31;28211:4;28208:1;28201:15;28235:4;28232:1;28225:15;28251:127;28312:10;28307:3;28303:20;28300:1;28293:31;28343:4;28340:1;28333:15;28367:4;28364:1;28357:15;28383:133;-1:-1:-1;;;;;;28459:32:1;;28449:43;;28439:2;;28506:1;28503;28496:12

Swarm Source

ipfs://6759dfe3175285406dc33dc120b9f60db93503947770c126a83051d81cdee18e
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.