ETH Price: $3,390.91 (+0.47%)

Token

cMyGraves (Grave)
 

Overview

Max Total Supply

439 Grave

Holders

172

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 Grave
0x85789ef93518e217598257130d6d9d4279f2776e
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.

Contract Source Code Verified (Exact Match)

Contract Name:
Graveyard

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 Etherscan.io on 2021-11-15
*/

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

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

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

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

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

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

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

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

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

// 
/**
 * @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}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be overriden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

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

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// 
/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `sender` to `recipient` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address sender,
        address recipient,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

// 
interface IMiece is IERC20 {
    function burnFrom(address account, uint256 amount) external;
    function getTokensStaked(address staker) external returns (uint256[] memory);
}

//

// 
interface IZombie is IERC721 {
    // function burnFrom(address account, uint256 amount) external;
    function mintZombie(address account, string memory hash) external;
    function totalSupply() external view returns (uint256);
}

// 
library GraveyardLibrary {
    string internal constant TABLE =
        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";


    struct Trait {
        string traitName;
        string traitType;
        string pixels;
        uint256 pixelCount;
    }


    /**
     * @dev Converts a digit from 0 - 10000 into its corresponding rarity based on the given rarity tier.
     * @param _randinput The input from 0 - 10000 to use for rarity gen.
     * @param _rarityTier The tier to use.
     */
    function rarityGen(uint256 _randinput, uint8 _rarityTier, uint16[][8] storage TIERS)
        external
        view
        returns (string memory)
    {
        uint16 currentLowerBound = 0;
        for (uint8 i = 0; i < TIERS[_rarityTier].length; i++) {
            uint16 thisPercentage = TIERS[_rarityTier][i];
            if (
                _randinput >= currentLowerBound &&
                _randinput < currentLowerBound + thisPercentage
            ) return toString(i);
            currentLowerBound = currentLowerBound + thisPercentage;
        }

        revert();
    }


    /**
     * @dev Returns the current miece cost of mint.
     */
    function currentMieceCost(uint256 _totalSupply) public pure returns (uint256) {

        if (_totalSupply <= 1000) 
            return 15 ether; // 15 miece

        if (_totalSupply > 1000 && _totalSupply <= 2111)
            return 25 ether; // 25 miece

        if (_totalSupply > 2111 && _totalSupply <= 3222)
            return 35 ether; // 35 miece

        if (_totalSupply > 3222 && _totalSupply <= 4333)
            return 45 ether; // 45 miece

        if (_totalSupply > 4333 && _totalSupply <= 5444)
            return 55 ether; // 55 miece

        revert();
    }


    /**
     * @dev Returns the current cost of fastening up a digging
     */
    function currentFastenCost() public pure returns (uint256) {
        return 10 ether;  // 10 miece
    }

    /**
     * @dev Helper function to reduce pixel size within contract
     */
    function letterToNumber(string memory _inputLetter, string[] memory LETTERS)
        public
        pure
        returns (uint8)
    {
        for (uint8 i = 0; i < LETTERS.length; i++) {
            if (
                keccak256(abi.encodePacked((LETTERS[i]))) ==
                keccak256(abi.encodePacked((_inputLetter)))
            ) return (i + 1);
        }
        revert();
    }


    /**
     * @dev Returns a hash for a given tokenId
     * @param tokenHash The tokenId to return the hash for.
     * @param yielded The tokenId to return the hash for.
     */
    function _tokenIdToHash(string memory tokenHash, bool yielded)
        external
        pure
        returns (string memory)
    {
        // string memory tokenHash = tokenIdToHash[_tokenId];

        // If this is grave has been dug override the previous hash
        // FIXME: we could just use the burn address instead and remove the yielded flag
        // if (ownerOf(_tokenId) == 0x000000000000000000000000000000000000dEaD) {

        if ( yielded ) {            
            tokenHash = string(
                abi.encodePacked(
                    "1",
                    GraveyardLibrary.substring(tokenHash, 1, 9)
                )
            );

        }

        return tokenHash;
    }


    /**
     * @dev Hash to metadata function
     */
    function hashToMetadata(string memory _hash, mapping(uint256 => Trait[]) storage traitTypes)
        public
        view
        returns (string memory)
    {
        string memory metadataString;

        for (uint8 i = 0; i < 9; i++) { //9
            uint8 thisTraitIndex = GraveyardLibrary.parseInt(
                GraveyardLibrary.substring(_hash, i, i + 1)
            );

            metadataString = string(
                abi.encodePacked(
                    metadataString,
                    '{"trait_type":"',
                    traitTypes[i][thisTraitIndex].traitType,
                    '","value":"',
                    traitTypes[i][thisTraitIndex].traitName,
                    '"}'
                )
            );

            if (i != 8)
                metadataString = string(abi.encodePacked(metadataString, ","));
        }

        return string(abi.encodePacked("[", metadataString, "]"));
    }


    /**
     * @dev Returns the SVG and metadata for a token Id
     * @param _tokenId The tokenId to return the SVG and metadata for.
     */
    function tokenURIData(uint256 _tokenId, string memory tokenHash, mapping(uint256 => Trait[]) storage traitTypes, string[] memory LETTERS, uint256 diggingStarted)
        external
        view        
        returns (string memory)
    {
        
        return
            string(
                abi.encodePacked(
                    "data:application/json;base64,",
                    encode(
                        bytes(
                            string(
                                abi.encodePacked(
                                    '{"name": "cMyGravez #',
                                    toString(_tokenId),
                                    // toString(diggingStarted),      // FIXME: !!!!                               
                                    '", "description": "cMyKatzGraves is a collection of 5,444 unique graves, where burned cats rests in peace. All the metadata and images stored 100% on-chain.", "image": "data:image/svg+xml;base64,',
                                    encode(
                                        bytes(hashToSVG(tokenHash,traitTypes,LETTERS,diggingStarted))
                                    ),
                                    '","attributes":',
                                    hashToMetadata(tokenHash,traitTypes),
                                    "}"
                                )
                            )
                        )
                    )
                )
            );
    }


    /**
     * @dev Hash to SVG function
     */
    function hashToSVG(string memory _hash, mapping(uint256 => Trait[]) storage traitTypes, string[] memory LETTERS, uint256 diggingStarted)
        public
        view
        returns (string memory)
    {
        string memory svgString;
        bool[24][24] memory placedPixels;

        for (uint8 i = 0; i < 9; i++) { 
            uint8 thisTraitIndex = GraveyardLibrary.parseInt(
                GraveyardLibrary.substring(_hash, i, i + 1)
            );
            
            // Hide the zombie arm if the digging is not started
            if ( i == 1 && diggingStarted == 0 ) {
                continue;
            }
            for (
                uint16 j = 0;
                j < traitTypes[i][thisTraitIndex].pixelCount; // <
                j++
            ) {
                string memory thisPixel = GraveyardLibrary.substring(
                    traitTypes[i][thisTraitIndex].pixels,
                    j * 4,
                    j * 4 + 4
                );

                uint8 x = letterToNumber(
                    GraveyardLibrary.substring(thisPixel, 0, 1), LETTERS
                );
                uint8 y = letterToNumber(
                    GraveyardLibrary.substring(thisPixel, 1, 2), LETTERS
                );

                if (placedPixels[x][y]) continue;

                svgString = string(
                    abi.encodePacked(
                        svgString,
                        "<rect class='c",
                        GraveyardLibrary.substring(thisPixel, 2, 4),
                        "' x='",
                        toString(x),
                        "' y='",
                        toString(y),
                        "'/>"
                    )
                );

                placedPixels[x][y] = true;
            }
        }

        svgString = string(
            abi.encodePacked(
                '<svg id="g" xmlns="http://www.w3.org/2000/svg" preserveAspectRatio="xMinYMin meet" viewBox="0 0 24 24" style="background-color:#2A2A2A"> ',
                svgString,
               // "<style>rect{width:1px;height:1px;} #mouse-svg{shape-rendering: crispedges;} .c00{fill:#000000}.c01{fill:#B1ADAC}.c02{fill:#D7D7D7}.c03{fill:#FFA6A6}.c04{fill:#FFD4D5}.c05{fill:#B9AD95}.c06{fill:#E2D6BE}.c07{fill:#7F625A}.c08{fill:#A58F82}.c09{fill:#4B1E0B}.c10{fill:#6D2C10}.c11{fill:#D8D8D8}.c12{fill:#F5F5F5}.c13{fill:#433D4B}.c14{fill:#8D949C}.c15{fill:#05FF00}.c16{fill:#01C700}.c17{fill:#0B8F08}.c18{fill:#421C13}.c19{fill:#6B392A}.c20{fill:#A35E40}.c21{fill:#DCBD91}.c22{fill:#777777}.c23{fill:#848484}.c24{fill:#ABABAB}.c25{fill:#BABABA}.c26{fill:#C7C7C7}.c27{fill:#EAEAEA}.c28{fill:#0C76AA}.c29{fill:#0E97DB}.c30{fill:#10A4EC}.c31{fill:#13B0FF}.c32{fill:#2EB9FE}.c33{fill:#54CCFF}.c34{fill:#50C0F2}.c35{fill:#54CCFF}.c36{fill:#72DAFF}.c37{fill:#B6EAFF}.c38{fill:#FFFFFF}.c39{fill:#954546}.c40{fill:#0B87F7}.c41{fill:#FF2626}.c42{fill:#180F02}.c43{fill:#2B2319}.c44{fill:#FBDD4B}.c45{fill:#F5B923}.c46{fill:#CC8A18}.c47{fill:#3C2203}.c48{fill:#53320B}.c49{fill:#7B501D}.c50{fill:#FFE646}.c51{fill:#FFD627}.c52{fill:#F5B700}.c53{fill:#242424}.c54{fill:#4A4A4A}.c55{fill:#676767}.c56{fill:#F08306}.c57{fill:#FCA30E}.c58{fill:#FEBC0E}.c59{fill:#FBEC1C}.c60{fill:#14242F}.c61{fill:#B06837}.c62{fill:#8F4B0E}.c63{fill:#D88227}.c64{fill:#B06837}</style></svg>"
                "<style>rect{width:1px;height:1px;}#g{shape-rendering: crispedges;}.c00{fill:#3b0346}.c01{fill:#9500b4}.c02{fill:#496707}.c03{fill:#a58d9c}.c04{fill:#859e4a}.c05{fill:#778d45}.c06{fill:#6f8342}.c07{fill:#ff0043}.c08{fill:#f6767b}.c09{fill:#c74249}.c10{fill:#aa343a}.c11{fill:#ffffff}.c12{fill:#000000}.c13{fill:#bfb23e}.c14{fill:#e9cf00}.c15{fill:#00b300}.c16{fill:#009a1a}.c17{fill:#00791a}.c18{fill:#ff2d00}.c19{fill:#e57600}.c20{fill:#f8d9d9}.c21{fill:#ddc600}.c22{fill:#4f4f4f}.c23{fill:#535353}.c24{fill:#565656}.c25{fill:#444444}.c26{fill:#46503f}.c27{fill:#363d30}.c28{fill:#72775c}.c29{fill:#474939}.c30{fill:#5c614a}.c31{fill:#833f41}.c32{fill:#a09300}.c33{fill:#938700}.c34{fill:#877c00}.c35{fill:#5b231d}.c36{fill:#733e39}.c37{fill:#97575a}.c38{fill:#c66703}.c39{fill:#a75c19}.c40{fill:#5a2e04}.c41{fill:#26331d}.c42{fill:#314522}.c43{fill:#3b2d08}.c44{fill:#47360c}.c45{fill:#002845}.c46{fill:#00538a}.c47{fill:#382e25}.c48{fill:#473c32}.c49{fill:#f6efe9}.c50{fill:#695841}.c51{fill:#705d43}.c52{fill:#786142}.c53{fill:#6a4945}.c54{fill:#724946}.c55{fill:#794a45}.c56{fill:#0f0f0f}.c57{fill:#181818}.c58{fill:#8a8a8a}.c59{fill:#445763}.c60{fill:#475c6a}.c61{fill:#465f70}.c62{fill:#ededed}</style></svg>"
            )
        );

        return svgString;
    }    


    function encode(bytes memory data) public pure returns (string memory) {
        if (data.length == 0) return "";

        // load the table into memory
        string memory table = TABLE;

        // multiply by 4/3 rounded up
        uint256 encodedLen = 4 * ((data.length + 2) / 3);

        // add some extra buffer at the end required for the writing
        string memory result = new string(encodedLen + 32);

        assembly {
            // set the actual output length
            mstore(result, encodedLen)

            // prepare the lookup table
            let tablePtr := add(table, 1)

            // input ptr
            let dataPtr := data
            let endPtr := add(dataPtr, mload(data))

            // result ptr, jump over length
            let resultPtr := add(result, 32)

            // run over the input, 3 bytes at a time
            for {

            } lt(dataPtr, endPtr) {

            } {
                dataPtr := add(dataPtr, 3)

                // read 3 bytes
                let input := mload(dataPtr)

                // write 4 characters
                mstore(
                    resultPtr,
                    shl(248, mload(add(tablePtr, and(shr(18, input), 0x3F))))
                )
                resultPtr := add(resultPtr, 1)
                mstore(
                    resultPtr,
                    shl(248, mload(add(tablePtr, and(shr(12, input), 0x3F))))
                )
                resultPtr := add(resultPtr, 1)
                mstore(
                    resultPtr,
                    shl(248, mload(add(tablePtr, and(shr(6, input), 0x3F))))
                )
                resultPtr := add(resultPtr, 1)
                mstore(
                    resultPtr,
                    shl(248, mload(add(tablePtr, and(input, 0x3F))))
                )
                resultPtr := add(resultPtr, 1)
            }

            // padding with '='
            switch mod(mload(data), 3)
            case 1 {
                mstore(sub(resultPtr, 2), shl(240, 0x3d3d))
            }
            case 2 {
                mstore(sub(resultPtr, 1), shl(248, 0x3d))
            }
        }

        return result;
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        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);
    }

    function parseInt(string memory _a)
        internal
        pure
        returns (uint8 _parsedInt)
    {
        bytes memory bresult = bytes(_a);
        uint8 mint = 0;
        for (uint8 i = 0; i < bresult.length; i++) {
            if (
                (uint8(uint8(bresult[i])) >= 48) &&
                (uint8(uint8(bresult[i])) <= 57)
            ) {
                mint *= 10;
                mint += uint8(bresult[i]) - 48;
            }
        }
        return mint;
    }

    function substring(
        string memory str,
        uint256 startIndex,
        uint256 endIndex
    ) internal pure returns (string memory) {
        bytes memory strBytes = bytes(str);
        bytes memory result = new bytes(endIndex - startIndex);
        for (uint256 i = startIndex; i < endIndex; i++) {
            result[i - startIndex] = strBytes[i];
        }
        return string(result);
    }

    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

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

// 
/*

     ___  ___      _____                          
     |  \/  |     |  __ \                         
  ___| .  . |_   _| |  \/_ __ __ ___   _____  ___ 
 / __| |\/| | | | | | __| '__/ _` \ \ / / _ \/ __|
| (__| |  | | |_| | |_\ \ | | (_| |\ V /  __/\__ \
 \___\_|  |_/\__, |\____/_|  \__,_| \_/ \___||___/
              __/ |                               
             |___/                                

*/
contract Graveyard is ERC721Enumerable {
    using GraveyardLibrary for uint8;
    
    // While zombies are false, minting graveyards is not possible
    // bool public ZOMBIES = false;

    // uint256 public DEFAULT_DIGGING_TIME = 86400;
    uint256 public MAX_SUPPLY = 5444;
    uint256 SEED_NONCE = 0;

    // Mappings for the traits and their hashes
    mapping(uint256 => GraveyardLibrary.Trait[]) public traitTypes;
    mapping(string => bool) hashToMinted;
    mapping(uint256 => string) internal tokenIdToHash;

    // Mapping of graveyardId to store the time when the zombie can be claimed
    mapping(uint256 => uint256) internal tokenIdToTargetTime;

    // Mapping of graveyardId to staker
    mapping(uint256 => address) internal tokenIdToStaker;    
    mapping(address => uint256[]) internal stakerToTokenIds;

    // Mapping of graveyardId to staked zombie ids 
    mapping(uint256 => uint256[]) internal graveyardIdToCatIds;

    address nullAddress = 0x0000000000000000000000000000000000000000;

    // Mapping of graveyardId to store if a zombie has been claimed or not
    mapping(uint256 => bool) internal tokenIdToYield;

    mapping(uint256 => bool) internal katzIdUsedForMint;

    // The ZombieKat contract address
    address public zombiesAddress;

    // String arrays, we were not able to store this in the library. Sing the alphabet while you read this.
    string[] LETTERS = [
        "a",
        "b",
        "c",
        "d",
        "e",
        "f",
        "g",
        "h",
        "i",
        "j",
        "k",
        "l",
        "m",
        "n",
        "o",
        "p",
        "q",
        "r",
        "s",
        "t",
        "u",
        "v",
        "w",
        "x",
        "y",
        "z"
    ];

    // Array to store the rarity of the graves
    uint16[][8] internal TIERS;

    // The miece contract address and the contract owner. 
    address mieceAddress;
    address _owner;

    constructor() ERC721("cMyGraves", "Grave") {
        _owner = msg.sender;

        TIERS[0] = [100, 200, 800, 800, 1200, 2000, 4900]; // arm
        TIERS[1] = [400, 1000, 3200, 5400];
        TIERS[2] = [500, 1400, 1600, 6500];
        TIERS[3] = [100, 400, 500, 9000];
        TIERS[4] = [200, 400, 1100, 1100, 2400, 2400, 2400];
        TIERS[5] = [2500, 2500, 2500, 2500];
        TIERS[6] = [2500, 2500, 2500, 2500];
        TIERS[7] = [40, 140, 1420, 1800, 2000, 2200, 2400 ];

    }

    /**
     * @dev Returns the staked zombies ids 
     * @param staker  The address of the staker
     */   
    function getCatsStaked(address staker)
        public
        view
        returns (uint256[] memory)
    {
        return stakerToTokenIds[staker];
    }
    
    /**
     * @dev helper function to remove a token id from the array associated to the staker
     * @param staker  The address of the staker
     * @param index Index
     */   
    function remove(address staker, uint256 index) internal {
        if (index >= stakerToTokenIds[staker].length) return;

        for (uint256 i = index; i < stakerToTokenIds[staker].length - 1; i++) {
            stakerToTokenIds[staker][i] = stakerToTokenIds[staker][i + 1];
        }
        stakerToTokenIds[staker].pop();
    }

    /**
     * @dev helper function to maintain the list of staked ids of an address
     * @param staker  The address of the staker
     * @param tokenId  The Staked Zombie Ids
     */
    function removeTokenIdFromStaker(address staker, uint256 tokenId) internal {
        for (uint256 i = 0; i < stakerToTokenIds[staker].length; i++) {
            if (stakerToTokenIds[staker][i] == tokenId) {
                //This is the tokenId to remove;
                remove(staker, i);
            }
        }
    }

    /**
     * @dev Initialize the digging op and sets the target time when user can claim a zombie
     * @param graveId  Target Grave Id
     */
    
    function initDigTime(uint256 graveId, uint256 multipler) internal {
        tokenIdToTargetTime[graveId] =
            block.timestamp +
            (86400 * multipler);
    }

    /**
     * @dev Unstakes the zombies from the grave, but only if the zombie has been claimed first. 
     * @param graveId  Grave Id
     */
    function claimAndUnstake(uint256 graveId) public {
        claimZombie(graveId);

        require(
            tokenIdToYield[graveId] == true
            // "You need to claim the zombie first"
        );

        for (uint256 i = 0; i < graveyardIdToCatIds[graveId].length; i++) {
            require(
                tokenIdToStaker[graveyardIdToCatIds[graveId][i]] == msg.sender
                // "Message Sender was not original staker!"
            );

            IERC721(zombiesAddress).transferFrom(
                address(this),
                msg.sender,
                graveyardIdToCatIds[graveId][i]
            );

            removeTokenIdFromStaker(
                msg.sender,
                graveyardIdToCatIds[graveId][i]
            );

            tokenIdToStaker[graveyardIdToCatIds[graveId][i]] = nullAddress;
        }
    }

    /**
     * @dev Moves staked zombies from one grave to an another
     * @param fromGraveId   Source Grave Id
     * @param toGraveId  Target Grave Id
     */

    function claimAndMove(uint256 fromGraveId, uint256 toGraveId) public {
        claimZombie(fromGraveId);

        require(
            tokenIdToYield[fromGraveId] == true
            // "You need to withdraw the zombie cat first."
        );

        require(
            ownerOf(toGraveId) == msg.sender
            // "You can only dig your own graves"
        );

        for (uint256 i = 0; i < graveyardIdToCatIds[fromGraveId].length; i++) {
            require(
                tokenIdToStaker[graveyardIdToCatIds[fromGraveId][i]] ==
                    msg.sender
                // "Message Sender was not original staker!"
            );
            graveyardIdToCatIds[toGraveId].push(
                graveyardIdToCatIds[fromGraveId][i]
            );
        }
        delete graveyardIdToCatIds[fromGraveId]; // Maybe we don't need this

        initDigTime(toGraveId, 7);
    }

    /**
     * @dev Stake zombies in a grave
     * @param graveId   The grave id
     * @param tokenIds  Ids of the zombies
     */

    function stakeByIds(uint256 graveId, uint256[] memory tokenIds) public {
        require(
            tokenIds.length == 2
            // "You need two cats to dig!"
        );

        require(
            graveyardIdToCatIds[graveId].length == 0
            // "There are already cats digging this grave"
        );

        require(
            ownerOf(graveId) == msg.sender
            // "You can only dig your own graves"
        );

        for (uint256 i = 0; i < tokenIds.length; i++) {
            require(
                IERC721(zombiesAddress).ownerOf(tokenIds[i]) == msg.sender &&
                    tokenIdToStaker[tokenIds[i]] == nullAddress
                // "Token must be stakable by you!"
            );

            IERC721(zombiesAddress).transferFrom(
                msg.sender,
                address(this),
                tokenIds[i]
            );

            stakerToTokenIds[msg.sender].push(tokenIds[i]);

            graveyardIdToCatIds[graveId].push(tokenIds[i]);

            tokenIdToStaker[tokenIds[i]] = msg.sender;
        }

        initDigTime(graveId, 7);
    }

    /**
     * @dev Returns the list of ids staked in a grave
     * @param graveId The grave id
     */
    function getCatsStakedByGraveId(uint256 graveId)
        public
        view
        returns (uint256[] memory)
    {
        return graveyardIdToCatIds[graveId];
    }
    

    /**
     * @dev Returns seconds lefts from a digging completion
     * @param graveId The tokenId to return the time lefts
     */ 
    function getDiggingCompletionTime(uint256 graveId)
        public
        view
        returns (uint256)
    {
        require(tokenIdToTargetTime[graveId] != 0
        // , "Digging not started"
        );
        require(tokenIdToYield[graveId] != true
        //, "Digging already finished"
        );

        return tokenIdToTargetTime[graveId];
    }

    /**
     * @dev Claims the zombie from a grave and burn the grave. 
     * @param tokenId The grave Id to claim the zombie from
     */
     function claimZombie(uint256 tokenId) internal {
         require(
            ownerOf(tokenId) == msg.sender
            // "You cannot withdraw from someone else grave"
        );
        require(
            tokenIdToTargetTime[tokenId] < block.timestamp
            //  "This grave digging is not finished yet"
        );

        // Zombie Contract will mint a Zombie with the same hash as the Current Grave
        IZombie(zombiesAddress).mintZombie(
            msg.sender,
            _tokenIdToHash(tokenId)
        );

        tokenIdToYield[tokenId] = true;

        // After the zombie claimed we burn the graveyard
        _transfer(
            msg.sender,
            0x000000000000000000000000000000000000dEaD,
            tokenId
        );
     }

    /**
     * @dev Claims the zombie from a grave and burn the grave. 
     * @param tokenIds The grave Ids to claim the zombie from
     */
    function claimZombies(uint256[] memory tokenIds) public {
        for (uint256 i = 0; i < tokenIds.length; i++) {
            require(
                graveyardIdToCatIds[tokenIds[i]].length == 0
                // "There are cats digging the grave, can't only claim yielded zombie"
            );

            claimZombie(tokenIds[i]);
        }
    }

    /**
     * @dev Fasten up the digging process by spending mice on the Grave. You can include the same GraveId multiple time, it decreases the digging time with a day.
     * @param tokenIds The graveyard Ids. 
     */
    function fastenDigging(uint256[] memory tokenIds) public {
        for (uint256 i = 0; i < tokenIds.length; i++) {
            IMiece(mieceAddress).burnFrom(
                msg.sender,
                GraveyardLibrary.currentFastenCost(
                    // IZombie(zombiesAddress).totalSupply()
                )
            );

            tokenIdToTargetTime[tokenIds[i]] =
                tokenIdToTargetTime[tokenIds[i]] -
                86400;
        }
    }

    /*
  __  __ _     _   _             ___             _   _             
 |  \/  (_)_ _| |_(_)_ _  __ _  | __|  _ _ _  __| |_(_)___ _ _  ___
 | |\/| | | ' \  _| | ' \/ _` | | _| || | ' \/ _|  _| / _ \ ' \(_-<
 |_|  |_|_|_||_\__|_|_||_\__, | |_| \_,_|_||_\__|\__|_\___/_||_/__/
                         |___/                                     
   */

    /**
     * @dev Generates a 9 digit hash from a tokenId, address, and random number.
     * @param _t The token id to be used within the hash.
     * @param _a The address to be used within the hash.
     * @param _c The custom nonce to be used within the hash.
     */
    function hash(
        uint256 _t,
        address _a,
        uint256 _c
    ) internal returns (string memory) {
        require(_c < 10);

        // This will generate a 9 character string.
        //The last 8 digits are random, the first is 0, due to the mouse not being burned.
        string memory currentHash = "0";

        for (uint8 i = 0; i < 8; i++) {
            SEED_NONCE++;
            uint16 _randinput = uint16(
                uint256(
                    keccak256(
                        abi.encodePacked(
                            block.timestamp,
                            block.difficulty,
                            _t,
                            _a,
                            _c,
                            SEED_NONCE
                        )
                    )
                ) % 10000
            );

            currentHash = string(
                abi.encodePacked(
                    currentHash,
                    GraveyardLibrary.rarityGen(_randinput, i, TIERS)
                )
            );
        }

        if (hashToMinted[currentHash]) return hash(_t, _a, _c + 1);

        return currentHash;
    }

    /**
     * @dev Returns the current miece cost of mint.
     */
    function currentMieceCost() public view returns (uint256) {
        return GraveyardLibrary.currentMieceCost(totalSupply());
    }


    /**
     * @dev Checks if a Katz has been used for minting.
     */
    function checkKatzUsage(uint256 katzId) public view returns (bool) {
        return katzIdUsedForMint[ katzId ];
    }

    /**
     * @dev Mints a Grave, this is to avoid code duplication.
     */
    function mintGrave(uint256 katzId) public {
        uint256 _totalSupply = totalSupply();
        require(_totalSupply < MAX_SUPPLY);

        // FIXME: Add these before deployment
        // require(_totalSupply > 4);
        // require(!GraveyardLibrary.isContract(msg.sender));
        
        uint256 thisTokenId = _totalSupply;

        tokenIdToHash[thisTokenId] = hash(thisTokenId, msg.sender, 0);

        hashToMinted[tokenIdToHash[thisTokenId]] = true;

        IMiece(mieceAddress).burnFrom(msg.sender, currentMieceCost());

        // First 1000 graves yields automatically after 7 days. 
        if ( _totalSupply < 1000 ) {

            bool doesListContainElement = false;

            uint256[] memory stakedIds = IMiece(mieceAddress).getTokensStaked(msg.sender);

            for (uint i=0; i < stakedIds.length; i++) {
                if (katzId == stakedIds[i]) {
                    doesListContainElement = true;
                }
            }
            require(doesListContainElement == true);

            require(katzIdUsedForMint[ katzId ] == false);

            katzIdUsedForMint[ katzId ] = true;
                                                            // require(stakedIds.length > 0);    
           initDigTime(thisTokenId, 7);
        }
        
        _mint(msg.sender, thisTokenId);
    }
 

  

    function mintReserve(uint256 _times) public onlyOwner {
        // ZOMBIES = true;
        for(uint256 i=0; i< _times; i++){
            uint256 thisTokenId = totalSupply();
            require(thisTokenId < 50);
            tokenIdToHash[thisTokenId] = hash(thisTokenId, msg.sender, 0);
            hashToMinted[tokenIdToHash[thisTokenId]] = true;
            initDigTime(thisTokenId, 7);
            _mint(msg.sender, thisTokenId);
        }
    }
 

    /*
 ____     ___   ____  ___        _____  __ __  ____     __ ______  ____  ___   ____   _____
|    \   /  _] /    ||   \      |     ||  |  ||    \   /  ]      ||    |/   \ |    \ / ___/
|  D  ) /  [_ |  o  ||    \     |   __||  |  ||  _  | /  /|      | |  ||     ||  _  (   \_ 
|    / |    _]|     ||  D  |    |  |_  |  |  ||  |  |/  / |_|  |_| |  ||  O  ||  |  |\__  |
|    \ |   [_ |  _  ||     |    |   _] |  :  ||  |  /   \_  |  |   |  ||     ||  |  |/  \ |
|  .  \|     ||  |  ||     |    |  |   |     ||  |  \     | |  |   |  ||     ||  |  |\    |
|__|\_||_____||__|__||_____|    |__|    \__,_||__|__|\____| |__|  |____|\___/ |__|__| \___|
                                                                                           
*/

    /**
     * @dev Returns the SVG and metadata for a token Id
     * @param _tokenId The tokenId to return the SVG and metadata for.
     */

    function tokenURI(uint256 _tokenId)
        public
        view
        override
        returns (string memory)
    {
        require(_exists(_tokenId));

        string memory tokenHash = _tokenIdToHash(_tokenId);
        
        return
            GraveyardLibrary.tokenURIData(
                _tokenId,
                tokenHash,
                traitTypes,
                LETTERS,
                tokenIdToTargetTime[_tokenId]
            );
    }


    /**
     * @dev Returns a hash for a given tokenId
     * @param _tokenId The tokenId to return the hash for.
     */
    function _tokenIdToHash(uint256 _tokenId)
        public
        view
        returns (string memory)
    {
        string memory tokenHash = tokenIdToHash[_tokenId];
        //If this is a burned token, override the previous hash
        if (tokenIdToYield[_tokenId]) {
            tokenHash = string(
                abi.encodePacked(
                    "1",
                    GraveyardLibrary.substring(tokenHash, 1, 9)
                )
            );
        }

        return tokenHash;
    }

    /**
     * @dev Returns the wallet of a given wallet. Mainly for ease for frontend devs.
     * @param _wallet The wallet to get the tokens of.
     */
    function walletOfOwner(address _wallet)
        public
        view
        returns (uint256[] memory)
    {
        uint256 tokenCount = balanceOf(_wallet);

        uint256[] memory tokensId = new uint256[](tokenCount);
        for (uint256 i; i < tokenCount; i++) {
            tokensId[i] = tokenOfOwnerByIndex(_wallet, i);
        }
        return tokensId;
    }

    /*

  ___   __    __  ____     ___  ____       _____  __ __  ____     __ ______  ____  ___   ____   _____
 /   \ |  |__|  ||    \   /  _]|    \     |     ||  |  ||    \   /  ]      ||    |/   \ |    \ / ___/
|     ||  |  |  ||  _  | /  [_ |  D  )    |   __||  |  ||  _  | /  /|      | |  ||     ||  _  (   \_ 
|  O  ||  |  |  ||  |  ||    _]|    /     |  |_  |  |  ||  |  |/  / |_|  |_| |  ||  O  ||  |  |\__  |
|     ||  `  '  ||  |  ||   [_ |    \     |   _] |  :  ||  |  /   \_  |  |   |  ||     ||  |  |/  \ |
|     | \      / |  |  ||     ||  .  \    |  |   |     ||  |  \     | |  |   |  ||     ||  |  |\    |
 \___/   \_/\_/  |__|__||_____||__|\_|    |__|    \__,_||__|__|\____| |__|  |____|\___/ |__|__| \___|
                                                                                                     


    */

    
    /**
     * @dev Add a trait type
     * @param _traitTypeIndex The trait type index
     * @param traits Array of traits to add
     */

    function addTraitType(
        uint256 _traitTypeIndex,
        GraveyardLibrary.Trait[] memory traits
    ) public onlyOwner {
        for (uint256 i = 0; i < traits.length; i++) {
            traitTypes[_traitTypeIndex].push(
                GraveyardLibrary.Trait(
                    traits[i].traitName,
                    traits[i].traitType,
                    traits[i].pixels,
                    traits[i].pixelCount
                )
            );
        }

        return;
    }

    /**
     * @dev Sets the miece, cats and zombie contract addresses
     * @param _mieceAddress The miece address
     * @param _zombiesAddress The cats address
     */
    function setContractAddresses(
        address _mieceAddress,
        address _zombiesAddress
    ) public onlyOwner {
        mieceAddress = _mieceAddress;
        zombiesAddress = _zombiesAddress;
        return;
    }

    /**
     * @dev Transfers ownership
     * @param _newOwner The new owner
     */
    // function transferOwnership(address _newOwner) public onlyOwner {
    //     _owner = _newOwner;
    // }
    

    /**
     * @dev Modifier to only allow owner to call functions
     */
    modifier onlyOwner() {
        require(_owner == msg.sender);
        _;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"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":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"_tokenIdToHash","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_traitTypeIndex","type":"uint256"},{"components":[{"internalType":"string","name":"traitName","type":"string"},{"internalType":"string","name":"traitType","type":"string"},{"internalType":"string","name":"pixels","type":"string"},{"internalType":"uint256","name":"pixelCount","type":"uint256"}],"internalType":"struct GraveyardLibrary.Trait[]","name":"traits","type":"tuple[]"}],"name":"addTraitType","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"katzId","type":"uint256"}],"name":"checkKatzUsage","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"fromGraveId","type":"uint256"},{"internalType":"uint256","name":"toGraveId","type":"uint256"}],"name":"claimAndMove","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"graveId","type":"uint256"}],"name":"claimAndUnstake","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"claimZombies","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"currentMieceCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"fastenDigging","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"staker","type":"address"}],"name":"getCatsStaked","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"graveId","type":"uint256"}],"name":"getCatsStakedByGraveId","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"graveId","type":"uint256"}],"name":"getDiggingCompletionTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"uint256","name":"katzId","type":"uint256"}],"name":"mintGrave","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_times","type":"uint256"}],"name":"mintReserve","outputs":[],"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":"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":"address","name":"_mieceAddress","type":"address"},{"internalType":"address","name":"_zombiesAddress","type":"address"}],"name":"setContractAddresses","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"graveId","type":"uint256"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"stakeByIds","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"traitTypes","outputs":[{"internalType":"string","name":"traitName","type":"string"},{"internalType":"string","name":"traitType","type":"string"},{"internalType":"string","name":"pixels","type":"string"},{"internalType":"uint256","name":"pixelCount","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_wallet","type":"address"}],"name":"walletOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"zombiesAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

611544600a556000600b55601380546001600160a01b031916905560016103c0818152606160f81b6103e0526080908152610400828152603160f91b6104205260a052610440828152606360f81b6104605260c052610480828152601960fa1b6104a05260e0526104c0828152606560f81b6104e05261010052610500828152603360f91b6105205261012052610540828152606760f81b6105605261014052610580828152600d60fb1b6105a052610160526105c0828152606960f81b6105e05261018052610600828152603560f91b610620526101a052610640828152606b60f81b610660526101c052610680828152601b60fa1b6106a0526101e0526106c0828152606d60f81b6106e05261020052610700828152603760f91b6107205261022052610740828152606f60f81b6107605261024052610780828152600760fc1b6107a052610260526107c0828152607160f81b6107e05261028052610800828152603960f91b610820526102a052610840828152607360f81b610860526102c052610880828152601d60fa1b6108a0526102e0526108c0828152607560f81b6108e05261030052610900828152603b60f91b6109205261032052610940828152607760f81b6109605261034052610980828152600f60fb1b6109a052610360526109c0828152607960f81b6109e05261038052610a40604052610a00918252603d60f91b610a20526103a0919091526200022190601790601a620004b5565b503480156200022f57600080fd5b506040805180820182526009815268634d7947726176657360b81b602080830191825283518085019094526005845264477261766560d81b9084015281519192916200027e9160009162000519565b5080516200029490600190602084019062000519565b5050602180546001600160a01b03191633179055506040805160e0810182526064815260c8602082015261032091810182905260608101919091526104b060808201526107d060a082015261132460c0820152620002f7906018906007620005a4565b506040805160808101825261019081526103e86020820152610c8091810191909152611518606082015262000331906019906004620005a4565b50604080516080810182526101f4815261057860208201526106409181019190915261196460608201526200036b90601a906004620005a4565b50604080516080810182526064815261019060208201526101f4918101919091526123286060820152620003a490601b906004620005a4565b506040805160e08101825260c88152610190602082015261044c91810182905260608101919091526109606080820181905260a0820181905260c0820152620003f290601c906007620005a4565b50604080516080810182526109c48082526020820181905291810182905260608101919091526200042890601d906004620005a4565b50604080516080810182526109c48082526020820181905291810182905260608101919091526200045e90601e906004620005a4565b506040805160e08101825260288152608c602082015261058c9181019190915261070860608201526107d0608082015261089860a082015261096060c0820152620004ae90601f906007620005a4565b5062000709565b82805482825590600052602060002090810192821562000507579160200282015b82811115620005075782518051620004f691849160209091019062000519565b5091602001919060010190620004d6565b50620005159291506200064f565b5090565b8280546200052790620006cc565b90600052602060002090601f0160209004810192826200054b576000855562000596565b82601f106200056657805160ff191683800117855562000596565b8280016001018555821562000596579182015b828111156200059657825182559160200191906001019062000579565b506200051592915062000670565b82805482825590600052602060002090600f01601090048101928215620005965791602002820160005b838211156200061057835183826101000a81548161ffff021916908361ffff1602179055509260200192600201602081600101049283019260010302620005ce565b8015620006405782816101000a81549061ffff021916905560020160208160010104928301926001030262000610565b50506200051592915062000670565b808211156200051557600062000666828262000687565b506001016200064f565b5b8082111562000515576000815560010162000671565b5080546200069590620006cc565b6000825580601f10620006a95750620006c9565b601f016020900490600052602060002090810190620006c9919062000670565b50565b600281046001821680620006e157607f821691505b602082108114156200070357634e487b7160e01b600052602260045260246000fd5b50919050565b6139dc80620007196000396000f3fe608060405234801561001057600080fd5b50600436106102105760003560e01c80636352211e11610125578063ab43c154116100ad578063d04061ab1161007c578063d04061ab14610469578063d102072f1461047c578063d93dfe881461048f578063e985e9c5146104a2578063f906751b146104b557610210565b8063ab43c1541461041d578063b88d4fde14610430578063c87b56dd14610443578063cd931e401461045657610210565b80637b570f2c116100f45780637b570f2c146103c95780637c197f93146103dc5780638f7f2566146103ef57806395d89b4114610402578063a22cb4651461040a57610210565b80636352211e1461038857806370a082311461039b57806372b11020146103ae578063748f7ded146103c157610210565b806327a3b4c8116101a857806332cb6b0c1161017757806332cb6b0c146103275780633ad403be1461032f57806342842e0e14610342578063438b6300146103555780634f6ccce71461037557610210565b806327a3b4c8146102d65780632f745c59146102e95780632fb098d2146102fc578063326071311461031f57610210565b8063081812fc116101e4578063081812fc1461027b578063095ea7b31461029b57806318160ddd146102ae57806323b872dd146102c357610210565b80625ea3071461021557806301ffc9a71461023e57806303e7fb781461025e57806306fdde0314610273575b600080fd5b610228610223366004612e20565b6104c8565b6040516102359190613221565b60405180910390f35b61025161024c366004612d75565b6105b3565b6040516102359190613216565b61027161026c366004612fb5565b6105d8565b005b610228610727565b61028e610289366004612e20565b6107b9565b6040516102359190613120565b6102716102a9366004612c87565b610805565b6102b661089d565b60405161023591906136d1565b6102716102d1366004612b99565b6108a3565b6102716102e4366004612f70565b6108db565b6102b66102f7366004612c87565b610bfe565b61030f61030a366004612fb5565b610c50565b6040516102359493929190613234565b6102b6610e35565b6102b6610eca565b6102b661033d366004612e20565b610ed0565b610271610350366004612b99565b610f1c565b610368610363366004612b29565b610f37565b60405161023591906131d2565b6102b6610383366004612e20565b610ff5565b61028e610396366004612e20565b611050565b6102b66103a9366004612b29565b611085565b6102716103bc366004612cb2565b6110c9565b61028e611161565b6103686103d7366004612e20565b611170565b6102716103ea366004612cb2565b6111d2565b6102716103fd366004612e20565b61135d565b610228611599565b610271610418366004612c56565b6115a8565b61025161042b366004612e20565b611676565b61027161043e366004612bd9565b61168b565b610228610451366004612e20565b6116ca565b610271610464366004612b61565b611796565b610368610477366004612b29565b6117db565b61027161048a366004612e20565b611845565b61027161049d366004612e50565b611a66565b6102516104b0366004612b61565b611bed565b6102716104c3366004612e20565b611c1b565b6000818152600e60205260408120805460609291906104e6906138b9565b80601f0160208091040260200160405190810160405280929190818152602001828054610512906138b9565b801561055f5780601f106105345761010080835404028352916020019161055f565b820191906000526020600020905b81548152906001019060200180831161054257829003601f168201915b505050600086815260146020526040902054929350505060ff16156105ad5761058b8160016009611cf2565b60405160200161059b91906130bc565b60405160208183030381529060405290505b92915050565b60006001600160e01b0319821663780e9d6360e01b14806105ad57506105ad82611de9565b6105e182611e29565b60008281526014602052604090205460ff16151560011461060157600080fd5b3361060b82611050565b6001600160a01b03161461061e57600080fd5b60005b6000838152601260205260409020548110156107005760008381526012602052604081208054339260109290918590811061066c57634e487b7160e01b600052603260045260246000fd5b600091825260208083209091015483528201929092526040019020546001600160a01b03161461069b57600080fd5b60008281526012602052604080822085835291208054839081106106cf57634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101548354600181018555938352912090910155806106f8816138f4565b915050610621565b506000828152601260205260408120610718916129ae565b610723816007611ef3565b5050565b606060008054610736906138b9565b80601f0160208091040260200160405190810160405280929190818152602001828054610762906138b9565b80156107af5780601f10610784576101008083540402835291602001916107af565b820191906000526020600020905b81548152906001019060200180831161079257829003601f168201915b5050505050905090565b60006107c482611f20565b6107e95760405162461bcd60e51b81526004016107e09061353f565b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061081082611050565b9050806001600160a01b0316836001600160a01b031614156108445760405162461bcd60e51b81526004016107e0906135d4565b806001600160a01b0316610856611f3d565b6001600160a01b031614806108725750610872816104b0611f3d565b61088e5760405162461bcd60e51b81526004016107e09061341a565b6108988383611f41565b505050565b60085490565b6108b46108ae611f3d565b82611faf565b6108d05760405162461bcd60e51b81526004016107e090613615565b610898838383612034565b80516002146108e957600080fd5b6000828152601260205260409020541561090257600080fd5b3361090c83611050565b6001600160a01b03161461091f57600080fd5b60005b8151811015610bf257601654825133916001600160a01b031690636352211e9085908590811061096257634e487b7160e01b600052603260045260246000fd5b60200260200101516040518263ffffffff1660e01b815260040161098691906136d1565b60206040518083038186803b15801561099e57600080fd5b505afa1580156109b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d69190612b45565b6001600160a01b0316148015610a44575060135482516001600160a01b0390911690601090600090859085908110610a1e57634e487b7160e01b600052603260045260246000fd5b6020908102919091018101518252810191909152604001600020546001600160a01b0316145b610a4d57600080fd5b60165482516001600160a01b03909116906323b872dd9033903090869086908110610a8857634e487b7160e01b600052603260045260246000fd5b60200260200101516040518463ffffffff1660e01b8152600401610aae93929190613134565b600060405180830381600087803b158015610ac857600080fd5b505af1158015610adc573d6000803e3d6000fd5b5050336000908152601160205260409020845190925084915083908110610b1357634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182546001810184556000938452828420015584825260129052604090208251839083908110610b5e57634e487b7160e01b600052603260045260246000fd5b602090810291909101810151825460018101845560009384529183209091015582513391601091859085908110610ba557634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508080610bea906138f4565b915050610922565b50610723826007611ef3565b6000610c0983611085565b8210610c275760405162461bcd60e51b81526004016107e09061327f565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b600c6020528160005260406000208181548110610c6c57600080fd5b906000526020600020906004020160009150915050806000018054610c90906138b9565b80601f0160208091040260200160405190810160405280929190818152602001828054610cbc906138b9565b8015610d095780601f10610cde57610100808354040283529160200191610d09565b820191906000526020600020905b815481529060010190602001808311610cec57829003601f168201915b505050505090806001018054610d1e906138b9565b80601f0160208091040260200160405190810160405280929190818152602001828054610d4a906138b9565b8015610d975780601f10610d6c57610100808354040283529160200191610d97565b820191906000526020600020905b815481529060010190602001808311610d7a57829003601f168201915b505050505090806002018054610dac906138b9565b80601f0160208091040260200160405190810160405280929190818152602001828054610dd8906138b9565b8015610e255780601f10610dfa57610100808354040283529160200191610e25565b820191906000526020600020905b815481529060010190602001808311610e0857829003601f168201915b5050505050908060030154905084565b60007391022862fc863dd812fe608db44cad0714c5833263895b6917610e5961089d565b6040518263ffffffff1660e01b8152600401610e7591906136d1565b60206040518083038186803b158015610e8d57600080fd5b505af4158015610ea1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ec59190612e38565b905090565b600a5481565b6000818152600f6020526040812054610ee857600080fd5b60008281526014602052604090205460ff16151560011415610f0957600080fd5b506000908152600f602052604090205490565b6108988383836040518060200160405280600081525061168b565b60606000610f4483611085565b905060008167ffffffffffffffff811115610f6f57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610f98578160200160208202803683370190505b50905060005b82811015610fed57610fb08582610bfe565b828281518110610fd057634e487b7160e01b600052603260045260246000fd5b602090810291909101015280610fe5816138f4565b915050610f9e565b509392505050565b6000610fff61089d565b821061101d5760405162461bcd60e51b81526004016107e090613666565b6008828154811061103e57634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050919050565b6000818152600260205260408120546001600160a01b0316806105ad5760405162461bcd60e51b81526004016107e0906134c1565b60006001600160a01b0382166110ad5760405162461bcd60e51b81526004016107e090613477565b506001600160a01b031660009081526003602052604090205490565b60005b815181101561072357601260008383815181106110f957634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000208054905060001461111f57600080fd5b61114f82828151811061114257634e487b7160e01b600052603260045260246000fd5b6020026020010151611e29565b80611159816138f4565b9150506110cc565b6016546001600160a01b031681565b6000818152601260209081526040918290208054835181840281018401909452808452606093928301828280156111c657602002820191906000526020600020905b8154815260200190600101908083116111b2575b50505050509050919050565b60005b815181101561072357602080546040805163648c9e7f60e01b815290516001600160a01b03909216926379cc67909233927391022862fc863dd812fe608db44cad0714c583329263648c9e7f92600480840193829003018186803b15801561123c57600080fd5b505af4158015611250573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112749190612e38565b6040518363ffffffff1660e01b81526004016112919291906131b9565b600060405180830381600087803b1580156112ab57600080fd5b505af11580156112bf573d6000803e3d6000fd5b5050505062015180600f60008484815181106112eb57634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000205461130c9190613876565b600f600084848151811061133057634e487b7160e01b600052603260045260246000fd5b60200260200101518152602001908152602001600020819055508080611355906138f4565b9150506111d5565b600061136761089d565b9050600a54811061137757600080fd5b8061138481336000612161565b6000828152600e6020908152604090912082516113a793919291909101906129cc565b506001600d600e60008481526020019081526020016000206040516113cc919061304d565b90815260405160209181900382019020805460ff191692151592909217909155546001600160a01b03166379cc679033611404610e35565b6040518363ffffffff1660e01b81526004016114219291906131b9565b600060405180830381600087803b15801561143b57600080fd5b505af115801561144f573d6000803e3d6000fd5b505050506103e882101561158f57602054604051632975bbcb60e11b815260009182916001600160a01b03909116906352eb779690611492903390600401613120565b600060405180830381600087803b1580156114ac57600080fd5b505af11580156114c0573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526114e89190810190612ce5565b905060005b815181101561153c5781818151811061151657634e487b7160e01b600052603260045260246000fd5b602002602001015186141561152a57600192505b80611534816138f4565b9150506114ed565b5060018215151461154c57600080fd5b60008581526015602052604090205460ff161561156857600080fd5b6000858152601560205260409020805460ff1916600117905561158c836007611ef3565b50505b6108983382612300565b606060018054610736906138b9565b6115b0611f3d565b6001600160a01b0316826001600160a01b031614156115e15760405162461bcd60e51b81526004016107e090613397565b80600560006115ee611f3d565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155611632611f3d565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161166a9190613216565b60405180910390a35050565b60009081526015602052604090205460ff1690565b61169c611696611f3d565b83611faf565b6116b85760405162461bcd60e51b81526004016107e090613615565b6116c4848484846123df565b50505050565b60606116d582611f20565b6116de57600080fd5b60006116e9836104c8565b6000848152600f602052604090819020549051630ac01bd560e21b81529192507391022862fc863dd812fe608db44cad0714c5833291632b006f549161173b9187918691600c916017916004016136da565b60006040518083038186803b15801561175357600080fd5b505af4158015611767573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261178f9190810190612dad565b9392505050565b6021546001600160a01b031633146117ad57600080fd5b602080546001600160a01b039384166001600160a01b03199182161790915560168054929093169116179055565b6001600160a01b0381166000908152601160209081526040918290208054835181840281018401909452808452606093928301828280156111c657602002820191906000526020600020908154815260200190600101908083116111b25750505050509050919050565b61184e81611e29565b60008181526014602052604090205460ff16151560011461186e57600080fd5b60005b600082815260126020526040902054811015610723576000828152601260205260408120805433926010929091859081106118bc57634e487b7160e01b600052603260045260246000fd5b600091825260208083209091015483528201929092526040019020546001600160a01b0316146118eb57600080fd5b601654600083815260126020526040902080546001600160a01b03909216916323b872dd9130913391908690811061193357634e487b7160e01b600052603260045260246000fd5b90600052602060002001546040518463ffffffff1660e01b815260040161195c93929190613134565b600060405180830381600087803b15801561197657600080fd5b505af115801561198a573d6000803e3d6000fd5b505050506119d4336012600085815260200190815260200160002083815481106119c457634e487b7160e01b600052603260045260246000fd5b9060005260206000200154612412565b601354600083815260126020526040812080546001600160a01b0390931692601092919085908110611a1657634e487b7160e01b600052603260045260246000fd5b9060005260206000200154815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508080611a5e906138f4565b915050611871565b6021546001600160a01b03163314611a7d57600080fd5b60005b815181101561089857600c60008481526020019081526020016000206040518060800160405280848481518110611ac757634e487b7160e01b600052603260045260246000fd5b6020026020010151600001518152602001848481518110611af857634e487b7160e01b600052603260045260246000fd5b6020026020010151602001518152602001848481518110611b2957634e487b7160e01b600052603260045260246000fd5b6020026020010151604001518152602001848481518110611b5a57634e487b7160e01b600052603260045260246000fd5b60209081029190910181015160600151909152825460018101845560009384529281902082518051939460040290910192611b9892849201906129cc565b506020828101518051611bb192600185019201906129cc565b5060408201518051611bcd9160028401916020909101906129cc565b506060820151816003015550508080611be5906138f4565b915050611a80565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6021546001600160a01b03163314611c3257600080fd5b60005b81811015610723576000611c4761089d565b905060328110611c5657600080fd5b611c6281336000612161565b6000828152600e602090815260409091208251611c8593919291909101906129cc565b506001600d600e6000848152602001908152602001600020604051611caa919061304d565b908152604051908190036020019020805491151560ff19909216919091179055611cd5816007611ef3565b611cdf3382612300565b5080611cea816138f4565b915050611c35565b6060836000611d018585613876565b67ffffffffffffffff811115611d2757634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611d51576020820181803683370190505b509050845b84811015611ddf57828181518110611d7e57634e487b7160e01b600052603260045260246000fd5b01602001516001600160f81b03191682611d988884613876565b81518110611db657634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535080611dd7816138f4565b915050611d56565b5095945050505050565b60006001600160e01b031982166380ac58cd60e01b1480611e1a57506001600160e01b03198216635b5e139f60e01b145b806105ad57506105ad8261249d565b33611e3382611050565b6001600160a01b031614611e4657600080fd5b6000818152600f60205260409020544211611e6057600080fd5b6016546001600160a01b0316632cc8447633611e7b846104c8565b6040518363ffffffff1660e01b8152600401611e98929190613195565b600060405180830381600087803b158015611eb257600080fd5b505af1158015611ec6573d6000803e3d6000fd5b5050506000828152601460205260409020805460ff1916600117905550611ef03361dead83612034565b50565b611f008162015180613857565b611f0a904261383f565b6000928352600f60205260409092209190915550565b6000908152600260205260409020546001600160a01b0316151590565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611f7682611050565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611fba82611f20565b611fd65760405162461bcd60e51b81526004016107e0906133ce565b6000611fe183611050565b9050806001600160a01b0316846001600160a01b0316148061201c5750836001600160a01b0316612011846107b9565b6001600160a01b0316145b8061202c575061202c8185611bed565b949350505050565b826001600160a01b031661204782611050565b6001600160a01b03161461206d5760405162461bcd60e51b81526004016107e09061358b565b6001600160a01b0382166120935760405162461bcd60e51b81526004016107e090613353565b61209e8383836124b6565b6120a9600082611f41565b6001600160a01b03831660009081526003602052604081208054600192906120d2908490613876565b90915550506001600160a01b038216600090815260036020526040812080546001929061210090849061383f565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6060600a821061217057600080fd5b6040805180820190915260018152600360fc1b602082015260005b60088160ff1610156122ba57600b80549060006121a7836138f4565b919050555060006127104244898989600b546040516020016121ce969594939291906130e5565b6040516020818303038152906040528051906020012060001c6121f1919061392f565b9050827391022862fc863dd812fe608db44cad0714c5833263ee3a84da838560186040518463ffffffff1660e01b8152600401612230939291906136b2565b60006040518083038186803b15801561224857600080fd5b505af415801561225c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526122849190810190612dad565b60405160200161229592919061301e565b60405160208183030381529060405292505080806122b29061390f565b91505061218b565b50600d816040516122cb9190613002565b9081526040519081900360200190205460ff161561202c576122f885856122f386600161383f565b612161565b91505061178f565b6001600160a01b0382166123265760405162461bcd60e51b81526004016107e09061350a565b61232f81611f20565b1561234c5760405162461bcd60e51b81526004016107e09061331c565b612358600083836124b6565b6001600160a01b038216600090815260036020526040812080546001929061238190849061383f565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6123ea848484612034565b6123f68484848461253f565b6116c45760405162461bcd60e51b81526004016107e0906132ca565b60005b6001600160a01b038316600090815260116020526040902054811015610898576001600160a01b038316600090815260116020526040902080548391908390811061247057634e487b7160e01b600052603260045260246000fd5b9060005260206000200154141561248b5761248b838261265a565b80612495816138f4565b915050612415565b6001600160e01b031981166301ffc9a760e01b14919050565b6124c1838383610898565b6001600160a01b0383166124dd576124d8816127aa565b612500565b816001600160a01b0316836001600160a01b0316146125005761250083826127ee565b6001600160a01b03821661251c576125178161288b565b610898565b826001600160a01b0316826001600160a01b031614610898576108988282612964565b6000612553846001600160a01b03166129a8565b1561264f57836001600160a01b031663150b7a0261256f611f3d565b8786866040518563ffffffff1660e01b81526004016125919493929190613158565b602060405180830381600087803b1580156125ab57600080fd5b505af19250505080156125db575060408051601f3d908101601f191682019092526125d891810190612d91565b60015b612635573d808015612609576040519150601f19603f3d011682016040523d82523d6000602084013e61260e565b606091505b50805161262d5760405162461bcd60e51b81526004016107e0906132ca565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061202c565b506001949350505050565b6001600160a01b038216600090815260116020526040902054811061267e57610723565b805b6001600160a01b0383166000908152601160205260409020546126a590600190613876565b81101561275a576001600160a01b03831660009081526011602052604090206126cf82600161383f565b815481106126ed57634e487b7160e01b600052603260045260246000fd5b906000526020600020015460116000856001600160a01b03166001600160a01b03168152602001908152602001600020828154811061273c57634e487b7160e01b600052603260045260246000fd5b60009182526020909120015580612752816138f4565b915050612680565b506001600160a01b038216600090815260116020526040902080548061279057634e487b7160e01b600052603160045260246000fd5b600190038181906000526020600020016000905590555050565b600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b600060016127fb84611085565b6128059190613876565b600083815260076020526040902054909150808214612858576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061289d90600190613876565b600083815260096020526040812054600880549394509092849081106128d357634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050806008838154811061290257634e487b7160e01b600052603260045260246000fd5b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061294857634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905550505050565b600061296f83611085565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b3b151590565b5080546000825590600052602060002090810190611ef09190612a50565b8280546129d8906138b9565b90600052602060002090601f0160209004810192826129fa5760008555612a40565b82601f10612a1357805160ff1916838001178555612a40565b82800160010185558215612a40579182015b82811115612a40578251825591602001919060010190612a25565b50612a4c929150612a50565b5090565b5b80821115612a4c5760008155600101612a51565b6000612a78612a7384613817565b6137c9565b9050828152838383011115612a8c57600080fd5b828260208301376000602084830101529392505050565b600082601f830112612ab3578081fd5b81356020612ac3612a73836137f3565b8281528181019085830183850287018401881015612adf578586fd5b855b85811015612afd57813584529284019290840190600101612ae1565b5090979650505050505050565b600082601f830112612b1a578081fd5b61178f83833560208501612a65565b600060208284031215612b3a578081fd5b813561178f8161397b565b600060208284031215612b56578081fd5b815161178f8161397b565b60008060408385031215612b73578081fd5b8235612b7e8161397b565b91506020830135612b8e8161397b565b809150509250929050565b600080600060608486031215612bad578081fd5b8335612bb88161397b565b92506020840135612bc88161397b565b929592945050506040919091013590565b60008060008060808587031215612bee578182fd5b8435612bf98161397b565b93506020850135612c098161397b565b925060408501359150606085013567ffffffffffffffff811115612c2b578182fd5b8501601f81018713612c3b578182fd5b612c4a87823560208401612a65565b91505092959194509250565b60008060408385031215612c68578182fd5b8235612c738161397b565b915060208301358015158114612b8e578182fd5b60008060408385031215612c99578182fd5b8235612ca48161397b565b946020939093013593505050565b600060208284031215612cc3578081fd5b813567ffffffffffffffff811115612cd9578182fd5b61202c84828501612aa3565b60006020808385031215612cf7578182fd5b825167ffffffffffffffff811115612d0d578283fd5b8301601f81018513612d1d578283fd5b8051612d2b612a73826137f3565b8181528381019083850185840285018601891015612d47578687fd5b8694505b83851015612d69578051835260019490940193918501918501612d4b565b50979650505050505050565b600060208284031215612d86578081fd5b813561178f81613990565b600060208284031215612da2578081fd5b815161178f81613990565b600060208284031215612dbe578081fd5b815167ffffffffffffffff811115612dd4578182fd5b8201601f81018413612de4578182fd5b8051612df2612a7382613817565b818152856020838501011115612e06578384fd5b612e1782602083016020860161388d565b95945050505050565b600060208284031215612e31578081fd5b5035919050565b600060208284031215612e49578081fd5b5051919050565b60008060408385031215612e62578182fd5b8235915060208084013567ffffffffffffffff80821115612e81578384fd5b818601915086601f830112612e94578384fd5b8135612ea2612a73826137f3565b81815284810190848601875b84811015612f5f57813587016080818e03601f19011215612ecd57898afd5b612ed760806137c9565b8982013588811115612ee7578b8cfd5b612ef58f8c83860101612b0a565b825250604082013588811115612f09578b8cfd5b612f178f8c83860101612b0a565b8b83015250606082013588811115612f2d578b8cfd5b612f3b8f8c83860101612b0a565b60408301525060809190910135606082015284529287019290870190600101612eae565b50979a909950975050505050505050565b60008060408385031215612f82578182fd5b82359150602083013567ffffffffffffffff811115612f9f578182fd5b612fab85828601612aa3565b9150509250929050565b60008060408385031215612fc7578182fd5b50508035926020909101359150565b60008151808452612fee81602086016020860161388d565b601f01601f19169290920160200192915050565b6000825161301481846020870161388d565b9190910192915050565b6000835161303081846020880161388d565b83519083019061304481836020880161388d565b01949350505050565b600080835461305b816138b9565b600182811680156130735760018114613084576130b0565b60ff198416875282870194506130b0565b8786526020808720875b858110156130a75781548a82015290840190820161308e565b50505082870194505b50929695505050505050565b6000603160f81b825282516130d881600185016020870161388d565b9190910160010192915050565b95865260208601949094526040850192909252606090811b6bffffffffffffffffffffffff1916908401526074830152609482015260b40190565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061318b90830184612fd6565b9695505050505050565b6001600160a01b038316815260406020820181905260009061202c90830184612fd6565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b8181101561320a578351835292840192918401916001016131ee565b50909695505050505050565b901515815260200190565b60006020825261178f6020830184612fd6565b6000608082526132476080830187612fd6565b82810360208401526132598187612fd6565b9050828103604084015261326d8186612fd6565b91505082606083015295945050505050565b6020808252602b908201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560408201526a74206f6620626f756e647360a81b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252601c908201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604082015260600190565b60208082526024908201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526019908201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604082015260600190565b6020808252602c908201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b60208082526038908201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760408201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606082015260800190565b6020808252602a908201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604082015269726f206164647265737360b01b606082015260800190565b60208082526029908201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460408201526832b73a103a37b5b2b760b91b606082015260800190565b6020808252818101527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b6020808252602c908201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b60208082526029908201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960408201526839903737ba1037bbb760b91b606082015260800190565b60208082526021908201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656040820152603960f91b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252602c908201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60408201526b7574206f6620626f756e647360a01b606082015260800190565b61ffff93909316835260ff919091166020830152604082015260600190565b90815260200190565b6000868252602060a0818401526136f460a0840188612fd6565b604087818601528482036060860152818754808452848401915084858202850101898752858720875b838110156137ae57601f1987840301855288825461373a816138b9565b80865260018281168015613755576001811461376857613797565b60ff198416888e01528a88019450613797565b868e528c8e208e5b8481101561378f5781548f828c01015283820191508e81019050613770565b89018e019550505b50978b01979295505050919091019060010161371d565b50508096505050505050508260808301529695505050505050565b60405181810167ffffffffffffffff811182821017156137eb576137eb613965565b604052919050565b600067ffffffffffffffff82111561380d5761380d613965565b5060209081020190565b600067ffffffffffffffff82111561383157613831613965565b50601f01601f191660200190565b600082198211156138525761385261394f565b500190565b60008160001904831182151516156138715761387161394f565b500290565b6000828210156138885761388861394f565b500390565b60005b838110156138a8578181015183820152602001613890565b838111156116c45750506000910152565b6002810460018216806138cd57607f821691505b602082108114156138ee57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156139085761390861394f565b5060010190565b600060ff821660ff8114156139265761392661394f565b60010192915050565b60008261394a57634e487b7160e01b81526012600452602481fd5b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114611ef057600080fd5b6001600160e01b031981168114611ef057600080fdfea2646970667358221220b56eec5563315257b0860708059d136b235fabda504ac5c3cad48931dcbd6afa64736f6c63430008000033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102105760003560e01c80636352211e11610125578063ab43c154116100ad578063d04061ab1161007c578063d04061ab14610469578063d102072f1461047c578063d93dfe881461048f578063e985e9c5146104a2578063f906751b146104b557610210565b8063ab43c1541461041d578063b88d4fde14610430578063c87b56dd14610443578063cd931e401461045657610210565b80637b570f2c116100f45780637b570f2c146103c95780637c197f93146103dc5780638f7f2566146103ef57806395d89b4114610402578063a22cb4651461040a57610210565b80636352211e1461038857806370a082311461039b57806372b11020146103ae578063748f7ded146103c157610210565b806327a3b4c8116101a857806332cb6b0c1161017757806332cb6b0c146103275780633ad403be1461032f57806342842e0e14610342578063438b6300146103555780634f6ccce71461037557610210565b806327a3b4c8146102d65780632f745c59146102e95780632fb098d2146102fc578063326071311461031f57610210565b8063081812fc116101e4578063081812fc1461027b578063095ea7b31461029b57806318160ddd146102ae57806323b872dd146102c357610210565b80625ea3071461021557806301ffc9a71461023e57806303e7fb781461025e57806306fdde0314610273575b600080fd5b610228610223366004612e20565b6104c8565b6040516102359190613221565b60405180910390f35b61025161024c366004612d75565b6105b3565b6040516102359190613216565b61027161026c366004612fb5565b6105d8565b005b610228610727565b61028e610289366004612e20565b6107b9565b6040516102359190613120565b6102716102a9366004612c87565b610805565b6102b661089d565b60405161023591906136d1565b6102716102d1366004612b99565b6108a3565b6102716102e4366004612f70565b6108db565b6102b66102f7366004612c87565b610bfe565b61030f61030a366004612fb5565b610c50565b6040516102359493929190613234565b6102b6610e35565b6102b6610eca565b6102b661033d366004612e20565b610ed0565b610271610350366004612b99565b610f1c565b610368610363366004612b29565b610f37565b60405161023591906131d2565b6102b6610383366004612e20565b610ff5565b61028e610396366004612e20565b611050565b6102b66103a9366004612b29565b611085565b6102716103bc366004612cb2565b6110c9565b61028e611161565b6103686103d7366004612e20565b611170565b6102716103ea366004612cb2565b6111d2565b6102716103fd366004612e20565b61135d565b610228611599565b610271610418366004612c56565b6115a8565b61025161042b366004612e20565b611676565b61027161043e366004612bd9565b61168b565b610228610451366004612e20565b6116ca565b610271610464366004612b61565b611796565b610368610477366004612b29565b6117db565b61027161048a366004612e20565b611845565b61027161049d366004612e50565b611a66565b6102516104b0366004612b61565b611bed565b6102716104c3366004612e20565b611c1b565b6000818152600e60205260408120805460609291906104e6906138b9565b80601f0160208091040260200160405190810160405280929190818152602001828054610512906138b9565b801561055f5780601f106105345761010080835404028352916020019161055f565b820191906000526020600020905b81548152906001019060200180831161054257829003601f168201915b505050600086815260146020526040902054929350505060ff16156105ad5761058b8160016009611cf2565b60405160200161059b91906130bc565b60405160208183030381529060405290505b92915050565b60006001600160e01b0319821663780e9d6360e01b14806105ad57506105ad82611de9565b6105e182611e29565b60008281526014602052604090205460ff16151560011461060157600080fd5b3361060b82611050565b6001600160a01b03161461061e57600080fd5b60005b6000838152601260205260409020548110156107005760008381526012602052604081208054339260109290918590811061066c57634e487b7160e01b600052603260045260246000fd5b600091825260208083209091015483528201929092526040019020546001600160a01b03161461069b57600080fd5b60008281526012602052604080822085835291208054839081106106cf57634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101548354600181018555938352912090910155806106f8816138f4565b915050610621565b506000828152601260205260408120610718916129ae565b610723816007611ef3565b5050565b606060008054610736906138b9565b80601f0160208091040260200160405190810160405280929190818152602001828054610762906138b9565b80156107af5780601f10610784576101008083540402835291602001916107af565b820191906000526020600020905b81548152906001019060200180831161079257829003601f168201915b5050505050905090565b60006107c482611f20565b6107e95760405162461bcd60e51b81526004016107e09061353f565b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061081082611050565b9050806001600160a01b0316836001600160a01b031614156108445760405162461bcd60e51b81526004016107e0906135d4565b806001600160a01b0316610856611f3d565b6001600160a01b031614806108725750610872816104b0611f3d565b61088e5760405162461bcd60e51b81526004016107e09061341a565b6108988383611f41565b505050565b60085490565b6108b46108ae611f3d565b82611faf565b6108d05760405162461bcd60e51b81526004016107e090613615565b610898838383612034565b80516002146108e957600080fd5b6000828152601260205260409020541561090257600080fd5b3361090c83611050565b6001600160a01b03161461091f57600080fd5b60005b8151811015610bf257601654825133916001600160a01b031690636352211e9085908590811061096257634e487b7160e01b600052603260045260246000fd5b60200260200101516040518263ffffffff1660e01b815260040161098691906136d1565b60206040518083038186803b15801561099e57600080fd5b505afa1580156109b2573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109d69190612b45565b6001600160a01b0316148015610a44575060135482516001600160a01b0390911690601090600090859085908110610a1e57634e487b7160e01b600052603260045260246000fd5b6020908102919091018101518252810191909152604001600020546001600160a01b0316145b610a4d57600080fd5b60165482516001600160a01b03909116906323b872dd9033903090869086908110610a8857634e487b7160e01b600052603260045260246000fd5b60200260200101516040518463ffffffff1660e01b8152600401610aae93929190613134565b600060405180830381600087803b158015610ac857600080fd5b505af1158015610adc573d6000803e3d6000fd5b5050336000908152601160205260409020845190925084915083908110610b1357634e487b7160e01b600052603260045260246000fd5b60209081029190910181015182546001810184556000938452828420015584825260129052604090208251839083908110610b5e57634e487b7160e01b600052603260045260246000fd5b602090810291909101810151825460018101845560009384529183209091015582513391601091859085908110610ba557634e487b7160e01b600052603260045260246000fd5b6020026020010151815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508080610bea906138f4565b915050610922565b50610723826007611ef3565b6000610c0983611085565b8210610c275760405162461bcd60e51b81526004016107e09061327f565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b600c6020528160005260406000208181548110610c6c57600080fd5b906000526020600020906004020160009150915050806000018054610c90906138b9565b80601f0160208091040260200160405190810160405280929190818152602001828054610cbc906138b9565b8015610d095780601f10610cde57610100808354040283529160200191610d09565b820191906000526020600020905b815481529060010190602001808311610cec57829003601f168201915b505050505090806001018054610d1e906138b9565b80601f0160208091040260200160405190810160405280929190818152602001828054610d4a906138b9565b8015610d975780601f10610d6c57610100808354040283529160200191610d97565b820191906000526020600020905b815481529060010190602001808311610d7a57829003601f168201915b505050505090806002018054610dac906138b9565b80601f0160208091040260200160405190810160405280929190818152602001828054610dd8906138b9565b8015610e255780601f10610dfa57610100808354040283529160200191610e25565b820191906000526020600020905b815481529060010190602001808311610e0857829003601f168201915b5050505050908060030154905084565b60007391022862fc863dd812fe608db44cad0714c5833263895b6917610e5961089d565b6040518263ffffffff1660e01b8152600401610e7591906136d1565b60206040518083038186803b158015610e8d57600080fd5b505af4158015610ea1573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ec59190612e38565b905090565b600a5481565b6000818152600f6020526040812054610ee857600080fd5b60008281526014602052604090205460ff16151560011415610f0957600080fd5b506000908152600f602052604090205490565b6108988383836040518060200160405280600081525061168b565b60606000610f4483611085565b905060008167ffffffffffffffff811115610f6f57634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610f98578160200160208202803683370190505b50905060005b82811015610fed57610fb08582610bfe565b828281518110610fd057634e487b7160e01b600052603260045260246000fd5b602090810291909101015280610fe5816138f4565b915050610f9e565b509392505050565b6000610fff61089d565b821061101d5760405162461bcd60e51b81526004016107e090613666565b6008828154811061103e57634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050919050565b6000818152600260205260408120546001600160a01b0316806105ad5760405162461bcd60e51b81526004016107e0906134c1565b60006001600160a01b0382166110ad5760405162461bcd60e51b81526004016107e090613477565b506001600160a01b031660009081526003602052604090205490565b60005b815181101561072357601260008383815181106110f957634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000208054905060001461111f57600080fd5b61114f82828151811061114257634e487b7160e01b600052603260045260246000fd5b6020026020010151611e29565b80611159816138f4565b9150506110cc565b6016546001600160a01b031681565b6000818152601260209081526040918290208054835181840281018401909452808452606093928301828280156111c657602002820191906000526020600020905b8154815260200190600101908083116111b2575b50505050509050919050565b60005b815181101561072357602080546040805163648c9e7f60e01b815290516001600160a01b03909216926379cc67909233927391022862fc863dd812fe608db44cad0714c583329263648c9e7f92600480840193829003018186803b15801561123c57600080fd5b505af4158015611250573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112749190612e38565b6040518363ffffffff1660e01b81526004016112919291906131b9565b600060405180830381600087803b1580156112ab57600080fd5b505af11580156112bf573d6000803e3d6000fd5b5050505062015180600f60008484815181106112eb57634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000205461130c9190613876565b600f600084848151811061133057634e487b7160e01b600052603260045260246000fd5b60200260200101518152602001908152602001600020819055508080611355906138f4565b9150506111d5565b600061136761089d565b9050600a54811061137757600080fd5b8061138481336000612161565b6000828152600e6020908152604090912082516113a793919291909101906129cc565b506001600d600e60008481526020019081526020016000206040516113cc919061304d565b90815260405160209181900382019020805460ff191692151592909217909155546001600160a01b03166379cc679033611404610e35565b6040518363ffffffff1660e01b81526004016114219291906131b9565b600060405180830381600087803b15801561143b57600080fd5b505af115801561144f573d6000803e3d6000fd5b505050506103e882101561158f57602054604051632975bbcb60e11b815260009182916001600160a01b03909116906352eb779690611492903390600401613120565b600060405180830381600087803b1580156114ac57600080fd5b505af11580156114c0573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526114e89190810190612ce5565b905060005b815181101561153c5781818151811061151657634e487b7160e01b600052603260045260246000fd5b602002602001015186141561152a57600192505b80611534816138f4565b9150506114ed565b5060018215151461154c57600080fd5b60008581526015602052604090205460ff161561156857600080fd5b6000858152601560205260409020805460ff1916600117905561158c836007611ef3565b50505b6108983382612300565b606060018054610736906138b9565b6115b0611f3d565b6001600160a01b0316826001600160a01b031614156115e15760405162461bcd60e51b81526004016107e090613397565b80600560006115ee611f3d565b6001600160a01b03908116825260208083019390935260409182016000908120918716808252919093529120805460ff191692151592909217909155611632611f3d565b6001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161166a9190613216565b60405180910390a35050565b60009081526015602052604090205460ff1690565b61169c611696611f3d565b83611faf565b6116b85760405162461bcd60e51b81526004016107e090613615565b6116c4848484846123df565b50505050565b60606116d582611f20565b6116de57600080fd5b60006116e9836104c8565b6000848152600f602052604090819020549051630ac01bd560e21b81529192507391022862fc863dd812fe608db44cad0714c5833291632b006f549161173b9187918691600c916017916004016136da565b60006040518083038186803b15801561175357600080fd5b505af4158015611767573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f1916820160405261178f9190810190612dad565b9392505050565b6021546001600160a01b031633146117ad57600080fd5b602080546001600160a01b039384166001600160a01b03199182161790915560168054929093169116179055565b6001600160a01b0381166000908152601160209081526040918290208054835181840281018401909452808452606093928301828280156111c657602002820191906000526020600020908154815260200190600101908083116111b25750505050509050919050565b61184e81611e29565b60008181526014602052604090205460ff16151560011461186e57600080fd5b60005b600082815260126020526040902054811015610723576000828152601260205260408120805433926010929091859081106118bc57634e487b7160e01b600052603260045260246000fd5b600091825260208083209091015483528201929092526040019020546001600160a01b0316146118eb57600080fd5b601654600083815260126020526040902080546001600160a01b03909216916323b872dd9130913391908690811061193357634e487b7160e01b600052603260045260246000fd5b90600052602060002001546040518463ffffffff1660e01b815260040161195c93929190613134565b600060405180830381600087803b15801561197657600080fd5b505af115801561198a573d6000803e3d6000fd5b505050506119d4336012600085815260200190815260200160002083815481106119c457634e487b7160e01b600052603260045260246000fd5b9060005260206000200154612412565b601354600083815260126020526040812080546001600160a01b0390931692601092919085908110611a1657634e487b7160e01b600052603260045260246000fd5b9060005260206000200154815260200190815260200160002060006101000a8154816001600160a01b0302191690836001600160a01b031602179055508080611a5e906138f4565b915050611871565b6021546001600160a01b03163314611a7d57600080fd5b60005b815181101561089857600c60008481526020019081526020016000206040518060800160405280848481518110611ac757634e487b7160e01b600052603260045260246000fd5b6020026020010151600001518152602001848481518110611af857634e487b7160e01b600052603260045260246000fd5b6020026020010151602001518152602001848481518110611b2957634e487b7160e01b600052603260045260246000fd5b6020026020010151604001518152602001848481518110611b5a57634e487b7160e01b600052603260045260246000fd5b60209081029190910181015160600151909152825460018101845560009384529281902082518051939460040290910192611b9892849201906129cc565b506020828101518051611bb192600185019201906129cc565b5060408201518051611bcd9160028401916020909101906129cc565b506060820151816003015550508080611be5906138f4565b915050611a80565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6021546001600160a01b03163314611c3257600080fd5b60005b81811015610723576000611c4761089d565b905060328110611c5657600080fd5b611c6281336000612161565b6000828152600e602090815260409091208251611c8593919291909101906129cc565b506001600d600e6000848152602001908152602001600020604051611caa919061304d565b908152604051908190036020019020805491151560ff19909216919091179055611cd5816007611ef3565b611cdf3382612300565b5080611cea816138f4565b915050611c35565b6060836000611d018585613876565b67ffffffffffffffff811115611d2757634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611d51576020820181803683370190505b509050845b84811015611ddf57828181518110611d7e57634e487b7160e01b600052603260045260246000fd5b01602001516001600160f81b03191682611d988884613876565b81518110611db657634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535080611dd7816138f4565b915050611d56565b5095945050505050565b60006001600160e01b031982166380ac58cd60e01b1480611e1a57506001600160e01b03198216635b5e139f60e01b145b806105ad57506105ad8261249d565b33611e3382611050565b6001600160a01b031614611e4657600080fd5b6000818152600f60205260409020544211611e6057600080fd5b6016546001600160a01b0316632cc8447633611e7b846104c8565b6040518363ffffffff1660e01b8152600401611e98929190613195565b600060405180830381600087803b158015611eb257600080fd5b505af1158015611ec6573d6000803e3d6000fd5b5050506000828152601460205260409020805460ff1916600117905550611ef03361dead83612034565b50565b611f008162015180613857565b611f0a904261383f565b6000928352600f60205260409092209190915550565b6000908152600260205260409020546001600160a01b0316151590565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611f7682611050565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611fba82611f20565b611fd65760405162461bcd60e51b81526004016107e0906133ce565b6000611fe183611050565b9050806001600160a01b0316846001600160a01b0316148061201c5750836001600160a01b0316612011846107b9565b6001600160a01b0316145b8061202c575061202c8185611bed565b949350505050565b826001600160a01b031661204782611050565b6001600160a01b03161461206d5760405162461bcd60e51b81526004016107e09061358b565b6001600160a01b0382166120935760405162461bcd60e51b81526004016107e090613353565b61209e8383836124b6565b6120a9600082611f41565b6001600160a01b03831660009081526003602052604081208054600192906120d2908490613876565b90915550506001600160a01b038216600090815260036020526040812080546001929061210090849061383f565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6060600a821061217057600080fd5b6040805180820190915260018152600360fc1b602082015260005b60088160ff1610156122ba57600b80549060006121a7836138f4565b919050555060006127104244898989600b546040516020016121ce969594939291906130e5565b6040516020818303038152906040528051906020012060001c6121f1919061392f565b9050827391022862fc863dd812fe608db44cad0714c5833263ee3a84da838560186040518463ffffffff1660e01b8152600401612230939291906136b2565b60006040518083038186803b15801561224857600080fd5b505af415801561225c573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526122849190810190612dad565b60405160200161229592919061301e565b60405160208183030381529060405292505080806122b29061390f565b91505061218b565b50600d816040516122cb9190613002565b9081526040519081900360200190205460ff161561202c576122f885856122f386600161383f565b612161565b91505061178f565b6001600160a01b0382166123265760405162461bcd60e51b81526004016107e09061350a565b61232f81611f20565b1561234c5760405162461bcd60e51b81526004016107e09061331c565b612358600083836124b6565b6001600160a01b038216600090815260036020526040812080546001929061238190849061383f565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6123ea848484612034565b6123f68484848461253f565b6116c45760405162461bcd60e51b81526004016107e0906132ca565b60005b6001600160a01b038316600090815260116020526040902054811015610898576001600160a01b038316600090815260116020526040902080548391908390811061247057634e487b7160e01b600052603260045260246000fd5b9060005260206000200154141561248b5761248b838261265a565b80612495816138f4565b915050612415565b6001600160e01b031981166301ffc9a760e01b14919050565b6124c1838383610898565b6001600160a01b0383166124dd576124d8816127aa565b612500565b816001600160a01b0316836001600160a01b0316146125005761250083826127ee565b6001600160a01b03821661251c576125178161288b565b610898565b826001600160a01b0316826001600160a01b031614610898576108988282612964565b6000612553846001600160a01b03166129a8565b1561264f57836001600160a01b031663150b7a0261256f611f3d565b8786866040518563ffffffff1660e01b81526004016125919493929190613158565b602060405180830381600087803b1580156125ab57600080fd5b505af19250505080156125db575060408051601f3d908101601f191682019092526125d891810190612d91565b60015b612635573d808015612609576040519150601f19603f3d011682016040523d82523d6000602084013e61260e565b606091505b50805161262d5760405162461bcd60e51b81526004016107e0906132ca565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061202c565b506001949350505050565b6001600160a01b038216600090815260116020526040902054811061267e57610723565b805b6001600160a01b0383166000908152601160205260409020546126a590600190613876565b81101561275a576001600160a01b03831660009081526011602052604090206126cf82600161383f565b815481106126ed57634e487b7160e01b600052603260045260246000fd5b906000526020600020015460116000856001600160a01b03166001600160a01b03168152602001908152602001600020828154811061273c57634e487b7160e01b600052603260045260246000fd5b60009182526020909120015580612752816138f4565b915050612680565b506001600160a01b038216600090815260116020526040902080548061279057634e487b7160e01b600052603160045260246000fd5b600190038181906000526020600020016000905590555050565b600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b600060016127fb84611085565b6128059190613876565b600083815260076020526040902054909150808214612858576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061289d90600190613876565b600083815260096020526040812054600880549394509092849081106128d357634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050806008838154811061290257634e487b7160e01b600052603260045260246000fd5b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061294857634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905550505050565b600061296f83611085565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b3b151590565b5080546000825590600052602060002090810190611ef09190612a50565b8280546129d8906138b9565b90600052602060002090601f0160209004810192826129fa5760008555612a40565b82601f10612a1357805160ff1916838001178555612a40565b82800160010185558215612a40579182015b82811115612a40578251825591602001919060010190612a25565b50612a4c929150612a50565b5090565b5b80821115612a4c5760008155600101612a51565b6000612a78612a7384613817565b6137c9565b9050828152838383011115612a8c57600080fd5b828260208301376000602084830101529392505050565b600082601f830112612ab3578081fd5b81356020612ac3612a73836137f3565b8281528181019085830183850287018401881015612adf578586fd5b855b85811015612afd57813584529284019290840190600101612ae1565b5090979650505050505050565b600082601f830112612b1a578081fd5b61178f83833560208501612a65565b600060208284031215612b3a578081fd5b813561178f8161397b565b600060208284031215612b56578081fd5b815161178f8161397b565b60008060408385031215612b73578081fd5b8235612b7e8161397b565b91506020830135612b8e8161397b565b809150509250929050565b600080600060608486031215612bad578081fd5b8335612bb88161397b565b92506020840135612bc88161397b565b929592945050506040919091013590565b60008060008060808587031215612bee578182fd5b8435612bf98161397b565b93506020850135612c098161397b565b925060408501359150606085013567ffffffffffffffff811115612c2b578182fd5b8501601f81018713612c3b578182fd5b612c4a87823560208401612a65565b91505092959194509250565b60008060408385031215612c68578182fd5b8235612c738161397b565b915060208301358015158114612b8e578182fd5b60008060408385031215612c99578182fd5b8235612ca48161397b565b946020939093013593505050565b600060208284031215612cc3578081fd5b813567ffffffffffffffff811115612cd9578182fd5b61202c84828501612aa3565b60006020808385031215612cf7578182fd5b825167ffffffffffffffff811115612d0d578283fd5b8301601f81018513612d1d578283fd5b8051612d2b612a73826137f3565b8181528381019083850185840285018601891015612d47578687fd5b8694505b83851015612d69578051835260019490940193918501918501612d4b565b50979650505050505050565b600060208284031215612d86578081fd5b813561178f81613990565b600060208284031215612da2578081fd5b815161178f81613990565b600060208284031215612dbe578081fd5b815167ffffffffffffffff811115612dd4578182fd5b8201601f81018413612de4578182fd5b8051612df2612a7382613817565b818152856020838501011115612e06578384fd5b612e1782602083016020860161388d565b95945050505050565b600060208284031215612e31578081fd5b5035919050565b600060208284031215612e49578081fd5b5051919050565b60008060408385031215612e62578182fd5b8235915060208084013567ffffffffffffffff80821115612e81578384fd5b818601915086601f830112612e94578384fd5b8135612ea2612a73826137f3565b81815284810190848601875b84811015612f5f57813587016080818e03601f19011215612ecd57898afd5b612ed760806137c9565b8982013588811115612ee7578b8cfd5b612ef58f8c83860101612b0a565b825250604082013588811115612f09578b8cfd5b612f178f8c83860101612b0a565b8b83015250606082013588811115612f2d578b8cfd5b612f3b8f8c83860101612b0a565b60408301525060809190910135606082015284529287019290870190600101612eae565b50979a909950975050505050505050565b60008060408385031215612f82578182fd5b82359150602083013567ffffffffffffffff811115612f9f578182fd5b612fab85828601612aa3565b9150509250929050565b60008060408385031215612fc7578182fd5b50508035926020909101359150565b60008151808452612fee81602086016020860161388d565b601f01601f19169290920160200192915050565b6000825161301481846020870161388d565b9190910192915050565b6000835161303081846020880161388d565b83519083019061304481836020880161388d565b01949350505050565b600080835461305b816138b9565b600182811680156130735760018114613084576130b0565b60ff198416875282870194506130b0565b8786526020808720875b858110156130a75781548a82015290840190820161308e565b50505082870194505b50929695505050505050565b6000603160f81b825282516130d881600185016020870161388d565b9190910160010192915050565b95865260208601949094526040850192909252606090811b6bffffffffffffffffffffffff1916908401526074830152609482015260b40190565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061318b90830184612fd6565b9695505050505050565b6001600160a01b038316815260406020820181905260009061202c90830184612fd6565b6001600160a01b03929092168252602082015260400190565b6020808252825182820181905260009190848201906040850190845b8181101561320a578351835292840192918401916001016131ee565b50909695505050505050565b901515815260200190565b60006020825261178f6020830184612fd6565b6000608082526132476080830187612fd6565b82810360208401526132598187612fd6565b9050828103604084015261326d8186612fd6565b91505082606083015295945050505050565b6020808252602b908201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560408201526a74206f6620626f756e647360a81b606082015260800190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252601c908201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604082015260600190565b60208082526024908201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526019908201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604082015260600190565b6020808252602c908201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b60208082526038908201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760408201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606082015260800190565b6020808252602a908201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604082015269726f206164647265737360b01b606082015260800190565b60208082526029908201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460408201526832b73a103a37b5b2b760b91b606082015260800190565b6020808252818101527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b6020808252602c908201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b60208082526029908201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960408201526839903737ba1037bbb760b91b606082015260800190565b60208082526021908201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656040820152603960f91b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252602c908201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60408201526b7574206f6620626f756e647360a01b606082015260800190565b61ffff93909316835260ff919091166020830152604082015260600190565b90815260200190565b6000868252602060a0818401526136f460a0840188612fd6565b604087818601528482036060860152818754808452848401915084858202850101898752858720875b838110156137ae57601f1987840301855288825461373a816138b9565b80865260018281168015613755576001811461376857613797565b60ff198416888e01528a88019450613797565b868e528c8e208e5b8481101561378f5781548f828c01015283820191508e81019050613770565b89018e019550505b50978b01979295505050919091019060010161371d565b50508096505050505050508260808301529695505050505050565b60405181810167ffffffffffffffff811182821017156137eb576137eb613965565b604052919050565b600067ffffffffffffffff82111561380d5761380d613965565b5060209081020190565b600067ffffffffffffffff82111561383157613831613965565b50601f01601f191660200190565b600082198211156138525761385261394f565b500190565b60008160001904831182151516156138715761387161394f565b500290565b6000828210156138885761388861394f565b500390565b60005b838110156138a8578181015183820152602001613890565b838111156116c45750506000910152565b6002810460018216806138cd57607f821691505b602082108114156138ee57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156139085761390861394f565b5060010190565b600060ff821660ff8114156139265761392661394f565b60010192915050565b60008261394a57634e487b7160e01b81526012600452602481fd5b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114611ef057600080fd5b6001600160e01b031981168114611ef057600080fdfea2646970667358221220b56eec5563315257b0860708059d136b235fabda504ac5c3cad48931dcbd6afa64736f6c63430008000033

Libraries Used

GraveyardLibrary : 0x91022862fc863dd812fe608db44cad0714c58332Unverified

Deployed Bytecode Sourcemap

58554:19727:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74901:518;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33676:224;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;63977:917::-;;;;;;:::i;:::-;;:::i;:::-;;20798:100;;;:::i;22357:221::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;21880:411::-;;;;;;:::i;:::-;;:::i;34316:113::-;;;:::i;:::-;;;;;;;:::i;23247:339::-;;;;;;:::i;:::-;;:::i;65042:1144::-;;;;;;:::i;:::-;;:::i;33984:256::-;;;;;;:::i;:::-;;:::i;58924:62::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;71103:132::-;;;:::i;58805:32::-;;;:::i;66631:369::-;;;;;;:::i;:::-;;:::i;23657:185::-;;;;;;:::i;:::-;;:::i;75587:380::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;34506:233::-;;;;;;:::i;:::-;;:::i;20492:239::-;;;;;;:::i;:::-;;:::i;20222:208::-;;;;;;:::i;:::-;;:::i;68095:361::-;;;;;;:::i;:::-;;:::i;59832:29::-;;;:::i;66303:174::-;;;;;;:::i;:::-;;:::i;68690:482::-;;;;;;:::i;:::-;;:::i;71529:1369::-;;;;;;:::i;:::-;;:::i;20967:104::-;;;:::i;22650:295::-;;;;;;:::i;:::-;;:::i;71320:120::-;;;;;;:::i;:::-;;:::i;23913:328::-;;;;;;:::i;:::-;;:::i;74292:473::-;;;;;;:::i;:::-;;:::i;77671:227::-;;;;;;:::i;:::-;;:::i;61195:160::-;;;;;;:::i;:::-;;:::i;62919:880::-;;;;;;:::i;:::-;;:::i;76976:510::-;;;;;;:::i;:::-;;:::i;23016:164::-;;;;;;:::i;:::-;;:::i;72915:459::-;;;;;;:::i;:::-;;:::i;74901:518::-;75022:23;75048;;;:13;:23;;;;;75022:49;;74991:13;;75022:23;75048;75022:49;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;75151:24:0;;;;:14;:24;;;;;;75022:49;;-1:-1:-1;;;75151:24:0;;75147:236;;;75294:43;75321:9;75332:1;75335;75294:26;:43::i;:::-;75229:127;;;;;;;;:::i;:::-;;;;;;;;;;;;;75192:179;;75147:236;75402:9;74901:518;-1:-1:-1;;74901:518:0:o;33676:224::-;33778:4;-1:-1:-1;;;;;;33802:50:0;;-1:-1:-1;;;33802:50:0;;:90;;;33856:36;33880:11;33856:23;:36::i;63977:917::-;64057:24;64069:11;64057;:24::i;:::-;64116:27;;;;:14;:27;;;;;;;;:35;;:27;:35;64094:129;;;;;;64280:10;64258:18;64266:9;64258:7;:18::i;:::-;-1:-1:-1;;;;;64258:32:0;;64236:116;;;;;;64370:9;64365:406;64389:32;;;;:19;:32;;;;;:39;64385:43;;64365:406;;;64476:52;64492:32;;;:19;:32;;;;;:35;;64553:10;;64476:15;;:52;;64525:1;;64492:35;;;;-1:-1:-1;;;64492:35:0;;;;;;;;;;;;;;;;;;;;;64476:52;;;;;;;;;;;;;-1:-1:-1;;;;;64476:52:0;:87;64450:190;;;;;;64655:30;;;;:19;:30;;;;;;64709:32;;;;;:35;;64742:1;;64709:35;;;;-1:-1:-1;;;64709:35:0;;;;;;;;;;;;;;;;;;;;;64655:104;;;;;;;;;;;;;;;;64430:3;;;;:::i;:::-;;;;64365:406;;;-1:-1:-1;64788:32:0;;;;:19;:32;;;;;64781:39;;;:::i;:::-;64861:25;64873:9;64884:1;64861:11;:25::i;:::-;63977:917;;:::o;20798:100::-;20852:13;20885:5;20878:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;20798:100;:::o;22357:221::-;22433:7;22461:16;22469:7;22461;:16::i;:::-;22453:73;;;;-1:-1:-1;;;22453:73:0;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;22546:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;22546:24:0;;22357:221::o;21880:411::-;21961:13;21977:23;21992:7;21977:14;:23::i;:::-;21961:39;;22025:5;-1:-1:-1;;;;;22019:11:0;:2;-1:-1:-1;;;;;22019:11:0;;;22011:57;;;;-1:-1:-1;;;22011:57:0;;;;;;;:::i;:::-;22119:5;-1:-1:-1;;;;;22103:21:0;:12;:10;:12::i;:::-;-1:-1:-1;;;;;22103:21:0;;:62;;;;22128:37;22145:5;22152:12;:10;:12::i;22128:37::-;22081:168;;;;-1:-1:-1;;;22081:168:0;;;;;;;:::i;:::-;22262:21;22271:2;22275:7;22262:8;:21::i;:::-;21880:411;;;:::o;34316:113::-;34404:10;:17;34316:113;:::o;23247:339::-;23442:41;23461:12;:10;:12::i;:::-;23475:7;23442:18;:41::i;:::-;23434:103;;;;-1:-1:-1;;;23434:103:0;;;;;;;:::i;:::-;23550:28;23560:4;23566:2;23570:7;23550:9;:28::i;65042:1144::-;65146:8;:15;65165:1;65146:20;65124:97;;;;;;65256:28;;;;:19;:28;;;;;:35;:40;65234:133;;;;;;65422:10;65402:16;65410:7;65402;:16::i;:::-;-1:-1:-1;;;;;65402:30:0;;65380:114;;;;;;65512:9;65507:636;65531:8;:15;65527:1;:19;65507:636;;;65602:14;;65626:11;;65642:10;;-1:-1:-1;;;;;65602:14:0;;65594:31;;65626:8;;65635:1;;65626:11;;;;-1:-1:-1;;;65626:11:0;;;;;;;;;;;;;;;65594:44;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;65594:58:0;;:126;;;;-1:-1:-1;65709:11:0;;65693;;-1:-1:-1;;;;;65709:11:0;;;;65677:15;;65709:11;;65693:8;;65702:1;;65693:11;;;;-1:-1:-1;;;65693:11:0;;;;;;;;;;;;;;;;;;;;65677:28;;;;;;;;;;-1:-1:-1;65677:28:0;;-1:-1:-1;;;;;65677:28:0;:43;65594:126;65568:220;;;;;;65813:14;;65921:11;;-1:-1:-1;;;;;65813:14:0;;;;65805:36;;65860:10;;65897:4;;65921:8;;65930:1;;65921:11;;;;-1:-1:-1;;;65921:11:0;;;;;;;;;;;;;;;65805:142;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;65981:10:0;65964:28;;;;:16;:28;;;;;65998:11;;65964:28;;-1:-1:-1;65998:8:0;;-1:-1:-1;66007:1:0;;65998:11;;;;-1:-1:-1;;;65998:11:0;;;;;;;;;;;;;;;;;;;;65964:46;;;;;;;-1:-1:-1;65964:46:0;;;;;;;;66027:28;;;:19;:28;;;;;66061:11;;:8;;66070:1;;66061:11;;;;-1:-1:-1;;;66061:11:0;;;;;;;;;;;;;;;;;;;;66027:46;;;;;;;-1:-1:-1;66027:46:0;;;;;;;;;;66106:11;;66121:10;;66090:15;;66106:8;;66115:1;;66106:11;;;;-1:-1:-1;;;66106:11:0;;;;;;;;;;;;;;;66090:28;;;;;;;;;;;;:41;;;;;-1:-1:-1;;;;;66090:41:0;;;;;-1:-1:-1;;;;;66090:41:0;;;;;;65548:3;;;;;:::i;:::-;;;;65507:636;;;;66155:23;66167:7;66176:1;66155:11;:23::i;33984:256::-;34081:7;34117:23;34134:5;34117:16;:23::i;:::-;34109:5;:31;34101:87;;;;-1:-1:-1;;;34101:87:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;;34206:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;33984:256::o;58924:62::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;71103:132::-;71152:7;71179:16;:33;71213:13;:11;:13::i;:::-;71179:48;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;71172:55;;71103:132;:::o;58805:32::-;;;;:::o;66631:369::-;66730:7;66763:28;;;:19;:28;;;;;;66755:88;;;;;;66862:23;;;;:14;:23;;;;;;;;:31;;:23;:31;;66854:90;;;;;;-1:-1:-1;66964:28:0;;;;:19;:28;;;;;;;66631:369::o;23657:185::-;23795:39;23812:4;23818:2;23822:7;23795:39;;;;;;;;;;;;:16;:39::i;75587:380::-;75675:16;75709:18;75730;75740:7;75730:9;:18::i;:::-;75709:39;;75761:25;75803:10;75789:25;;;;;;-1:-1:-1;;;75789:25:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;75789:25:0;;75761:53;;75830:9;75825:109;75845:10;75841:1;:14;75825:109;;;75891:31;75911:7;75920:1;75891:19;:31::i;:::-;75877:8;75886:1;75877:11;;;;;;-1:-1:-1;;;75877:11:0;;;;;;;;;;;;;;;;;;:45;75857:3;;;;:::i;:::-;;;;75825:109;;;-1:-1:-1;75951:8:0;75587:380;-1:-1:-1;;;75587:380:0:o;34506:233::-;34581:7;34617:30;:28;:30::i;:::-;34609:5;:38;34601:95;;;;-1:-1:-1;;;34601:95:0;;;;;;;:::i;:::-;34714:10;34725:5;34714:17;;;;;;-1:-1:-1;;;34714:17:0;;;;;;;;;;;;;;;;;34707:24;;34506:233;;;:::o;20492:239::-;20564:7;20600:16;;;:7;:16;;;;;;-1:-1:-1;;;;;20600:16:0;20635:19;20627:73;;;;-1:-1:-1;;;20627:73:0;;;;;;;:::i;20222:208::-;20294:7;-1:-1:-1;;;;;20322:19:0;;20314:74;;;;-1:-1:-1;;;20314:74:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;;20406:16:0;;;;;:9;:16;;;;;;;20222:208::o;68095:361::-;68167:9;68162:287;68186:8;:15;68182:1;:19;68162:287;;;68249:19;:32;68269:8;68278:1;68269:11;;;;;;-1:-1:-1;;;68269:11:0;;;;;;;;;;;;;;;68249:32;;;;;;;;;;;:39;;;;68292:1;68249:44;68223:173;;;;;;68413:24;68425:8;68434:1;68425:11;;;;;;-1:-1:-1;;;68425:11:0;;;;;;;;;;;;;;;68413;:24::i;:::-;68203:3;;;;:::i;:::-;;;;68162:287;;59832:29;;;-1:-1:-1;;;;;59832:29:0;;:::o;66303:174::-;66441:28;;;;:19;:28;;;;;;;;;66434:35;;;;;;;;;;;;;;;;;66400:16;;66434:35;;;66441:28;66434:35;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;66303:174;;;:::o;68690:482::-;68763:9;68758:407;68782:8;:15;68778:1;:19;68758:407;;;68826:12;;;68896:116;;;-1:-1:-1;;;68896:116:0;;;;-1:-1:-1;;;;;68826:12:0;;;;68819:29;;68867:10;;68896:16;;:34;;:116;;;;;;;;;;:16;:116;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;68819:208;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69148:5;69096:19;:32;69116:8;69125:1;69116:11;;;;;;-1:-1:-1;;;69116:11:0;;;;;;;;;;;;;;;69096:32;;;;;;;;;;;;:57;;;;:::i;:::-;69044:19;:32;69064:8;69073:1;69064:11;;;;;;-1:-1:-1;;;69064:11:0;;;;;;;;;;;;;;;69044:32;;;;;;;;;;;:109;;;;68799:3;;;;;:::i;:::-;;;;68758:407;;71529:1369;71582:20;71605:13;:11;:13::i;:::-;71582:36;;71652:10;;71637:12;:25;71629:34;;;;;;71857:12;71911:32;71857:12;71929:10;71835:19;71911:4;:32::i;:::-;71882:26;;;;:13;:26;;;;;;;;:61;;;;:26;;:61;;;;;;:::i;:::-;;71999:4;71956:12;71969:13;:26;71983:11;71969:26;;;;;;;;;;;71956:40;;;;;;:::i;:::-;;;;;;;;;;;;;;;:47;;-1:-1:-1;;71956:47:0;;;;;;;;;;;72023:12;-1:-1:-1;;;;;72023:12:0;72016:29;72046:10;72058:18;:16;:18::i;:::-;72016:61;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;72176:4;72161:12;:19;72156:684;;;72288:12;;72281:48;;-1:-1:-1;;;72281:48:0;;72200:27;;;;-1:-1:-1;;;;;72288:12:0;;;;72281:36;;:48;;72318:10;;72281:48;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;72281:48:0;;;;;;;;;;;;:::i;:::-;72252:77;;72351:6;72346:176;72365:9;:16;72361:1;:20;72346:176;;;72421:9;72431:1;72421:12;;;;;;-1:-1:-1;;;72421:12:0;;;;;;;;;;;;;;;72411:6;:22;72407:100;;;72483:4;72458:29;;72407:100;72383:3;;;;:::i;:::-;;;;72346:176;;;-1:-1:-1;72570:4:0;72544:30;;;;72536:39;;;;;;72600:27;;;;:17;:27;;;;;;;;:36;72592:45;;;;;;72654:27;;;;:17;:27;;;;;:34;;-1:-1:-1;;72654:34:0;72684:4;72654:34;;;72801:27;72813:11;72826:1;72801:11;:27::i;:::-;72156:684;;;72860:30;72866:10;72878:11;72860:5;:30::i;20967:104::-;21023:13;21056:7;21049:14;;;;;:::i;22650:295::-;22765:12;:10;:12::i;:::-;-1:-1:-1;;;;;22753:24:0;:8;-1:-1:-1;;;;;22753:24:0;;;22745:62;;;;-1:-1:-1;;;22745:62:0;;;;;;;:::i;:::-;22865:8;22820:18;:32;22839:12;:10;:12::i;:::-;-1:-1:-1;;;;;22820:32:0;;;;;;;;;;;;;;;;;-1:-1:-1;22820:32:0;;;:42;;;;;;;;;;;;:53;;-1:-1:-1;;22820:53:0;;;;;;;;;;;22904:12;:10;:12::i;:::-;-1:-1:-1;;;;;22889:48:0;;22928:8;22889:48;;;;;;:::i;:::-;;;;;;;;22650:295;;:::o;71320:120::-;71381:4;71405:27;;;:17;:27;;;;;;;;;71320:120::o;23913:328::-;24088:41;24107:12;:10;:12::i;:::-;24121:7;24088:18;:41::i;:::-;24080:103;;;;-1:-1:-1;;;24080:103:0;;;;;;;:::i;:::-;24194:39;24208:4;24214:2;24218:7;24227:5;24194:13;:39::i;:::-;23913:328;;;;:::o;74292:473::-;74394:13;74433:17;74441:8;74433:7;:17::i;:::-;74425:26;;;;;;74464:23;74490:24;74505:8;74490:14;:24::i;:::-;74713:29;;;;:19;:29;;;;;;;;74555:202;;-1:-1:-1;;;74555:202:0;;74464:50;;-1:-1:-1;74555:16:0;;:29;;:202;;74603:8;;74464:50;;74658:10;;74687:7;;74555:202;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;74555:202:0;;;;;;;;;;;;:::i;:::-;74535:222;74292:473;-1:-1:-1;;;74292:473:0:o;77671:227::-;78237:6;;-1:-1:-1;;;;;78237:6:0;78247:10;78237:20;78229:29;;;;;;77802:12:::1;:28:::0;;-1:-1:-1;;;;;77802:28:0;;::::1;-1:-1:-1::0;;;;;;77802:28:0;;::::1;;::::0;;;77841:14:::1;:32:::0;;;;;::::1;::::0;::::1;;::::0;;77671:227::o;61195:160::-;-1:-1:-1;;;;;61323:24:0;;;;;;:16;:24;;;;;;;;;61316:31;;;;;;;;;;;;;;;;;61282:16;;61316:31;;;61323:24;61316:31;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61195:160;;;:::o;62919:880::-;62979:20;62991:7;62979:11;:20::i;:::-;63034:23;;;;:14;:23;;;;;;;;:31;;:23;:31;63012:117;;;;;;63147:9;63142:650;63166:28;;;;:19;:28;;;;;:35;63162:39;;63142:650;;;63249:48;63265:28;;;:19;:28;;;;;:31;;63301:10;;63249:15;;:48;;63294:1;;63265:31;;;;-1:-1:-1;;;63265:31:0;;;;;;;;;;;;;;;;;;;;;63249:48;;;;;;;;;;;;;-1:-1:-1;;;;;63249:48:0;:62;63223:165;;;;;;63413:14;;;63521:28;;;:19;:28;;;;;:31;;-1:-1:-1;;;;;63413:14:0;;;;63405:36;;63468:4;;63492:10;;63521:28;63550:1;;63521:31;;;;-1:-1:-1;;;63521:31:0;;;;;;;;;;;;;;;;;63405:162;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63584:117;63626:10;63655:19;:28;63675:7;63655:28;;;;;;;;;;;63684:1;63655:31;;;;;;-1:-1:-1;;;63655:31:0;;;;;;;;;;;;;;;;;63584:23;:117::i;:::-;63769:11;;;63734:28;;;:19;:28;;;;;:31;;-1:-1:-1;;;;;63769:11:0;;;;63718:15;;63769:11;63734:28;63763:1;;63734:31;;;;-1:-1:-1;;;63734:31:0;;;;;;;;;;;;;;;;;63718:48;;;;;;;;;;;;:62;;;;;-1:-1:-1;;;;;63718:62:0;;;;;-1:-1:-1;;;;;63718:62:0;;;;;;63203:3;;;;;:::i;:::-;;;;63142:650;;76976:510;78237:6;;-1:-1:-1;;;;;78237:6:0;78247:10;78237:20;78229:29;;;;;;77121:9:::1;77116:344;77140:6;:13;77136:1;:17;77116:344;;;77175:10;:27;77186:15;77175:27;;;;;;;;;;;77226:207;;;;;;;;77271:6;77278:1;77271:9;;;;;;-1:-1:-1::0;;;77271:9:0::1;;;;;;;;;;;;;;;:19;;;77226:207;;;;77313:6;77320:1;77313:9;;;;;;-1:-1:-1::0;;;77313:9:0::1;;;;;;;;;;;;;;;:19;;;77226:207;;;;77355:6;77362:1;77355:9;;;;;;-1:-1:-1::0;;;77355:9:0::1;;;;;;;;;;;;;;;:16;;;77226:207;;;;77394:6;77401:1;77394:9;;;;;;-1:-1:-1::0;;;77394:9:0::1;;;;;;;;;;::::0;;::::1;::::0;;;;;;;:20:::1;;::::0;77226:207;;;77175:273;;::::1;::::0;::::1;::::0;;-1:-1:-1;77175:273:0;;;;;;;;;;;;;::::1;;::::0;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;77175:273:0::1;::::0;;::::1;::::0;;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;77175:273:0::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;:::i;:::-;;;;;;;;;;;;77155:3;;;;;:::i;:::-;;;;77116:344;;23016:164:::0;-1:-1:-1;;;;;23137:25:0;;;23113:4;23137:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;23016:164::o;72915:459::-;78237:6;;-1:-1:-1;;;;;78237:6:0;78247:10;78237:20;78229:29;;;;;;73012:9:::1;73008:359;73028:6;73025:1;:9;73008:359;;;73055:19;73077:13;:11;:13::i;:::-;73055:35;;73127:2;73113:11;:16;73105:25;;;::::0;::::1;;73174:32;73179:11;73192:10;73204:1;73174:4;:32::i;:::-;73145:26;::::0;;;:13:::1;:26;::::0;;;;;;;:61;;::::1;::::0;:26;;:61;;;::::1;::::0;::::1;:::i;:::-;;73264:4;73221:12;73234:13;:26;73248:11;73234:26;;;;;;;;;;;73221:40;;;;;;:::i;:::-;::::0;;;::::1;::::0;;;;;::::1;::::0;;;:47;;;::::1;;-1:-1:-1::0;;73221:47:0;;::::1;::::0;;;::::1;::::0;;73283:27:::1;73295:11:::0;73308:1:::1;73283:11;:27::i;:::-;73325:30;73331:10;73343:11;73325:5;:30::i;:::-;-1:-1:-1::0;73036:3:0;::::1;::::0;::::1;:::i;:::-;;;;73008:359;;57300:419:::0;57433:13;57489:3;57459:21;57536;57547:10;57536:8;:21;:::i;:::-;57526:32;;;;;;-1:-1:-1;;;57526:32:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;57526:32:0;-1:-1:-1;57504:54:0;-1:-1:-1;57586:10:0;57569:111;57602:8;57598:1;:12;57569:111;;;57657:8;57666:1;57657:11;;;;;;-1:-1:-1;;;57657:11:0;;;;;;;;;;;;;-1:-1:-1;;;;;;57657:11:0;57632:6;57639:14;57643:10;57639:1;:14;:::i;:::-;57632:22;;;;;;-1:-1:-1;;;57632:22:0;;;;;;;;;;;;:36;-1:-1:-1;;;;;57632:36:0;;;;;;;;-1:-1:-1;57612:3:0;;;;:::i;:::-;;;;57569:111;;;-1:-1:-1;57704:6:0;57300:419;-1:-1:-1;;;;;57300:419:0:o;19853:305::-;19955:4;-1:-1:-1;;;;;;19992:40:0;;-1:-1:-1;;;19992:40:0;;:105;;-1:-1:-1;;;;;;;20049:48:0;;-1:-1:-1;;;20049:48:0;19992:105;:158;;;;20114:36;20138:11;20114:23;:36::i;67153:788::-;67254:10;67234:16;67242:7;67234;:16::i;:::-;-1:-1:-1;;;;;67234:30:0;;67212:125;;;;;;67370:28;;;;:19;:28;;;;;;67401:15;-1:-1:-1;67348:137:0;;;;;;67593:14;;-1:-1:-1;;;;;67593:14:0;67585:34;67634:10;67659:23;67674:7;67659:14;:23::i;:::-;67585:108;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;67706:23:0;;;;:14;:23;;;;;:30;;-1:-1:-1;;67706:30:0;67732:4;67706:30;;;-1:-1:-1;67808:124:0;67832:10;67857:42;67721:7;67808:9;:124::i;:::-;67153:788;:::o;62583:179::-;62736:17;62744:9;62736:5;:17;:::i;:::-;62704:50;;:15;:50;:::i;:::-;62660:28;;;;:19;:28;;;;;;:94;;;;-1:-1:-1;62583:179:0:o;25751:127::-;25816:4;25840:16;;;:7;:16;;;;;;-1:-1:-1;;;;;25840:16:0;:30;;;25751:127::o;15550:98::-;15630:10;15550:98;:::o;29733:174::-;29808:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;29808:29:0;-1:-1:-1;;;;;29808:29:0;;;;;;;;:24;;29862:23;29808:24;29862:14;:23::i;:::-;-1:-1:-1;;;;;29853:46:0;;;;;;;;;;;29733:174;;:::o;26045:348::-;26138:4;26163:16;26171:7;26163;:16::i;:::-;26155:73;;;;-1:-1:-1;;;26155:73:0;;;;;;;:::i;:::-;26239:13;26255:23;26270:7;26255:14;:23::i;:::-;26239:39;;26308:5;-1:-1:-1;;;;;26297:16:0;:7;-1:-1:-1;;;;;26297:16:0;;:51;;;;26341:7;-1:-1:-1;;;;;26317:31:0;:20;26329:7;26317:11;:20::i;:::-;-1:-1:-1;;;;;26317:31:0;;26297:51;:87;;;;26352:32;26369:5;26376:7;26352:16;:32::i;:::-;26289:96;26045:348;-1:-1:-1;;;;26045:348:0:o;29037:578::-;29196:4;-1:-1:-1;;;;;29169:31:0;:23;29184:7;29169:14;:23::i;:::-;-1:-1:-1;;;;;29169:31:0;;29161:85;;;;-1:-1:-1;;;29161:85:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;29265:16:0;;29257:65;;;;-1:-1:-1;;;29257:65:0;;;;;;;:::i;:::-;29335:39;29356:4;29362:2;29366:7;29335:20;:39::i;:::-;29439:29;29456:1;29460:7;29439:8;:29::i;:::-;-1:-1:-1;;;;;29481:15:0;;;;;;:9;:15;;;;;:20;;29500:1;;29481:15;:20;;29500:1;;29481:20;:::i;:::-;;;;-1:-1:-1;;;;;;;29512:13:0;;;;;;:9;:13;;;;;:18;;29529:1;;29512:13;:18;;29529:1;;29512:18;:::i;:::-;;;;-1:-1:-1;;29541:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;29541:21:0;-1:-1:-1;;;;;29541:21:0;;;;;;;;;29580:27;;29541:16;;29580:27;;;;;;;29037:578;;;:::o;69822:1202::-;69924:13;69963:2;69958;:7;69950:16;;;;;;70124:31;;;;;;;;;;;;-1:-1:-1;;;70124:31:0;;;;:25;70168:747;70190:1;70186;:5;;;70168:747;;;70213:10;:12;;;:10;:12;;;:::i;:::-;;;;;;70240:17;70672:5;70398:15;70444:16;70491:2;70524;70557;70590:10;;70351:276;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;70315:335;;;;;;70285:384;;:392;;;;:::i;:::-;70240:452;;70787:11;70821:16;:26;70848:10;70860:1;70863:5;70821:48;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;70821:48:0;;;;;;;;;;;;:::i;:::-;70748:140;;;;;;;;;:::i;:::-;;;;;;;;;;;;;70709:194;;70168:747;70193:3;;;;;:::i;:::-;;;;70168:747;;;;70931:12;70944:11;70931:25;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;70927:58;;;70965:20;70970:2;70974;70978:6;:2;70983:1;70978:6;:::i;:::-;70965:4;:20::i;:::-;70958:27;;;;;27729:382;-1:-1:-1;;;;;27809:16:0;;27801:61;;;;-1:-1:-1;;;27801:61:0;;;;;;;:::i;:::-;27882:16;27890:7;27882;:16::i;:::-;27881:17;27873:58;;;;-1:-1:-1;;;27873:58:0;;;;;;;:::i;:::-;27944:45;27973:1;27977:2;27981:7;27944:20;:45::i;:::-;-1:-1:-1;;;;;28002:13:0;;;;;;:9;:13;;;;;:18;;28019:1;;28002:13;:18;;28019:1;;28002:18;:::i;:::-;;;;-1:-1:-1;;28031:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;28031:21:0;-1:-1:-1;;;;;28031:21:0;;;;;;;;28070:33;;28031:16;;;28070:33;;28031:16;;28070:33;27729:382;;:::o;25123:315::-;25280:28;25290:4;25296:2;25300:7;25280:9;:28::i;:::-;25327:48;25350:4;25356:2;25360:7;25369:5;25327:22;:48::i;:::-;25319:111;;;;-1:-1:-1;;;25319:111:0;;;;;;;:::i;62091:327::-;62182:9;62177:234;-1:-1:-1;;;;;62201:24:0;;;;;;:16;:24;;;;;:31;62197:35;;62177:234;;;-1:-1:-1;;;;;62258:24:0;;;;;;:16;:24;;;;;:27;;62289:7;;62258:24;62283:1;;62258:27;;;;-1:-1:-1;;;62258:27:0;;;;;;;;;;;;;;;;;:38;62254:146;;;62367:17;62374:6;62382:1;62367:6;:17::i;:::-;62234:3;;;;:::i;:::-;;;;62177:234;;18457:157;-1:-1:-1;;;;;;18566:40:0;;-1:-1:-1;;;18566:40:0;18457:157;;;:::o;35352:589::-;35496:45;35523:4;35529:2;35533:7;35496:26;:45::i;:::-;-1:-1:-1;;;;;35558:18:0;;35554:187;;35593:40;35625:7;35593:31;:40::i;:::-;35554:187;;;35663:2;-1:-1:-1;;;;;35655:10:0;:4;-1:-1:-1;;;;;35655:10:0;;35651:90;;35682:47;35715:4;35721:7;35682:32;:47::i;:::-;-1:-1:-1;;;;;35755:16:0;;35751:183;;35788:45;35825:7;35788:36;:45::i;:::-;35751:183;;;35861:4;-1:-1:-1;;;;;35855:10:0;:2;-1:-1:-1;;;;;35855:10:0;;35851:83;;35882:40;35910:2;35914:7;35882:27;:40::i;30472:799::-;30627:4;30648:15;:2;-1:-1:-1;;;;;30648:13:0;;:15::i;:::-;30644:620;;;30700:2;-1:-1:-1;;;;;30684:36:0;;30721:12;:10;:12::i;:::-;30735:4;30741:7;30750:5;30684:72;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;30684:72:0;;;;;;;;-1:-1:-1;;30684:72:0;;;;;;;;;;;;:::i;:::-;;;30680:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;30926:13:0;;30922:272;;30969:60;;-1:-1:-1;;;30969:60:0;;;;;;;:::i;30922:272::-;31144:6;31138:13;31129:6;31125:2;31121:15;31114:38;30680:529;-1:-1:-1;;;;;;30807:51:0;-1:-1:-1;;;30807:51:0;;-1:-1:-1;30800:58:0;;30644:620;-1:-1:-1;31248:4:0;30472:799;;;;;;:::o;61554:338::-;-1:-1:-1;;;;;61634:24:0;;;;;;:16;:24;;;;;:31;61625:40;;61621:53;;61667:7;;61621:53;61703:5;61686:158;-1:-1:-1;;;;;61714:24:0;;;;;;:16;:24;;;;;:31;:35;;61748:1;;61714:35;:::i;:::-;61710:1;:39;61686:158;;;-1:-1:-1;;;;;61801:24:0;;;;;;:16;:24;;;;;61826:5;:1;61830;61826:5;:::i;:::-;61801:31;;;;;;-1:-1:-1;;;61801:31:0;;;;;;;;;;;;;;;;;61771:16;:24;61788:6;-1:-1:-1;;;;;61771:24:0;-1:-1:-1;;;;;61771:24:0;;;;;;;;;;;;61796:1;61771:27;;;;;;-1:-1:-1;;;61771:27:0;;;;;;;;;;;;;;;;;;:61;61751:3;;;;:::i;:::-;;;;61686:158;;;-1:-1:-1;;;;;;61854:24:0;;;;;;:16;:24;;;;;:30;;;;;-1:-1:-1;;;61854:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;61554:338;;:::o;36664:164::-;36768:10;:17;;36741:24;;;;:15;:24;;;;;:44;;;36796:24;;;;;;;;;;;;36664:164::o;37455:988::-;37721:22;37771:1;37746:22;37763:4;37746:16;:22::i;:::-;:26;;;;:::i;:::-;37783:18;37804:26;;;:17;:26;;;;;;37721:51;;-1:-1:-1;37937:28:0;;;37933:328;;-1:-1:-1;;;;;38004:18:0;;37982:19;38004:18;;;:12;:18;;;;;;;;:34;;;;;;;;;38055:30;;;;;;:44;;;38172:30;;:17;:30;;;;;:43;;;37933:328;-1:-1:-1;38357:26:0;;;;:17;:26;;;;;;;;38350:33;;;-1:-1:-1;;;;;38401:18:0;;;;;:12;:18;;;;;:34;;;;;;;38394:41;37455:988::o;38738:1079::-;39016:10;:17;38991:22;;39016:21;;39036:1;;39016:21;:::i;:::-;39048:18;39069:24;;;:15;:24;;;;;;39442:10;:26;;38991:46;;-1:-1:-1;39069:24:0;;38991:46;;39442:26;;;;-1:-1:-1;;;39442:26:0;;;;;;;;;;;;;;;;;39420:48;;39506:11;39481:10;39492;39481:22;;;;;;-1:-1:-1;;;39481:22:0;;;;;;;;;;;;;;;;;;;;:36;;;;39586:28;;;:15;:28;;;;;;;:41;;;39758:24;;;;;39751:31;39793:10;:16;;;;;-1:-1:-1;;;39793:16:0;;;;;;;;;;;;;;;;;;;;;;;;;;38738:1079;;;;:::o;36242:221::-;36327:14;36344:20;36361:2;36344:16;:20::i;:::-;-1:-1:-1;;;;;36375:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;36420:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;36242:221:0:o;7674:387::-;7997:20;8045:8;;;7674:387::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:339:1;;109:53;124:37;154:6;124:37;:::i;:::-;109:53;:::i;:::-;100:62;;185:6;178:5;171:21;225:3;216:6;211:3;207:16;204:25;201:2;;;242:1;239;232:12;201:2;291:6;286:3;279:4;272:5;268:16;255:43;345:1;338:4;329:6;322:5;318:18;314:29;307:40;90:263;;;;;:::o;358:711::-;;471:3;464:4;456:6;452:17;448:27;438:2;;493:5;486;479:20;438:2;533:6;520:20;559:4;583:71;598:55;650:2;598:55;:::i;583:71::-;688:15;;;719:12;;;;751:15;;;797:11;;;785:24;;781:33;;778:42;-1:-1:-1;775:2:1;;;837:5;830;823:20;775:2;863:5;877:163;891:2;888:1;885:9;877:163;;;948:17;;936:30;;986:12;;;;1018;;;;909:1;902:9;877:163;;;-1:-1:-1;1058:5:1;;428:641;-1:-1:-1;;;;;;;428:641:1:o;1074:233::-;;1172:3;1165:4;1157:6;1153:17;1149:27;1139:2;;1194:5;1187;1180:20;1139:2;1220:81;1297:3;1288:6;1275:20;1268:4;1260:6;1256:17;1220:81;:::i;1312:259::-;;1424:2;1412:9;1403:7;1399:23;1395:32;1392:2;;;1445:6;1437;1430:22;1392:2;1489:9;1476:23;1508:33;1535:5;1508:33;:::i;1576:263::-;;1699:2;1687:9;1678:7;1674:23;1670:32;1667:2;;;1720:6;1712;1705:22;1667:2;1757:9;1751:16;1776:33;1803:5;1776:33;:::i;1844:402::-;;;1973:2;1961:9;1952:7;1948:23;1944:32;1941:2;;;1994:6;1986;1979:22;1941:2;2038:9;2025:23;2057:33;2084:5;2057:33;:::i;:::-;2109:5;-1:-1:-1;2166:2:1;2151:18;;2138:32;2179:35;2138:32;2179:35;:::i;:::-;2233:7;2223:17;;;1931:315;;;;;:::o;2251:470::-;;;;2397:2;2385:9;2376:7;2372:23;2368:32;2365:2;;;2418:6;2410;2403:22;2365:2;2462:9;2449:23;2481:33;2508:5;2481:33;:::i;:::-;2533:5;-1:-1:-1;2590:2:1;2575:18;;2562:32;2603:35;2562:32;2603:35;:::i;:::-;2355:366;;2657:7;;-1:-1:-1;;;2711:2:1;2696:18;;;;2683:32;;2355:366::o;2726:830::-;;;;;2898:3;2886:9;2877:7;2873:23;2869:33;2866:2;;;2920:6;2912;2905:22;2866:2;2964:9;2951:23;2983:33;3010:5;2983:33;:::i;:::-;3035:5;-1:-1:-1;3092:2:1;3077:18;;3064:32;3105:35;3064:32;3105:35;:::i;:::-;3159:7;-1:-1:-1;3213:2:1;3198:18;;3185:32;;-1:-1:-1;3268:2:1;3253:18;;3240:32;3295:18;3284:30;;3281:2;;;3332:6;3324;3317:22;3281:2;3360:22;;3413:4;3405:13;;3401:27;-1:-1:-1;3391:2:1;;3447:6;3439;3432:22;3391:2;3475:75;3542:7;3537:2;3524:16;3519:2;3515;3511:11;3475:75;:::i;:::-;3465:85;;;2856:700;;;;;;;:::o;3561:438::-;;;3687:2;3675:9;3666:7;3662:23;3658:32;3655:2;;;3708:6;3700;3693:22;3655:2;3752:9;3739:23;3771:33;3798:5;3771:33;:::i;:::-;3823:5;-1:-1:-1;3880:2:1;3865:18;;3852:32;3922:15;;3915:23;3903:36;;3893:2;;3958:6;3950;3943:22;4004:327;;;4133:2;4121:9;4112:7;4108:23;4104:32;4101:2;;;4154:6;4146;4139:22;4101:2;4198:9;4185:23;4217:33;4244:5;4217:33;:::i;:::-;4269:5;4321:2;4306:18;;;;4293:32;;-1:-1:-1;;;4091:240:1:o;4336:374::-;;4473:2;4461:9;4452:7;4448:23;4444:32;4441:2;;;4494:6;4486;4479:22;4441:2;4539:9;4526:23;4572:18;4564:6;4561:30;4558:2;;;4609:6;4601;4594:22;4558:2;4637:67;4696:7;4687:6;4676:9;4672:22;4637:67;:::i;4715:949::-;;4841:2;4884;4872:9;4863:7;4859:23;4855:32;4852:2;;;4905:6;4897;4890:22;4852:2;4943:9;4937:16;4976:18;4968:6;4965:30;4962:2;;;5013:6;5005;4998:22;4962:2;5041:22;;5094:4;5086:13;;5082:27;-1:-1:-1;5072:2:1;;5128:6;5120;5113:22;5072:2;5162;5156:9;5185:71;5200:55;5252:2;5200:55;:::i;5185:71::-;5290:15;;;5321:12;;;;5353:11;;;5391;;;5383:20;;5379:29;;5376:42;-1:-1:-1;5373:2:1;;;5436:6;5428;5421:22;5373:2;5463:6;5454:15;;5478:156;5492:2;5489:1;5486:9;5478:156;;;5549:10;;5537:23;;5510:1;5503:9;;;;;5580:12;;;;5612;;5478:156;;;-1:-1:-1;5653:5:1;4821:843;-1:-1:-1;;;;;;;4821:843:1:o;5669:257::-;;5780:2;5768:9;5759:7;5755:23;5751:32;5748:2;;;5801:6;5793;5786:22;5748:2;5845:9;5832:23;5864:32;5890:5;5864:32;:::i;5931:261::-;;6053:2;6041:9;6032:7;6028:23;6024:32;6021:2;;;6074:6;6066;6059:22;6021:2;6111:9;6105:16;6130:32;6156:5;6130:32;:::i;6197:676::-;;6330:2;6318:9;6309:7;6305:23;6301:32;6298:2;;;6351:6;6343;6336:22;6298:2;6389:9;6383:16;6422:18;6414:6;6411:30;6408:2;;;6459:6;6451;6444:22;6408:2;6487:22;;6540:4;6532:13;;6528:27;-1:-1:-1;6518:2:1;;6574:6;6566;6559:22;6518:2;6608;6602:9;6633:49;6648:33;6678:2;6648:33;:::i;6633:49::-;6705:2;6698:5;6691:17;6745:7;6740:2;6735;6731;6727:11;6723:20;6720:33;6717:2;;;6771:6;6763;6756:22;6717:2;6789:54;6840:2;6835;6828:5;6824:14;6819:2;6815;6811:11;6789:54;:::i;:::-;6862:5;6288:585;-1:-1:-1;;;;;6288:585:1:o;6878:190::-;;6990:2;6978:9;6969:7;6965:23;6961:32;6958:2;;;7011:6;7003;6996:22;6958:2;-1:-1:-1;7039:23:1;;6948:120;-1:-1:-1;6948:120:1:o;7073:194::-;;7196:2;7184:9;7175:7;7171:23;7167:32;7164:2;;;7217:6;7209;7202:22;7164:2;-1:-1:-1;7245:16:1;;7154:113;-1:-1:-1;7154:113:1:o;7272:1830::-;;;7449:2;7437:9;7428:7;7424:23;7420:32;7417:2;;;7470:6;7462;7455:22;7417:2;7511:9;7498:23;7488:33;;7540:2;7593;7582:9;7578:18;7565:32;7616:18;7657:2;7649:6;7646:14;7643:2;;;7678:6;7670;7663:22;7643:2;7721:6;7710:9;7706:22;7696:32;;7766:7;7759:4;7755:2;7751:13;7747:27;7737:2;;7793:6;7785;7778:22;7737:2;7834;7821:16;7857:71;7872:55;7924:2;7872:55;:::i;7857:71::-;7962:15;;;7993:12;;;;8025:11;;;8054:6;8069:1003;8083:2;8080:1;8077:9;8069:1003;;;8146:17;;8138:26;;8216:4;8188:16;;;-1:-1:-1;;8184:30:1;8180:41;8177:2;;;8239:6;8231;8224:22;8177:2;8274:20;8289:4;8274:20;:::i;:::-;8344:2;8340;8336:11;8323:25;8377:2;8367:8;8364:16;8361:2;;;8398:6;8390;8383:22;8361:2;8434:56;8482:7;8477:2;8466:8;8462:2;8458:17;8454:26;8434:56;:::i;:::-;8427:5;8420:71;;8541:2;8537;8533:11;8520:25;8574:2;8564:8;8561:16;8558:2;;;8595:6;8587;8580:22;8558:2;8640:56;8688:7;8683:2;8672:8;8668:2;8664:17;8660:26;8640:56;:::i;:::-;8635:2;8628:5;8624:14;8617:80;;8747:2;8743;8739:11;8726:25;8780:2;8770:8;8767:16;8764:2;;;8801:6;8793;8786:22;8764:2;8846:56;8894:7;8889:2;8878:8;8874:2;8870:17;8866:26;8846:56;:::i;:::-;8841:2;8830:14;;8823:80;-1:-1:-1;8960:4:1;8952:13;;;;8939:27;8934:2;8923:14;;8916:51;8980:18;;9018:12;;;;9050;;;;8101:1;8094:9;8069:1003;;;-1:-1:-1;7407:1695:1;;9091:5;;-1:-1:-1;7407:1695:1;-1:-1:-1;;;;;;;;7407:1695:1:o;9107:442::-;;;9261:2;9249:9;9240:7;9236:23;9232:32;9229:2;;;9282:6;9274;9267:22;9229:2;9323:9;9310:23;9300:33;;9384:2;9373:9;9369:18;9356:32;9411:18;9403:6;9400:30;9397:2;;;9448:6;9440;9433:22;9397:2;9476:67;9535:7;9526:6;9515:9;9511:22;9476:67;:::i;:::-;9466:77;;;9219:330;;;;;:::o;9554:258::-;;;9683:2;9671:9;9662:7;9658:23;9654:32;9651:2;;;9704:6;9696;9689:22;9651:2;-1:-1:-1;;9732:23:1;;;9802:2;9787:18;;;9774:32;;-1:-1:-1;9641:171:1:o;9817:259::-;;9898:5;9892:12;9925:6;9920:3;9913:19;9941:63;9997:6;9990:4;9985:3;9981:14;9974:4;9967:5;9963:16;9941:63;:::i;:::-;10058:2;10037:15;-1:-1:-1;;10033:29:1;10024:39;;;;10065:4;10020:50;;9868:208;-1:-1:-1;;9868:208:1:o;10081:276::-;;10250:6;10244:13;10266:53;10312:6;10307:3;10300:4;10292:6;10288:17;10266:53;:::i;:::-;10335:16;;;;;10220:137;-1:-1:-1;;10220:137:1:o;10362:470::-;;10579:6;10573:13;10595:53;10641:6;10636:3;10629:4;10621:6;10617:17;10595:53;:::i;:::-;10711:13;;10670:16;;;;10733:57;10711:13;10670:16;10767:4;10755:17;;10733:57;:::i;:::-;10806:20;;10549:283;-1:-1:-1;;;;10549:283:1:o;10837:821::-;;10994:3;11029:6;11023:13;11059:36;11085:9;11059:36;:::i;:::-;11114:1;11131:18;;;11158:104;;;;11276:1;11271:362;;;;11124:509;;11158:104;-1:-1:-1;;11191:24:1;;11179:37;;11236:16;;;;-1:-1:-1;11158:104:1;;11271:362;11304:6;11299:3;11292:19;11334:4;11381:2;11376:3;11366:18;11406:3;11422:165;11436:6;11433:1;11430:13;11422:165;;;11514:14;;11501:11;;;11494:35;11557:16;;;;11451:10;;11422:165;;;11426:3;;;11616:6;11611:3;11607:16;11600:23;;11124:509;-1:-1:-1;11649:3:1;;10973:685;-1:-1:-1;;;;;;10973:685:1:o;11663:418::-;;-1:-1:-1;;;11920:3:1;11913:16;11958:6;11952:13;11974:61;12028:6;12024:1;12019:3;12015:11;12008:4;12000:6;11996:17;11974:61;:::i;:::-;12055:16;;;;12073:1;12051:24;;11903:178;-1:-1:-1;;11903:178:1:o;12086:557::-;12355:19;;;12399:2;12390:12;;12383:28;;;;12436:2;12427:12;;12420:28;;;;12486:2;12482:15;;;-1:-1:-1;;12478:53:1;12464:12;;;12457:75;12557:3;12548:13;;12541:29;12595:3;12586:13;;12579:29;12633:3;12624:13;;12345:298::o;12648:203::-;-1:-1:-1;;;;;12812:32:1;;;;12794:51;;12782:2;12767:18;;12749:102::o;12856:375::-;-1:-1:-1;;;;;13114:15:1;;;13096:34;;13166:15;;;;13161:2;13146:18;;13139:43;13213:2;13198:18;;13191:34;;;;13046:2;13031:18;;13013:218::o;13236:490::-;-1:-1:-1;;;;;13505:15:1;;;13487:34;;13557:15;;13552:2;13537:18;;13530:43;13604:2;13589:18;;13582:34;;;13652:3;13647:2;13632:18;;13625:31;;;13236:490;;13673:47;;13700:19;;13692:6;13673:47;:::i;:::-;13665:55;13439:287;-1:-1:-1;;;;;;13439:287:1:o;13731:318::-;-1:-1:-1;;;;;13908:32:1;;13890:51;;13977:2;13972;13957:18;;13950:30;;;13731:318;;13997:46;;14024:18;;14016:6;13997:46;:::i;14054:274::-;-1:-1:-1;;;;;14246:32:1;;;;14228:51;;14310:2;14295:18;;14288:34;14216:2;14201:18;;14183:145::o;14333:635::-;14504:2;14556:21;;;14626:13;;14529:18;;;14648:22;;;14333:635;;14504:2;14727:15;;;;14701:2;14686:18;;;14333:635;14773:169;14787:6;14784:1;14781:13;14773:169;;;14848:13;;14836:26;;14917:15;;;;14882:12;;;;14809:1;14802:9;14773:169;;;-1:-1:-1;14959:3:1;;14484:484;-1:-1:-1;;;;;;14484:484:1:o;14973:187::-;15138:14;;15131:22;15113:41;;15101:2;15086:18;;15068:92::o;15165:221::-;;15314:2;15303:9;15296:21;15334:46;15376:2;15365:9;15361:18;15353:6;15334:46;:::i;15391:622::-;;15664:3;15653:9;15646:22;15691:47;15733:3;15722:9;15718:19;15710:6;15691:47;:::i;:::-;15786:9;15778:6;15774:22;15769:2;15758:9;15754:18;15747:50;15820:34;15847:6;15839;15820:34;:::i;:::-;15806:48;;15902:9;15894:6;15890:22;15885:2;15874:9;15870:18;15863:50;15930:34;15957:6;15949;15930:34;:::i;:::-;15922:42;;;16000:6;15995:2;15984:9;15980:18;15973:34;15636:377;;;;;;;:::o;16018:407::-;16220:2;16202:21;;;16259:2;16239:18;;;16232:30;16298:34;16293:2;16278:18;;16271:62;-1:-1:-1;;;16364:2:1;16349:18;;16342:41;16415:3;16400:19;;16192:233::o;16430:414::-;16632:2;16614:21;;;16671:2;16651:18;;;16644:30;16710:34;16705:2;16690:18;;16683:62;-1:-1:-1;;;16776:2:1;16761:18;;16754:48;16834:3;16819:19;;16604:240::o;16849:352::-;17051:2;17033:21;;;17090:2;17070:18;;;17063:30;17129;17124:2;17109:18;;17102:58;17192:2;17177:18;;17023:178::o;17206:400::-;17408:2;17390:21;;;17447:2;17427:18;;;17420:30;17486:34;17481:2;17466:18;;17459:62;-1:-1:-1;;;17552:2:1;17537:18;;17530:34;17596:3;17581:19;;17380:226::o;17611:349::-;17813:2;17795:21;;;17852:2;17832:18;;;17825:30;17891:27;17886:2;17871:18;;17864:55;17951:2;17936:18;;17785:175::o;17965:408::-;18167:2;18149:21;;;18206:2;18186:18;;;18179:30;18245:34;18240:2;18225:18;;18218:62;-1:-1:-1;;;18311:2:1;18296:18;;18289:42;18363:3;18348:19;;18139:234::o;18378:420::-;18580:2;18562:21;;;18619:2;18599:18;;;18592:30;18658:34;18653:2;18638:18;;18631:62;18729:26;18724:2;18709:18;;18702:54;18788:3;18773:19;;18552:246::o;18803:406::-;19005:2;18987:21;;;19044:2;19024:18;;;19017:30;19083:34;19078:2;19063:18;;19056:62;-1:-1:-1;;;19149:2:1;19134:18;;19127:40;19199:3;19184:19;;18977:232::o;19214:405::-;19416:2;19398:21;;;19455:2;19435:18;;;19428:30;19494:34;19489:2;19474:18;;19467:62;-1:-1:-1;;;19560:2:1;19545:18;;19538:39;19609:3;19594:19;;19388:231::o;19624:356::-;19826:2;19808:21;;;19845:18;;;19838:30;19904:34;19899:2;19884:18;;19877:62;19971:2;19956:18;;19798:182::o;19985:408::-;20187:2;20169:21;;;20226:2;20206:18;;;20199:30;20265:34;20260:2;20245:18;;20238:62;-1:-1:-1;;;20331:2:1;20316:18;;20309:42;20383:3;20368:19;;20159:234::o;20398:405::-;20600:2;20582:21;;;20639:2;20619:18;;;20612:30;20678:34;20673:2;20658:18;;20651:62;-1:-1:-1;;;20744:2:1;20729:18;;20722:39;20793:3;20778:19;;20572:231::o;20808:397::-;21010:2;20992:21;;;21049:2;21029:18;;;21022:30;21088:34;21083:2;21068:18;;21061:62;-1:-1:-1;;;21154:2:1;21139:18;;21132:31;21195:3;21180:19;;20982:223::o;21210:413::-;21412:2;21394:21;;;21451:2;21431:18;;;21424:30;21490:34;21485:2;21470:18;;21463:62;-1:-1:-1;;;21556:2:1;21541:18;;21534:47;21613:3;21598:19;;21384:239::o;21628:408::-;21830:2;21812:21;;;21869:2;21849:18;;;21842:30;21908:34;21903:2;21888:18;;21881:62;-1:-1:-1;;;21974:2:1;21959:18;;21952:42;22026:3;22011:19;;21802:234::o;22041:387::-;22317:6;22305:19;;;;22287:38;;22373:4;22361:17;;;;22356:2;22341:18;;22334:45;22410:2;22395:18;;22388:34;22275:2;22260:18;;22242:186::o;22433:185::-;22587:25;;;22575:2;22560:18;;22542:76::o;22805:2034::-;;23205:6;23194:9;23187:25;23231:2;23269:3;23264:2;23253:9;23249:18;23242:31;23296:47;23338:3;23327:9;23323:19;23315:6;23296:47;:::i;:::-;23362:2;23400:6;23395:2;23384:9;23380:18;23373:34;23455:9;23447:6;23443:22;23438:2;23427:9;23423:18;23416:50;23486:6;23521;23515:13;23552:6;23544;23537:22;23587:2;23579:6;23575:15;23568:22;;23647:2;23641;23633:6;23629:15;23621:6;23617:28;23613:37;23672:6;23666:4;23659:20;23718:2;23712:4;23702:19;23739:4;23752:1014;23766:6;23763:1;23760:13;23752:1014;;;23856:2;23852:7;23843:6;23835;23831:19;23827:33;23822:3;23815:46;23885:4;23925:6;23919:13;23961:36;23987:9;23961:36;:::i;:::-;24010:24;;;24057:1;24078:18;;;24109:127;;;;24254:1;24249:411;;;;24071:589;;24109:127;-1:-1:-1;;24158:24:1;;24141:15;;;24134:49;24207:15;;;;-1:-1:-1;24109:127:1;;24249:411;24287:6;24281:4;24274:20;24342:2;24336:4;24326:19;24373:4;24394:203;24410:8;24405:3;24402:17;24394:203;;;24522:7;24516:14;24511:2;24505:3;24497:6;24493:16;24489:25;24482:49;24576:2;24567:7;24563:16;24552:27;;24438:2;24433:3;24429:12;24422:19;;24394:203;;;24625:16;;24621:25;;;-1:-1:-1;;24071:589:1;-1:-1:-1;24744:12:1;;;;24683:3;;-1:-1:-1;;;24709:15:1;;;;;23788:1;23781:9;23752:1014;;;23756:3;;24783:6;24775:14;;;;;;;;24826:6;24820:3;24809:9;24805:19;24798:35;23177:1662;;;;;;;;:::o;24844:251::-;24914:2;24908:9;24944:17;;;24991:18;24976:34;;25012:22;;;24973:62;24970:2;;;25038:18;;:::i;:::-;25074:2;25067:22;24888:207;;-1:-1:-1;24888:207:1:o;25100:198::-;;25205:18;25197:6;25194:30;25191:2;;;25227:18;;:::i;:::-;-1:-1:-1;25287:4:1;25268:17;;;25264:28;;25181:117::o;25303:190::-;;25386:18;25378:6;25375:30;25372:2;;;25408:18;;:::i;:::-;-1:-1:-1;25476:2:1;25453:17;-1:-1:-1;;25449:31:1;25482:4;25445:42;;25362:131::o;25498:128::-;;25569:1;25565:6;25562:1;25559:13;25556:2;;;25575:18;;:::i;:::-;-1:-1:-1;25611:9:1;;25546:80::o;25631:168::-;;25737:1;25733;25729:6;25725:14;25722:1;25719:21;25714:1;25707:9;25700:17;25696:45;25693:2;;;25744:18;;:::i;:::-;-1:-1:-1;25784:9:1;;25683:116::o;25804:125::-;;25872:1;25869;25866:8;25863:2;;;25877:18;;:::i;:::-;-1:-1:-1;25914:9:1;;25853:76::o;25934:258::-;26006:1;26016:113;26030:6;26027:1;26024:13;26016:113;;;26106:11;;;26100:18;26087:11;;;26080:39;26052:2;26045:10;26016:113;;;26147:6;26144:1;26141:13;26138:2;;;-1:-1:-1;;26182:1:1;26164:16;;26157:27;25987:205::o;26197:380::-;26282:1;26272:12;;26329:1;26319:12;;;26340:2;;26394:4;26386:6;26382:17;26372:27;;26340:2;26447;26439:6;26436:14;26416:18;26413:38;26410:2;;;26493:10;26488:3;26484:20;26481:1;26474:31;26528:4;26525:1;26518:15;26556:4;26553:1;26546:15;26410:2;;26252:325;;;:::o;26582:135::-;;-1:-1:-1;;26642:17:1;;26639:2;;;26662:18;;:::i;:::-;-1:-1:-1;26709:1:1;26698:13;;26629:88::o;26722:175::-;;26803:4;26796:5;26792:16;26832:4;26823:7;26820:17;26817:2;;;26840:18;;:::i;:::-;26889:1;26876:15;;26767:130;-1:-1:-1;;26767:130:1:o;26902:209::-;;26960:1;26950:2;;-1:-1:-1;;;26985:31:1;;27039:4;27036:1;27029:15;27067:4;26992:1;27057:15;26950:2;-1:-1:-1;27096:9:1;;26940:171::o;27116:127::-;27177:10;27172:3;27168:20;27165:1;27158:31;27208:4;27205:1;27198:15;27232:4;27229:1;27222:15;27248:127;27309:10;27304:3;27300:20;27297:1;27290:31;27340:4;27337:1;27330:15;27364:4;27361:1;27354:15;27380:133;-1:-1:-1;;;;;27457:31:1;;27447:42;;27437:2;;27503:1;27500;27493:12;27518:133;-1:-1:-1;;;;;;27594:32:1;;27584:43;;27574:2;;27641:1;27638;27631:12

Swarm Source

ipfs://b56eec5563315257b0860708059d136b235fabda504ac5c3cad48931dcbd6afa
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.