ETH Price: $3,350.18 (-7.90%)

Token

 

Overview

Max Total Supply

9,200

Holders

294

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
trying2think.eth
0xbB29504F136db5f69Dd0e5C0AC5870b16E2D0941
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
ZombieTradingPost

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 1000 runs

Other Settings:
default evmVersion, GNU AGPLv3 license
File 1 of 28 : ZombieTradingPost.sol
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.4;

import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {ERC165, IERC165, ERC1155, ERC1155Pausable} from "@openzeppelin/contracts/token/ERC1155/extensions/ERC1155Pausable.sol";
import {ERC1155Holder, ERC1155Receiver} from "@openzeppelin/contracts/token/ERC1155/utils/ERC1155Holder.sol";
import {Strings} from "@openzeppelin/contracts/utils/Strings.sol";
import {IItemExecutor} from "./IItemExecutor.sol";
import {IZombieTradingPost} from "./IZombieTradingPost.sol";

contract ZombieTradingPost is Ownable, ERC1155Pausable, ERC1155Holder {
    using Strings for uint256;

    address private antidoteInjector;

    string private baseURI;

    mapping(uint256 => IZombieTradingPost.ItemDefinition) public registeredItems;

    uint256[] public itemIds;

    event UpdateBaseURI(string uri);

    event UpdateInjector(address injector);

    event ItemAdded(uint256 itemId);

    event ItemDisabled(uint256 itemId);
    
    event ItemCostUpdated(uint256 oldCost, uint256 newCost);

    event ItemPurchased(address purchaser, uint256 itemId, uint256 amount);

    event ItemDestroyed(address destroyer, uint256 itemId, uint256 amount);

    constructor(string memory _baseURI) ERC1155(_baseURI) {
        baseURI = _baseURI;
    }

    function addItem(uint256 cost, uint256 _purchaseLimit, bool feoEnabled, bool autoEnable, bool mint) public onlyOwner {
        uint256 _itemId = itemIds.length;
        itemIds.push(_itemId);
        registeredItems[_itemId] = IZombieTradingPost.ItemDefinition({
            executor: address(0x0),
            feoEnabled: feoEnabled,
            purchased: 0,
            purchaseLimit: _purchaseLimit,
            cost: cost,
            enabled: autoEnable
        });

        if(mint) {
            _mint(address(this), _itemId, _purchaseLimit, "");
        }

        emit ItemAdded(_itemId);
    }

    function transferItems(uint256 itemId) external onlyOwner _itemRegistered(itemId) {
        safeTransferFrom(address(this), msg.sender, itemId, balanceOf(address(this), itemId), "");
    }

    function updateItemCost(uint256 itemId, uint256 cost) external onlyOwner _itemRegistered(itemId) {
        IZombieTradingPost.ItemDefinition storage definition = registeredItems[itemId];
        uint256 oldCost = definition.cost;
        definition.cost = cost;
        emit ItemCostUpdated(oldCost, cost);
    }

    function disableItem(uint256 itemId) external onlyOwner {
        registeredItems[itemId].enabled = false;
        emit ItemDisabled(itemId);
    }

    function getItemLength() external view returns (uint256 length) {
        length = itemIds.length;
    }

    function getItem(uint256 itemId) external view _itemRegistered(itemId) _itemEnabled(itemId) returns (IZombieTradingPost.ItemDefinition memory definition) {
        return registeredItems[itemId];
    }

    function getItems() external view returns (IZombieTradingPost.ItemDefinition[] memory definitions) {
        definitions = new IZombieTradingPost.ItemDefinition[](itemIds.length);
        for(uint256 index = 0; index<itemIds.length; index++) {
            definitions[index] = registeredItems[itemIds[index]];
        }
    }

    function destroyItem(uint256 itemId, uint256 amount) external _itemRegistered(itemId) whenNotPaused {
        _burn(msg.sender, itemId, amount);
        emit ItemDestroyed(msg.sender, itemId, amount);
    }

    function destroyItemFor(address owner, uint256 itemId, uint256 amount) external _itemRegistered(itemId) _onlyExecutor(itemId) whenNotPaused {
        _burn(owner, itemId, amount);
        emit ItemDestroyed(owner, itemId, amount);
    }

    function updateBaseUri(string memory _baseURI) external onlyOwner {
        baseURI = _baseURI;
        _setURI(_baseURI);
        emit UpdateBaseURI(baseURI);
    }

    function mintBatch(uint256[] memory ids, uint256[] memory amounts) external onlyOwner {
        _mintBatch(owner(), ids, amounts, "");
    }

    function mintBatchFor(uint256[] memory ids, uint256[] memory amounts, address to) external onlyOwner {
        _mintBatch(to, ids, amounts, "");
    }

    function uri(uint256 typeId)
        public
        view                
        override
        returns (string memory)
    {
        require(
            registeredItems[typeId].enabled,
            "URI requested for invalid item type"
        );
        return
            bytes(baseURI).length > 0
                ? string(abi.encodePacked(baseURI, typeId.toString()))
                : baseURI;
    }

    function withdraw() external onlyOwner {
        uint balance = address(this).balance;
        payable(msg.sender).transfer(balance);
    }

    modifier _itemRegistered(uint256 itemId) {
        require(itemIds.length > itemId, "item_non_existent");
        _;
    }

    modifier _itemEnabled(uint256 itemId) {
        require(registeredItems[itemId].enabled, "item_disabled");
        _;
    }

    modifier _onlyExecutor(uint256 tokenId) {
        IZombieTradingPost.ItemDefinition memory definition = registeredItems[tokenId];
        if(definition.executor != address(0x0)) {
            require(msg.sender == definition.executor, "sender_not_executor");
        }
        _;
    }

    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC1155, ERC1155Receiver) returns (bool) {
        return super.supportsInterface(interfaceId);
    }

    function _beforeTokenTransfer(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual override {
        super._beforeTokenTransfer(operator, from, to, ids, amounts, data);

        for(uint256 id = ids[0]; id<ids.length; id++) {
            IZombieTradingPost.ItemDefinition memory definition = registeredItems[id];
            if(definition.executor != address(0x0)) {
                IItemExecutor(definition.executor).executeOnTransfer(id);
            }
        }
    }

    function pause() external onlyOwner whenNotPaused {
        super._pause();
    }

    function unpause() external onlyOwner whenPaused {
        super._unpause();
    }
}

File 2 of 28 : IItemExecutor.sol
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.4;

interface IItemExecutor {
    function executeOnTransfer(uint256 itemId) external returns (bool executed);
    function executeAction(uint256 itemId) external returns (bool executed);
}

File 3 of 28 : Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (access/Ownable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

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

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _transferOwnership(_msgSender());
    }

    /**
     * @dev Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _transferOwnership(address(0));
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Internal function without access restriction.
     */
    function _transferOwnership(address newOwner) internal virtual {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

File 4 of 28 : ERC1155Pausable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC1155/extensions/ERC1155Pausable.sol)

pragma solidity ^0.8.0;

import "../ERC1155.sol";
import "../../../security/Pausable.sol";

/**
 * @dev ERC1155 token with pausable token transfers, minting and burning.
 *
 * Useful for scenarios such as preventing trades until the end of an evaluation
 * period, or having an emergency switch for freezing all token transfers in the
 * event of a large bug.
 *
 * _Available since v3.1._
 */
abstract contract ERC1155Pausable is ERC1155, Pausable {
    /**
     * @dev See {ERC1155-_beforeTokenTransfer}.
     *
     * Requirements:
     *
     * - the contract must not be paused.
     */
    function _beforeTokenTransfer(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual override {
        super._beforeTokenTransfer(operator, from, to, ids, amounts, data);

        require(!paused(), "ERC1155Pausable: token transfer while paused");
    }
}

File 5 of 28 : ERC1155Holder.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC1155/utils/ERC1155Holder.sol)

pragma solidity ^0.8.0;

import "./ERC1155Receiver.sol";

/**
 * @dev _Available since v3.1._
 */
contract ERC1155Holder is ERC1155Receiver {
    function onERC1155Received(
        address,
        address,
        uint256,
        uint256,
        bytes memory
    ) public virtual override returns (bytes4) {
        return this.onERC1155Received.selector;
    }

    function onERC1155BatchReceived(
        address,
        address,
        uint256[] memory,
        uint256[] memory,
        bytes memory
    ) public virtual override returns (bytes4) {
        return this.onERC1155BatchReceived.selector;
    }
}

File 6 of 28 : Strings.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/Strings.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

File 7 of 28 : IZombieTradingPost.sol
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.4;

interface IZombieTradingPost {
    struct ItemDefinition {
        address executor;
        uint256 cost;
        uint256 purchased;
        uint256 purchaseLimit;
        bool feoEnabled;
        bool enabled;
    }
}

File 8 of 28 : Context.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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

File 9 of 28 : ERC1155.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC1155/ERC1155.sol)

pragma solidity ^0.8.0;

import "./IERC1155.sol";
import "./IERC1155Receiver.sol";
import "./extensions/IERC1155MetadataURI.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/introspection/ERC165.sol";

/**
 * @dev Implementation of the basic standard multi-token.
 * See https://eips.ethereum.org/EIPS/eip-1155
 * Originally based on code by Enjin: https://github.com/enjin/erc-1155
 *
 * _Available since v3.1._
 */
contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
    using Address for address;

    // Mapping from token ID to account balances
    mapping(uint256 => mapping(address => uint256)) private _balances;

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

    // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json
    string private _uri;

    /**
     * @dev See {_setURI}.
     */
    constructor(string memory uri_) {
        _setURI(uri_);
    }

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

    /**
     * @dev See {IERC1155MetadataURI-uri}.
     *
     * This implementation returns the same URI for *all* token types. It relies
     * on the token type ID substitution mechanism
     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
     *
     * Clients calling this function must replace the `\{id\}` substring with the
     * actual token type ID.
     */
    function uri(uint256) public view virtual override returns (string memory) {
        return _uri;
    }

    /**
     * @dev See {IERC1155-balanceOf}.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
        require(account != address(0), "ERC1155: balance query for the zero address");
        return _balances[id][account];
    }

    /**
     * @dev See {IERC1155-balanceOfBatch}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] memory accounts, uint256[] memory ids)
        public
        view
        virtual
        override
        returns (uint256[] memory)
    {
        require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");

        uint256[] memory batchBalances = new uint256[](accounts.length);

        for (uint256 i = 0; i < accounts.length; ++i) {
            batchBalances[i] = balanceOf(accounts[i], ids[i]);
        }

        return batchBalances;
    }

    /**
     * @dev See {IERC1155-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

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

    /**
     * @dev See {IERC1155-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) public virtual override {
        require(
            from == _msgSender() || isApprovedForAll(from, _msgSender()),
            "ERC1155: caller is not owner nor approved"
        );
        _safeTransferFrom(from, to, id, amount, data);
    }

    /**
     * @dev See {IERC1155-safeBatchTransferFrom}.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) public virtual override {
        require(
            from == _msgSender() || isApprovedForAll(from, _msgSender()),
            "ERC1155: transfer caller is not owner nor approved"
        );
        _safeBatchTransferFrom(from, to, ids, amounts, data);
    }

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function _safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        require(to != address(0), "ERC1155: transfer to the zero address");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, from, to, _asSingletonArray(id), _asSingletonArray(amount), data);

        uint256 fromBalance = _balances[id][from];
        require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
        unchecked {
            _balances[id][from] = fromBalance - amount;
        }
        _balances[id][to] += amount;

        emit TransferSingle(operator, from, to, id, amount);

        _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function _safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
        require(to != address(0), "ERC1155: transfer to the zero address");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, from, to, ids, amounts, data);

        for (uint256 i = 0; i < ids.length; ++i) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];

            uint256 fromBalance = _balances[id][from];
            require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
            unchecked {
                _balances[id][from] = fromBalance - amount;
            }
            _balances[id][to] += amount;
        }

        emit TransferBatch(operator, from, to, ids, amounts);

        _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);
    }

    /**
     * @dev Sets a new URI for all token types, by relying on the token type ID
     * substitution mechanism
     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
     *
     * By this mechanism, any occurrence of the `\{id\}` substring in either the
     * URI or any of the amounts in the JSON file at said URI will be replaced by
     * clients with the token type ID.
     *
     * For example, the `https://token-cdn-domain/\{id\}.json` URI would be
     * interpreted by clients as
     * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
     * for token type ID 0x4cce0.
     *
     * See {uri}.
     *
     * Because these URIs cannot be meaningfully represented by the {URI} event,
     * this function emits no events.
     */
    function _setURI(string memory newuri) internal virtual {
        _uri = newuri;
    }

    /**
     * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function _mint(
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        require(to != address(0), "ERC1155: mint to the zero address");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, address(0), to, _asSingletonArray(id), _asSingletonArray(amount), data);

        _balances[id][to] += amount;
        emit TransferSingle(operator, address(0), to, id, amount);

        _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function _mintBatch(
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {
        require(to != address(0), "ERC1155: mint to the zero address");
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);

        for (uint256 i = 0; i < ids.length; i++) {
            _balances[ids[i]][to] += amounts[i];
        }

        emit TransferBatch(operator, address(0), to, ids, amounts);

        _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
    }

    /**
     * @dev Destroys `amount` tokens of token type `id` from `from`
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `from` must have at least `amount` tokens of token type `id`.
     */
    function _burn(
        address from,
        uint256 id,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC1155: burn from the zero address");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, from, address(0), _asSingletonArray(id), _asSingletonArray(amount), "");

        uint256 fromBalance = _balances[id][from];
        require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
        unchecked {
            _balances[id][from] = fromBalance - amount;
        }

        emit TransferSingle(operator, from, address(0), id, amount);
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     */
    function _burnBatch(
        address from,
        uint256[] memory ids,
        uint256[] memory amounts
    ) internal virtual {
        require(from != address(0), "ERC1155: burn from the zero address");
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, from, address(0), ids, amounts, "");

        for (uint256 i = 0; i < ids.length; i++) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];

            uint256 fromBalance = _balances[id][from];
            require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
            unchecked {
                _balances[id][from] = fromBalance - amount;
            }
        }

        emit TransferBatch(operator, from, address(0), ids, amounts);
    }

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits a {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC1155: setting approval status for self");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning, as well as batched variants.
     *
     * The same hook is called on both single and batched variants. For single
     * transfers, the length of the `id` and `amount` arrays will be 1.
     *
     * Calling conditions (for each `id` and `amount` pair):
     *
     * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * of token type `id` will be  transferred to `to`.
     * - When `from` is zero, `amount` tokens of token type `id` will be minted
     * for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
     * will be burned.
     * - `from` and `to` are never both zero.
     * - `ids` and `amounts` have the same, non-zero length.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {}

    function _doSafeTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) private {
        if (to.isContract()) {
            try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
                if (response != IERC1155Receiver.onERC1155Received.selector) {
                    revert("ERC1155: ERC1155Receiver rejected tokens");
                }
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert("ERC1155: transfer to non ERC1155Receiver implementer");
            }
        }
    }

    function _doSafeBatchTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) private {
        if (to.isContract()) {
            try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (
                bytes4 response
            ) {
                if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {
                    revert("ERC1155: ERC1155Receiver rejected tokens");
                }
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert("ERC1155: transfer to non ERC1155Receiver implementer");
            }
        }
    }

    function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {
        uint256[] memory array = new uint256[](1);
        array[0] = element;

        return array;
    }
}

File 10 of 28 : Pausable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (security/Pausable.sol)

pragma solidity ^0.8.0;

import "../utils/Context.sol";

/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        require(!paused(), "Pausable: paused");
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        require(paused(), "Pausable: not paused");
        _;
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

File 11 of 28 : IERC1155.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC1155/IERC1155.sol)

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev Required interface of an ERC1155 compliant contract, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1155[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155 is IERC165 {
    /**
     * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
     */
    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

    /**
     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
     * transfers.
     */
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

    /**
     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
     * `approved`.
     */
    event ApprovalForAll(address indexed account, address indexed operator, bool approved);

    /**
     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
     *
     * If an {URI} event was emitted for `id`, the standard
     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
     * returned by {IERC1155MetadataURI-uri}.
     */
    event URI(string value, uint256 indexed id);

    /**
     * @dev Returns the amount of tokens of token type `id` owned by `account`.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) external view returns (uint256);

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
        external
        view
        returns (uint256[] memory);

    /**
     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
     *
     * Emits an {ApprovalForAll} event.
     *
     * Requirements:
     *
     * - `operator` cannot be the caller.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
     *
     * See {setApprovalForAll}.
     */
    function isApprovedForAll(address account, address operator) external view returns (bool);

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must be have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) external;
}

File 12 of 28 : IERC1155Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC1155/IERC1155Receiver.sol)

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

/**
 * @dev _Available since v3.1._
 */
interface IERC1155Receiver is IERC165 {
    /**
        @dev Handles the receipt of a single ERC1155 token type. This function is
        called at the end of a `safeTransferFrom` after the balance has been updated.
        To accept the transfer, this must return
        `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
        (i.e. 0xf23a6e61, or its own function selector).
        @param operator The address which initiated the transfer (i.e. msg.sender)
        @param from The address which previously owned the token
        @param id The ID of the token being transferred
        @param value The amount of tokens being transferred
        @param data Additional data with no specified format
        @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
    */
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    ) external returns (bytes4);

    /**
        @dev Handles the receipt of a multiple ERC1155 token types. This function
        is called at the end of a `safeBatchTransferFrom` after the balances have
        been updated. To accept the transfer(s), this must return
        `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
        (i.e. 0xbc197c81, or its own function selector).
        @param operator The address which initiated the batch transfer (i.e. msg.sender)
        @param from The address which previously owned the token
        @param ids An array containing ids of each token being transferred (order and length must match values array)
        @param values An array containing amounts of each token being transferred (order and length must match ids array)
        @param data Additional data with no specified format
        @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
    */
    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external returns (bytes4);
}

File 13 of 28 : IERC1155MetadataURI.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC1155/extensions/IERC1155MetadataURI.sol)

pragma solidity ^0.8.0;

import "../IERC1155.sol";

/**
 * @dev Interface of the optional ERC1155MetadataExtension interface, as defined
 * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155MetadataURI is IERC1155 {
    /**
     * @dev Returns the URI for token type `id`.
     *
     * If the `\{id\}` substring is present in the URI, it must be replaced by
     * clients with the actual token type ID.
     */
    function uri(uint256 id) external view returns (string memory);
}

File 14 of 28 : Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/Address.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

File 15 of 28 : ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

File 16 of 28 : IERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

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

File 17 of 28 : ERC1155Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC1155/utils/ERC1155Receiver.sol)

pragma solidity ^0.8.0;

import "../IERC1155Receiver.sol";
import "../../../utils/introspection/ERC165.sol";

/**
 * @dev _Available since v3.1._
 */
abstract contract ERC1155Receiver is ERC165, IERC1155Receiver {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override(ERC165, IERC165) returns (bool) {
        return interfaceId == type(IERC1155Receiver).interfaceId || super.supportsInterface(interfaceId);
    }
}

File 18 of 28 : ERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;

import "./IERC721.sol";
import "./IERC721Receiver.sol";
import "./extensions/IERC721Metadata.sol";
import "../../utils/Address.sol";
import "../../utils/Context.sol";
import "../../utils/Strings.sol";
import "../../utils/introspection/ERC165.sol";

/**
 * @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 {
        _setApprovalForAll(_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 Approve `operator` to operate on all of `owner` tokens
     *
     * Emits a {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC721: approve to caller");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

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

File 19 of 28 : IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

import "../../utils/introspection/IERC165.sol";

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

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

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

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

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

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

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

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

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

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

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

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

File 20 of 28 : IERC721Receiver.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

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

File 21 of 28 : IERC721Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;

import "../IERC721.sol";

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

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

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

File 22 of 28 : ZombieFrens.sol
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.4;

import {Ownable} from "@openzeppelin/contracts/access/Ownable.sol";
import {ERC721, ERC721Enumerable} from "@openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol";
import {TeiredWhitelist} from "./TeiredWhitelist.sol";
import {IYieldVestment} from "./IYieldVestment.sol";

/// @author tempest-sol
contract ZombieFrens is Ownable, ERC721Enumerable, TeiredWhitelist {

    IYieldVestment public vestmentPool;

    uint256 constant public MAX_ZOMBIES = 9999;

    uint8 constant public PER_WALLET_MINT = 10;
    uint8 constant public MAX_PER_TX = 2;
    uint8 constant public MAXIMUM_RESERVE = 100;
    uint8 public reserveCount;

    bool public publicSaleActive;

    string private baseURI;
    
    mapping(address => uint8) public reserveList;

    event ZombieMinted(address minter, uint8 amount);

    event PublicSaleStatusChanged(bool oldStatus, bool newStatus);

    event ZombieReservedFor(address receiver, uint8 amount);

    constructor() ERC721("ZombieFrens", "ZFREN") { }

    function setVestmentPool(address _vestmentPool) external onlyOwner {
        vestmentPool = IYieldVestment(_vestmentPool);
    }

    function setBaseURI(string memory uri) external onlyOwner {
        baseURI = uri;
    }

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

    function reserveFor(address to, uint8 amount) external onlyOwner {
        require(to != address(0x0), "zero_address");
        require(amount > 0, "amount_zero");
        require(reserveCount < MAXIMUM_RESERVE && reserveCount + amount <= MAXIMUM_RESERVE, "not_enough_reserve");

        reserveList[to] += amount;
    }

    function setWhitelistSale(WhitelistTeir teir) external onlyOwner {
        require(currentWhitelistSale != teir, "sale_already_active");
        require(!publicSaleActive, "public_sale_active");
        WhitelistTeir oldTeir = currentWhitelistSale;
        currentWhitelistSale = teir;

        emit WhitelistSaleChanged(oldTeir, currentWhitelistSale);
    }

    function claimWhitelist(bytes32[] calldata merkleProof, uint8 amount) external {
        super._claimWhitelist(merkleProof, amount);
        _mintZombie(msg.sender, amount);
        emit WhitelistClaimed(msg.sender, amount);
    }

    function claimReserved() external _hasReserves {
        uint8 reserves = getReserveCount();
        reserveList[msg.sender] -= reserves;
        _mintZombie(msg.sender, reserves);
    }

    function mint(uint8 amount) external _canMint(amount) _publicSale {
        _mintZombie(msg.sender, amount);
    }

    function _mintZombie(address to, uint8 amount) internal {
        uint256 tokenId = totalSupply();
        for(uint8 i = 0; i<amount; i++) {
            _safeMint(to, tokenId + i);
        }
        emit ZombieMinted(msg.sender, amount);
    }

    function flipPublicSale() external onlyOwner {
        currentWhitelistSale = WhitelistTeir.CONCLUDED;
        publicSaleActive = !publicSaleActive;
        emit PublicSaleStatusChanged(!publicSaleActive, publicSaleActive);
    }

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

    function getReserveCount() public view returns (uint8 _reserveCount) {
        _reserveCount = reserveList[msg.sender];
    }

    function withdraw() external onlyOwner {
        uint balance = address(this).balance;
        payable(msg.sender).transfer(balance);
    }

    modifier _canMint(uint8 amount) {
        require(amount <= MAX_PER_TX, "exceeds_tx_limit");
        require(balanceOf(msg.sender) + amount <= PER_WALLET_MINT, "exceeds_wallet_limit");
        _;
    }

    modifier _hasReserves() {
        require(reserveList[msg.sender] > 0, "no_reserves");
        _;
    }

    modifier _notVested(uint256 tokenId) {
        if(address(vestmentPool) != address(0x0)) {
            bool isVested = vestmentPool.isVested(tokenId);
            require(!isVested, "cannot_transfer_vested_token");
        }
        _;
    }

    modifier _publicSale() {
        if(currentWhitelistSale == WhitelistTeir.INACTIVE && !publicSaleActive) revert("no_active_sale");
        require(currentWhitelistSale == WhitelistTeir.CONCLUDED, "whitelist_sale_active");
        require(publicSaleActive, "public_sale_inactive");
        _;
    }
}

File 23 of 28 : ERC721Enumerable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC721/extensions/ERC721Enumerable.sol)

pragma solidity ^0.8.0;

import "../ERC721.sol";
import "./IERC721Enumerable.sol";

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

File 24 of 28 : TeiredWhitelist.sol
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.4;

import {MerkleProof} from "@openzeppelin/contracts/utils/cryptography/MerkleProof.sol";

/// @author tempest-sol
abstract contract TeiredWhitelist {

    enum WhitelistTeir {
        INACTIVE,
        OG,
        OG_OG,
        CONCLUDED
    }

    WhitelistTeir public currentWhitelistSale;

    mapping(address => uint8) public claimedWhitelistMints;

    mapping(WhitelistTeir => bytes32) public merkleRoots;

    mapping(WhitelistTeir => uint8) public teiredWhitelistMintAmount;

    event WhitelistMerkleRootUpdated(WhitelistTeir teir, bytes32 oldMerkleRoot, bytes32 newMerkleRoot);

    event WhitelistSaleChanged(WhitelistTeir oldTeir, WhitelistTeir newTeir);

    event WhitelistClaimed(address claimee, uint8 amount);

    constructor() {
        teiredWhitelistMintAmount[WhitelistTeir.OG] = 3;
        teiredWhitelistMintAmount[WhitelistTeir.OG_OG] = 5;
    }

    function getClaimableAmount(WhitelistTeir teir) public view returns (uint8 amount) {
        uint8 mintable = teiredWhitelistMintAmount[teir];
        uint8 claimed = claimedWhitelistMints[msg.sender];
        amount = mintable > claimed ? mintable - claimed : 0;
    }

    function _claimWhitelist(bytes32[] calldata merkleProof, uint8 amount) internal virtual _canMintWhitelist(merkleProof, amount) {
        claimedWhitelistMints[msg.sender] += amount;
    }

    function updateWhitelistMerkle(WhitelistTeir teir, bytes32 _merkleRoot) external {
        require(teir > WhitelistTeir.INACTIVE && teir <= WhitelistTeir.OG_OG, "invalid_whitelist_teir");
        require(_merkleRoot != 0x0, "invalid_merkle_root");
        bytes32 currentRoot = merkleRoots[teir];
        merkleRoots[teir] =_merkleRoot;

        emit WhitelistMerkleRootUpdated(teir, currentRoot, _merkleRoot);
    }

    function whitelistData(bytes32[] calldata _merkleProof) private view returns (WhitelistTeir teir, bool valid) {
        bytes32 leaf = keccak256(abi.encodePacked(msg.sender));
        valid = MerkleProof.verify(_merkleProof, merkleRoots[currentWhitelistSale], leaf);
        teir = currentWhitelistSale;
    }

    modifier _canMintWhitelist(bytes32[] calldata merkleProof, uint8 amount) {
        (WhitelistTeir teir, bool isValid) = whitelistData(merkleProof);
        require(isValid, "not_whitelisted");
        uint8 claimable = getClaimableAmount(teir);
        require(amount > 0 && amount <= claimable, "amount_exceeds_claimable");
        _;
    }

}

File 25 of 28 : IYieldVestment.sol
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.4;

/// @author tempest-sol
interface IYieldVestment {
    function isVested(uint256 tokenId) external view returns (bool vested);
}

File 26 of 28 : IERC721Enumerable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;

import "../IERC721.sol";

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

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

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

File 27 of 28 : MerkleProof.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.0 (utils/cryptography/MerkleProof.sol)

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Trees proofs.
 *
 * The proofs can be generated using the JavaScript library
 * https://github.com/miguelmota/merkletreejs[merkletreejs].
 * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
 *
 * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merklee tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            bytes32 proofElement = proof[i];
            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
            }
        }
        return computedHash;
    }
}

File 28 of 28 : YieldVestment.sol
// SPDX-License-Identifier: AGPL-3.0-or-later
pragma solidity ^0.8.4;

import {IYieldVestment} from "./IYieldVestment.sol";

contract YieldVestment is IYieldVestment {

    function isVested(uint256 tokenId) external view override returns (bool vested) {
        vested = false;
    }

}

Settings
{
  "metadata": {
    "bytecodeHash": "none"
  },
  "optimizer": {
    "enabled": true,
    "runs": 1000
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "abi"
      ]
    }
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_baseURI","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"itemId","type":"uint256"}],"name":"ItemAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"oldCost","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"newCost","type":"uint256"}],"name":"ItemCostUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"destroyer","type":"address"},{"indexed":false,"internalType":"uint256","name":"itemId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ItemDestroyed","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"itemId","type":"uint256"}],"name":"ItemDisabled","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"purchaser","type":"address"},{"indexed":false,"internalType":"uint256","name":"itemId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ItemPurchased","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"uri","type":"string"}],"name":"UpdateBaseURI","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"injector","type":"address"}],"name":"UpdateInjector","type":"event"},{"inputs":[{"internalType":"uint256","name":"cost","type":"uint256"},{"internalType":"uint256","name":"_purchaseLimit","type":"uint256"},{"internalType":"bool","name":"feoEnabled","type":"bool"},{"internalType":"bool","name":"autoEnable","type":"bool"},{"internalType":"bool","name":"mint","type":"bool"}],"name":"addItem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"itemId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"destroyItem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"itemId","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"destroyItemFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"itemId","type":"uint256"}],"name":"disableItem","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"itemId","type":"uint256"}],"name":"getItem","outputs":[{"components":[{"internalType":"address","name":"executor","type":"address"},{"internalType":"uint256","name":"cost","type":"uint256"},{"internalType":"uint256","name":"purchased","type":"uint256"},{"internalType":"uint256","name":"purchaseLimit","type":"uint256"},{"internalType":"bool","name":"feoEnabled","type":"bool"},{"internalType":"bool","name":"enabled","type":"bool"}],"internalType":"struct IZombieTradingPost.ItemDefinition","name":"definition","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getItemLength","outputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getItems","outputs":[{"components":[{"internalType":"address","name":"executor","type":"address"},{"internalType":"uint256","name":"cost","type":"uint256"},{"internalType":"uint256","name":"purchased","type":"uint256"},{"internalType":"uint256","name":"purchaseLimit","type":"uint256"},{"internalType":"bool","name":"feoEnabled","type":"bool"},{"internalType":"bool","name":"enabled","type":"bool"}],"internalType":"struct IZombieTradingPost.ItemDefinition[]","name":"definitions","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"itemIds","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"}],"name":"mintBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"address","name":"to","type":"address"}],"name":"mintBatchFor","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155BatchReceived","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"onERC1155Received","outputs":[{"internalType":"bytes4","name":"","type":"bytes4"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"registeredItems","outputs":[{"internalType":"address","name":"executor","type":"address"},{"internalType":"uint256","name":"cost","type":"uint256"},{"internalType":"uint256","name":"purchased","type":"uint256"},{"internalType":"uint256","name":"purchaseLimit","type":"uint256"},{"internalType":"bool","name":"feoEnabled","type":"bool"},{"internalType":"bool","name":"enabled","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"internalType":"uint256[]","name":"amounts","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"amount","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"itemId","type":"uint256"}],"name":"transferItems","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseURI","type":"string"}],"name":"updateBaseUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"itemId","type":"uint256"},{"internalType":"uint256","name":"cost","type":"uint256"}],"name":"updateItemCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"typeId","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b506040516200389338038062003893833981016040819052620000349162000182565b80620000403362000073565b6200004b81620000c3565b506004805460ff1916905580516200006b906005906020840190620000dc565b5050620002ab565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b8051620000d8906003906020840190620000dc565b5050565b828054620000ea9062000258565b90600052602060002090601f0160209004810192826200010e576000855562000159565b82601f106200012957805160ff191683800117855562000159565b8280016001018555821562000159579182015b82811115620001595782518255916020019190600101906200013c565b50620001679291506200016b565b5090565b5b808211156200016757600081556001016200016c565b6000602080838503121562000195578182fd5b82516001600160401b0380821115620001ac578384fd5b818501915085601f830112620001c0578384fd5b815181811115620001d557620001d562000295565b604051601f8201601f19908116603f0116810190838211818310171562000200576200020062000295565b81604052828152888684870101111562000218578687fd5b8693505b828410156200023b57848401860151818501870152928501926200021c565b828411156200024c57868684830101525b98975050505050505050565b600181811c908216806200026d57607f821691505b602082108114156200028f57634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052604160045260246000fd5b6135d880620002bb6000396000f3fe608060405234801561001057600080fd5b50600436106101e45760003560e01c806365dd80a01161010f578063bc197c81116100a2578063e985e9c511610071578063e985e9c5146104a1578063f23a6e61146104dd578063f242432a146104fc578063f2fde38b1461050f57600080fd5b8063bc197c8114610430578063d351cfdc14610468578063d5a3deca1461047b578063dcca20431461048e57600080fd5b806392184bfb116100de57806392184bfb146103e4578063a22cb465146103f7578063b01d1c911461040a578063b3dc00fe1461041d57600080fd5b806365dd80a0146103a6578063715018a6146103b95780638456cb59146103c15780638da5cb5b146103c957600080fd5b80633ccfd60b1161018757806348d9b4021161015657806348d9b402146102da5780634e1273f4146103685780635c975abb146103885780635f09c7821461039357600080fd5b80633ccfd60b146102ad5780633f4ba83a146102b5578063410d59cc146102bd5780634362bca5146102d257600080fd5b80632eb2c2d6116101c35780632eb2c2d6146102525780633129e77314610267578063366af9ef1461028757806339f7e37f1461029a57600080fd5b8062fdd58e146101e957806301ffc9a71461020f5780630e89341c14610232575b600080fd5b6101fc6101f7366004612d27565b610522565b6040519081526020015b60405180910390f35b61022261021d366004612f24565b6105d0565b6040519015158152602001610206565b610245610240366004612fa2565b6105db565b6040516102069190613291565b610265610260366004612be8565b610741565b005b61027a610275366004612fa2565b6107e3565b6040516102069190613325565b610265610295366004612fdb565b610933565b6102656102a8366004612f5c565b610abb565b610265610b5b565b610265610bd6565b6102c5610c7a565b60405161020691906131c0565b6007546101fc565b61032d6102e8366004612fa2565b600660205260009081526040902080546001820154600283015460038401546004909401546001600160a01b0390931693919290919060ff8082169161010090041686565b604080516001600160a01b039097168752602087019590955293850192909252606084015215156080830152151560a082015260c001610206565b61037b610376366004612d82565b610df2565b6040516102069190613250565b60045460ff16610222565b6102656103a1366004612fba565b610f68565b6102656103b4366004612fa2565b611046565b6102656110fa565b61026561114c565b6000546040516001600160a01b039091168152602001610206565b6102656103f2366004612fa2565b6111e2565b610265610405366004612cf1565b611276565b610265610418366004612fba565b611281565b6101fc61042b366004612fa2565b61136d565b61044f61043e366004612be8565b63bc197c8160e01b95945050505050565b6040516001600160e01b03199091168152602001610206565b610265610476366004612e4d565b61138e565b610265610489366004612e97565b611402565b61026561049c366004612d50565b61146a565b6102226104af366004612bb6565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205460ff1690565b61044f6104eb366004612c8e565b63f23a6e6160e01b95945050505050565b61026561050a366004612c8e565b611612565b61026561051d366004612b9c565b6116ad565b60006001600160a01b0383166105a55760405162461bcd60e51b815260206004820152602b60248201527f455243313135353a2062616c616e636520717565727920666f7220746865207a60448201527f65726f206164647265737300000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5060008181526001602090815260408083206001600160a01b03861684529091529020545b92915050565b60006105ca8261177d565b600081815260066020526040902060040154606090610100900460ff1661066a5760405162461bcd60e51b815260206004820152602360248201527f5552492072657175657374656420666f7220696e76616c6964206974656d207460448201527f7970650000000000000000000000000000000000000000000000000000000000606482015260840161059c565b6000600580546106799061340c565b905011610710576005805461068d9061340c565b80601f01602080910402602001604051908101604052809291908181526020018280546106b99061340c565b80156107065780601f106106db57610100808354040283529160200191610706565b820191906000526020600020905b8154815290600101906020018083116106e957829003601f168201915b50505050506105ca565b600561071b836117bb565b60405160200161072c92919061309f565b60405160208183030381529060405292915050565b6001600160a01b03851633148061075d575061075d85336104af565b6107cf5760405162461bcd60e51b815260206004820152603260248201527f455243313135353a207472616e736665722063616c6c6572206973206e6f742060448201527f6f776e6572206e6f7220617070726f7665640000000000000000000000000000606482015260840161059c565b6107dc8585858585611911565b5050505050565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091526007548290811061085c5760405162461bcd60e51b81526020600482015260116024820152701a5d195b57db9bdb97d95e1a5cdd195b9d607a1b604482015260640161059c565b6000838152600660205260409020600401548390610100900460ff166108c45760405162461bcd60e51b815260206004820152600d60248201527f6974656d5f64697361626c656400000000000000000000000000000000000000604482015260640161059c565b505050600090815260066020908152604091829020825160c08101845281546001600160a01b031681526001820154928101929092526002810154928201929092526003820154606082015260049091015460ff8082161515608084015261010090910416151560a082015290565b6000546001600160a01b0316331461097b5760405162461bcd60e51b815260206004820181905260248201526000805160206135ac833981519152604482015260640161059c565b6007805460018082019092557fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68881018190556040805160c081018252600080825260208281018b8152838501838152606085018c81528b1515608087019081528b151560a08801908152898752600690955296909420945185546001600160a01b039190911673ffffffffffffffffffffffffffffffffffffffff1990911617855590519684019690965594516002830155516003820155905160049091018054935115156101000261ff00199215159290921661ffff1990941693909317179091558115610a7f57610a7f30828760405180602001604052806000815250611b9c565b6040518181527f186760a37e06b130959978c68b5c592841caf4f64de1dc960b2c54cf454ca9dd906020015b60405180910390a1505050505050565b6000546001600160a01b03163314610b035760405162461bcd60e51b815260206004820181905260248201526000805160206135ac833981519152604482015260640161059c565b8051610b169060059060208401906129f8565b50610b2081611cae565b7f157d450c8fb1377294d9db75af1de2753efc52d8e5578551d70d2c7d9cd74df96005604051610b5091906132a4565b60405180910390a150565b6000546001600160a01b03163314610ba35760405162461bcd60e51b815260206004820181905260248201526000805160206135ac833981519152604482015260640161059c565b6040514790339082156108fc029083906000818181858888f19350505050158015610bd2573d6000803e3d6000fd5b5050565b6000546001600160a01b03163314610c1e5760405162461bcd60e51b815260206004820181905260248201526000805160206135ac833981519152604482015260640161059c565b60045460ff16610c705760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015260640161059c565b610c78611cc1565b565b60075460609067ffffffffffffffff811115610ca657634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610d0657816020015b6040805160c08101825260008082526020808301829052928201819052606082018190526080820181905260a08201528252600019909201910181610cc45790505b50905060005b600754811015610dee576006600060078381548110610d3b57634e487b7160e01b600052603260045260246000fd5b600091825260208083209091015483528281019390935260409182019020815160c08101835281546001600160a01b03168152600182015493810193909352600281015491830191909152600381015460608301526004015460ff8082161515608084015261010090910416151560a08201528251839083908110610dd057634e487b7160e01b600052603260045260246000fd5b60200260200101819052508080610de690613474565b915050610d0c565b5090565b60608151835114610e6b5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e67746860448201527f206d69736d617463680000000000000000000000000000000000000000000000606482015260840161059c565b6000835167ffffffffffffffff811115610e9557634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610ebe578160200160208202803683370190505b50905060005b8451811015610f6057610f25858281518110610ef057634e487b7160e01b600052603260045260246000fd5b6020026020010151858381518110610f1857634e487b7160e01b600052603260045260246000fd5b6020026020010151610522565b828281518110610f4557634e487b7160e01b600052603260045260246000fd5b6020908102919091010152610f5981613474565b9050610ec4565b509392505050565b60075482908110610faf5760405162461bcd60e51b81526020600482015260116024820152701a5d195b57db9bdb97d95e1a5cdd195b9d607a1b604482015260640161059c565b60045460ff1615610ff55760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161059c565b611000338484611d5d565b60408051338152602081018590529081018390527fd5a6b92e9ce7526b6436f01b4bf0d6647dfef511352212f6efab3e71cc4f67a39060600160405180910390a1505050565b6000546001600160a01b0316331461108e5760405162461bcd60e51b815260206004820181905260248201526000805160206135ac833981519152604482015260640161059c565b600754819081106110d55760405162461bcd60e51b81526020600482015260116024820152701a5d195b57db9bdb97d95e1a5cdd195b9d607a1b604482015260640161059c565b610bd23033846110e53087610522565b60405180602001604052806000815250611612565b6000546001600160a01b031633146111425760405162461bcd60e51b815260206004820181905260248201526000805160206135ac833981519152604482015260640161059c565b610c786000611f0d565b6000546001600160a01b031633146111945760405162461bcd60e51b815260206004820181905260248201526000805160206135ac833981519152604482015260640161059c565b60045460ff16156111da5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161059c565b610c78611f6a565b6000546001600160a01b0316331461122a5760405162461bcd60e51b815260206004820181905260248201526000805160206135ac833981519152604482015260640161059c565b60008181526006602052604090819020600401805461ff0019169055517f39f89f0510aa178a7f60657f01d3db17fd8598d75836cbe0d02fbacd2119662590610b509083815260200190565b610bd2338383611fe5565b6000546001600160a01b031633146112c95760405162461bcd60e51b815260206004820181905260248201526000805160206135ac833981519152604482015260640161059c565b600754829081106113105760405162461bcd60e51b81526020600482015260116024820152701a5d195b57db9bdb97d95e1a5cdd195b9d607a1b604482015260640161059c565b600083815260066020908152604091829020600181018054908690558351818152928301869052909290917f5bafb764641bca5020da0d7bf013dc61205051f17d7214c6dfd0b28909399191910160405180910390a15050505050565b6007818154811061137d57600080fd5b600091825260209091200154905081565b6000546001600160a01b031633146113d65760405162461bcd60e51b815260206004820181905260248201526000805160206135ac833981519152604482015260640161059c565b610bd26113eb6000546001600160a01b031690565b8383604051806020016040528060008152506120da565b6000546001600160a01b0316331461144a5760405162461bcd60e51b815260206004820181905260248201526000805160206135ac833981519152604482015260640161059c565b611465818484604051806020016040528060008152506120da565b505050565b600754829081106114b15760405162461bcd60e51b81526020600482015260116024820152701a5d195b57db9bdb97d95e1a5cdd195b9d607a1b604482015260640161059c565b600083815260066020908152604091829020825160c08101845281546001600160a01b0316808252600183015493820193909352600282015493810193909352600381015460608401526004015460ff8082161515608085015261010090910416151560a08301528491901561157a5780516001600160a01b0316331461157a5760405162461bcd60e51b815260206004820152601360248201527f73656e6465725f6e6f745f6578656375746f7200000000000000000000000000604482015260640161059c565b60045460ff16156115c05760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161059c565b6115cb868686611d5d565b604080516001600160a01b0388168152602081018790529081018590527fd5a6b92e9ce7526b6436f01b4bf0d6647dfef511352212f6efab3e71cc4f67a390606001610aab565b6001600160a01b03851633148061162e575061162e85336104af565b6116a05760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260448201527f20617070726f7665640000000000000000000000000000000000000000000000606482015260840161059c565b6107dc85858585856122cc565b6000546001600160a01b031633146116f55760405162461bcd60e51b815260206004820181905260248201526000805160206135ac833981519152604482015260640161059c565b6001600160a01b0381166117715760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161059c565b61177a81611f0d565b50565b60006001600160e01b031982167f4e2312e00000000000000000000000000000000000000000000000000000000014806105ca57506105ca8261246e565b6060816117fb57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611825578061180f81613474565b915061181e9050600a836133b1565b91506117ff565b60008167ffffffffffffffff81111561184e57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611878576020820181803683370190505b5090505b84156119095761188d6001836133c5565b915061189a600a8661348f565b6118a5906030613399565b60f81b8183815181106118c857634e487b7160e01b600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611902600a866133b1565b945061187c565b949350505050565b81518351146119735760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b606482015260840161059c565b6001600160a01b0384166119d75760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b606482015260840161059c565b336119e6818787878787612509565b60005b8451811015611b2e576000858281518110611a1457634e487b7160e01b600052603260045260246000fd5b602002602001015190506000858381518110611a4057634e487b7160e01b600052603260045260246000fd5b60209081029190910181015160008481526001835260408082206001600160a01b038e168352909352919091205490915081811015611ad45760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201526939103a3930b739b332b960b11b606482015260840161059c565b60008381526001602090815260408083206001600160a01b038e8116855292528083208585039055908b16825281208054849290611b13908490613399565b9250508190555050505080611b2790613474565b90506119e9565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051611b7e929190613263565b60405180910390a4611b94818787878787612666565b505050505050565b6001600160a01b038416611bfc5760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b606482015260840161059c565b33611c1c81600087611c0d8861281b565b611c168861281b565b87612509565b60008481526001602090815260408083206001600160a01b038916845290915281208054859290611c4e908490613399565b909155505060408051858152602081018590526001600160a01b0380881692600092918516917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46107dc81600087878787612874565b8051610bd29060039060208401906129f8565b60045460ff16611d135760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015260640161059c565b6004805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6001600160a01b038316611dd95760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161059c565b33611e0881856000611dea8761281b565b611df38761281b565b60405180602001604052806000815250612509565b60008381526001602090815260408083206001600160a01b038816845290915290205482811015611ea05760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c60448201527f616e636500000000000000000000000000000000000000000000000000000000606482015260840161059c565b60008481526001602090815260408083206001600160a01b03898116808652918452828520888703905582518981529384018890529092908616917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a45050505050565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60045460ff1615611fb05760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161059c565b6004805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611d403390565b816001600160a01b0316836001600160a01b0316141561206d5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c2073746174757360448201527f20666f722073656c660000000000000000000000000000000000000000000000606482015260840161059c565b6001600160a01b03838116600081815260026020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b03841661213a5760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b606482015260840161059c565b815183511461219c5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b606482015260840161059c565b336121ac81600087878787612509565b60005b8451811015612264578381815181106121d857634e487b7160e01b600052603260045260246000fd5b60200260200101516001600087848151811061220457634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b03168152602001908152602001600020600082825461224c9190613399565b9091555081905061225c81613474565b9150506121af565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516122b5929190613263565b60405180910390a46107dc81600087878787612666565b6001600160a01b0384166123305760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b606482015260840161059c565b33612340818787611c0d8861281b565b60008481526001602090815260408083206001600160a01b038a168452909152902054838110156123c65760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201526939103a3930b739b332b960b11b606482015260840161059c565b60008581526001602090815260408083206001600160a01b038b8116855292528083208785039055908816825281208054869290612405908490613399565b909155505060408051868152602081018690526001600160a01b03808916928a821692918616917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4612465828888888888612874565b50505050505050565b60006001600160e01b031982167fd9b67a260000000000000000000000000000000000000000000000000000000014806124d157506001600160e01b031982167f0e89341c00000000000000000000000000000000000000000000000000000000145b806105ca57507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b03198316146105ca565b61251786868686868661297f565b60008360008151811061253a57634e487b7160e01b600052603260045260246000fd5b602002602001015190505b835181101561246557600081815260066020908152604091829020825160c08101845281546001600160a01b0316808252600183015493820193909352600282015493810193909352600381015460608401526004015460ff8082161515608085015261010090910416151560a0830152156126535780516040517fd2346419000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b039091169063d234641990602401602060405180830381600087803b15801561261957600080fd5b505af115801561262d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126519190612f08565b505b508061265e81613474565b915050612545565b6001600160a01b0384163b15611b945760405163bc197c8160e01b81526001600160a01b0385169063bc197c81906126aa908990899088908890889060040161311f565b602060405180830381600087803b1580156126c457600080fd5b505af19250505080156126f4575060408051601f3d908101601f191682019092526126f191810190612f40565b60015b6127aa576127006134e5565b806308c379a0141561273a57506127156134fd565b80612720575061273c565b8060405162461bcd60e51b815260040161059c9190613291565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e204552433131353560448201527f526563656976657220696d706c656d656e746572000000000000000000000000606482015260840161059c565b6001600160e01b0319811663bc197c8160e01b146124655760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a656374656044820152676420746f6b656e7360c01b606482015260840161059c565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061286357634e487b7160e01b600052603260045260246000fd5b602090810291909101015292915050565b6001600160a01b0384163b15611b945760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e61906128b8908990899088908890889060040161317d565b602060405180830381600087803b1580156128d257600080fd5b505af1925050508015612902575060408051601f3d908101601f191682019092526128ff91810190612f40565b60015b61290e576127006134e5565b6001600160e01b0319811663f23a6e6160e01b146124655760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a656374656044820152676420746f6b656e7360c01b606482015260840161059c565b60045460ff1615611b945760405162461bcd60e51b815260206004820152602c60248201527f455243313135355061757361626c653a20746f6b656e207472616e736665722060448201527f7768696c65207061757365640000000000000000000000000000000000000000606482015260840161059c565b828054612a049061340c565b90600052602060002090601f016020900481019282612a265760008555612a6c565b82601f10612a3f57805160ff1916838001178555612a6c565b82800160010185558215612a6c579182015b82811115612a6c578251825591602001919060010190612a51565b50610dee9291505b80821115610dee5760008155600101612a74565b600067ffffffffffffffff831115612aa257612aa26134cf565b604051612ab9601f8501601f191660200182613447565b809150838152848484011115612ace57600080fd5b83836020830137600060208583010152509392505050565b80356001600160a01b0381168114612afd57600080fd5b919050565b600082601f830112612b12578081fd5b81356020612b1f82613375565b604051612b2c8282613447565b8381528281019150858301600585901b87018401881015612b4b578586fd5b855b85811015612b6957813584529284019290840190600101612b4d565b5090979650505050505050565b600082601f830112612b86578081fd5b612b9583833560208501612a88565b9392505050565b600060208284031215612bad578081fd5b612b9582612ae6565b60008060408385031215612bc8578081fd5b612bd183612ae6565b9150612bdf60208401612ae6565b90509250929050565b600080600080600060a08688031215612bff578081fd5b612c0886612ae6565b9450612c1660208701612ae6565b9350604086013567ffffffffffffffff80821115612c32578283fd5b612c3e89838a01612b02565b94506060880135915080821115612c53578283fd5b612c5f89838a01612b02565b93506080880135915080821115612c74578283fd5b50612c8188828901612b76565b9150509295509295909350565b600080600080600060a08688031215612ca5578081fd5b612cae86612ae6565b9450612cbc60208701612ae6565b93506040860135925060608601359150608086013567ffffffffffffffff811115612ce5578182fd5b612c8188828901612b76565b60008060408385031215612d03578182fd5b612d0c83612ae6565b91506020830135612d1c81613587565b809150509250929050565b60008060408385031215612d39578182fd5b612d4283612ae6565b946020939093013593505050565b600080600060608486031215612d64578283fd5b612d6d84612ae6565b95602085013595506040909401359392505050565b60008060408385031215612d94578182fd5b823567ffffffffffffffff80821115612dab578384fd5b818501915085601f830112612dbe578384fd5b81356020612dcb82613375565b604051612dd88282613447565b8381528281019150858301600585901b870184018b1015612df7578889fd5b8896505b84871015612e2057612e0c81612ae6565b835260019690960195918301918301612dfb565b5096505086013592505080821115612e36578283fd5b50612e4385828601612b02565b9150509250929050565b60008060408385031215612e5f578182fd5b823567ffffffffffffffff80821115612e76578384fd5b612e8286838701612b02565b93506020850135915080821115612e36578283fd5b600080600060608486031215612eab578081fd5b833567ffffffffffffffff80821115612ec2578283fd5b612ece87838801612b02565b94506020860135915080821115612ee3578283fd5b50612ef086828701612b02565b925050612eff60408501612ae6565b90509250925092565b600060208284031215612f19578081fd5b8151612b9581613587565b600060208284031215612f35578081fd5b8135612b9581613595565b600060208284031215612f51578081fd5b8151612b9581613595565b600060208284031215612f6d578081fd5b813567ffffffffffffffff811115612f83578182fd5b8201601f81018413612f93578182fd5b61190984823560208401612a88565b600060208284031215612fb3578081fd5b5035919050565b60008060408385031215612fcc578182fd5b50508035926020909101359150565b600080600080600060a08688031215612ff2578283fd5b8535945060208601359350604086013561300b81613587565b9250606086013561301b81613587565b9150608086013561302b81613587565b809150509295509295909350565b6000815180845260208085019450808401835b838110156130685781518752958201959082019060010161304c565b509495945050505050565b6000815180845261308b8160208601602086016133dc565b601f01601f19169290920160200192915050565b60008084546130ad8161340c565b600182811680156130c557600181146130d657613102565b60ff19841687528287019450613102565b8886526020808720875b858110156130f95781548a8201529084019082016130e0565b50505082870194505b5050505083516131168183602088016133dc565b01949350505050565b60006001600160a01b03808816835280871660208401525060a0604083015261314b60a0830186613039565b828103606084015261315d8186613039565b905082810360808401526131718185613073565b98975050505050505050565b60006001600160a01b03808816835280871660208401525084604083015283606083015260a060808301526131b560a0830184613073565b979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613244576132318385516001600160a01b03815116825260208101516020830152604081015160408301526060810151606083015260808101511515608083015260a0810151151560a08301525050565b9284019260c092909201916001016131dc565b50909695505050505050565b602081526000612b956020830184613039565b6040815260006132766040830185613039565b82810360208401526132888185613039565b95945050505050565b602081526000612b956020830184613073565b600060208083528184546132b78161340c565b808487015260406001808416600081146132d857600181146132ec57613317565b60ff19851689840152606089019550613317565b898852868820885b8581101561330f5781548b82018601529083019088016132f4565b8a0184019650505b509398975050505050505050565b60c081016105ca82846001600160a01b03815116825260208101516020830152604081015160408301526060810151606083015260808101511515608083015260a0810151151560a08301525050565b600067ffffffffffffffff82111561338f5761338f6134cf565b5060051b60200190565b600082198211156133ac576133ac6134a3565b500190565b6000826133c0576133c06134b9565b500490565b6000828210156133d7576133d76134a3565b500390565b60005b838110156133f75781810151838201526020016133df565b83811115613406576000848401525b50505050565b600181811c9082168061342057607f821691505b6020821081141561344157634e487b7160e01b600052602260045260246000fd5b50919050565b601f8201601f1916810167ffffffffffffffff8111828210171561346d5761346d6134cf565b6040525050565b6000600019821415613488576134886134a3565b5060010190565b60008261349e5761349e6134b9565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b600060033d11156134fa57600481823e5160e01c5b90565b600060443d101561350b5790565b6040516003193d81016004833e81513d67ffffffffffffffff816024840111818411171561353b57505050505090565b82850191508151818111156135535750505050505090565b843d870101602082850101111561356d5750505050505090565b61357c60208286010187613447565b509095945050505050565b801515811461177a57600080fd5b6001600160e01b03198116811461177a57600080fdfe4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a164736f6c6343000804000a0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003168747470733a2f2f6170692e7a6f6d6269656672656e732e636f6d2f6d657461646174612f74726164696e67706f73742f000000000000000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101e45760003560e01c806365dd80a01161010f578063bc197c81116100a2578063e985e9c511610071578063e985e9c5146104a1578063f23a6e61146104dd578063f242432a146104fc578063f2fde38b1461050f57600080fd5b8063bc197c8114610430578063d351cfdc14610468578063d5a3deca1461047b578063dcca20431461048e57600080fd5b806392184bfb116100de57806392184bfb146103e4578063a22cb465146103f7578063b01d1c911461040a578063b3dc00fe1461041d57600080fd5b806365dd80a0146103a6578063715018a6146103b95780638456cb59146103c15780638da5cb5b146103c957600080fd5b80633ccfd60b1161018757806348d9b4021161015657806348d9b402146102da5780634e1273f4146103685780635c975abb146103885780635f09c7821461039357600080fd5b80633ccfd60b146102ad5780633f4ba83a146102b5578063410d59cc146102bd5780634362bca5146102d257600080fd5b80632eb2c2d6116101c35780632eb2c2d6146102525780633129e77314610267578063366af9ef1461028757806339f7e37f1461029a57600080fd5b8062fdd58e146101e957806301ffc9a71461020f5780630e89341c14610232575b600080fd5b6101fc6101f7366004612d27565b610522565b6040519081526020015b60405180910390f35b61022261021d366004612f24565b6105d0565b6040519015158152602001610206565b610245610240366004612fa2565b6105db565b6040516102069190613291565b610265610260366004612be8565b610741565b005b61027a610275366004612fa2565b6107e3565b6040516102069190613325565b610265610295366004612fdb565b610933565b6102656102a8366004612f5c565b610abb565b610265610b5b565b610265610bd6565b6102c5610c7a565b60405161020691906131c0565b6007546101fc565b61032d6102e8366004612fa2565b600660205260009081526040902080546001820154600283015460038401546004909401546001600160a01b0390931693919290919060ff8082169161010090041686565b604080516001600160a01b039097168752602087019590955293850192909252606084015215156080830152151560a082015260c001610206565b61037b610376366004612d82565b610df2565b6040516102069190613250565b60045460ff16610222565b6102656103a1366004612fba565b610f68565b6102656103b4366004612fa2565b611046565b6102656110fa565b61026561114c565b6000546040516001600160a01b039091168152602001610206565b6102656103f2366004612fa2565b6111e2565b610265610405366004612cf1565b611276565b610265610418366004612fba565b611281565b6101fc61042b366004612fa2565b61136d565b61044f61043e366004612be8565b63bc197c8160e01b95945050505050565b6040516001600160e01b03199091168152602001610206565b610265610476366004612e4d565b61138e565b610265610489366004612e97565b611402565b61026561049c366004612d50565b61146a565b6102226104af366004612bb6565b6001600160a01b03918216600090815260026020908152604080832093909416825291909152205460ff1690565b61044f6104eb366004612c8e565b63f23a6e6160e01b95945050505050565b61026561050a366004612c8e565b611612565b61026561051d366004612b9c565b6116ad565b60006001600160a01b0383166105a55760405162461bcd60e51b815260206004820152602b60248201527f455243313135353a2062616c616e636520717565727920666f7220746865207a60448201527f65726f206164647265737300000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5060008181526001602090815260408083206001600160a01b03861684529091529020545b92915050565b60006105ca8261177d565b600081815260066020526040902060040154606090610100900460ff1661066a5760405162461bcd60e51b815260206004820152602360248201527f5552492072657175657374656420666f7220696e76616c6964206974656d207460448201527f7970650000000000000000000000000000000000000000000000000000000000606482015260840161059c565b6000600580546106799061340c565b905011610710576005805461068d9061340c565b80601f01602080910402602001604051908101604052809291908181526020018280546106b99061340c565b80156107065780601f106106db57610100808354040283529160200191610706565b820191906000526020600020905b8154815290600101906020018083116106e957829003601f168201915b50505050506105ca565b600561071b836117bb565b60405160200161072c92919061309f565b60405160208183030381529060405292915050565b6001600160a01b03851633148061075d575061075d85336104af565b6107cf5760405162461bcd60e51b815260206004820152603260248201527f455243313135353a207472616e736665722063616c6c6572206973206e6f742060448201527f6f776e6572206e6f7220617070726f7665640000000000000000000000000000606482015260840161059c565b6107dc8585858585611911565b5050505050565b6040805160c081018252600080825260208201819052918101829052606081018290526080810182905260a08101919091526007548290811061085c5760405162461bcd60e51b81526020600482015260116024820152701a5d195b57db9bdb97d95e1a5cdd195b9d607a1b604482015260640161059c565b6000838152600660205260409020600401548390610100900460ff166108c45760405162461bcd60e51b815260206004820152600d60248201527f6974656d5f64697361626c656400000000000000000000000000000000000000604482015260640161059c565b505050600090815260066020908152604091829020825160c08101845281546001600160a01b031681526001820154928101929092526002810154928201929092526003820154606082015260049091015460ff8082161515608084015261010090910416151560a082015290565b6000546001600160a01b0316331461097b5760405162461bcd60e51b815260206004820181905260248201526000805160206135ac833981519152604482015260640161059c565b6007805460018082019092557fa66cc928b5edb82af9bd49922954155ab7b0942694bea4ce44661d9a8736c68881018190556040805160c081018252600080825260208281018b8152838501838152606085018c81528b1515608087019081528b151560a08801908152898752600690955296909420945185546001600160a01b039190911673ffffffffffffffffffffffffffffffffffffffff1990911617855590519684019690965594516002830155516003820155905160049091018054935115156101000261ff00199215159290921661ffff1990941693909317179091558115610a7f57610a7f30828760405180602001604052806000815250611b9c565b6040518181527f186760a37e06b130959978c68b5c592841caf4f64de1dc960b2c54cf454ca9dd906020015b60405180910390a1505050505050565b6000546001600160a01b03163314610b035760405162461bcd60e51b815260206004820181905260248201526000805160206135ac833981519152604482015260640161059c565b8051610b169060059060208401906129f8565b50610b2081611cae565b7f157d450c8fb1377294d9db75af1de2753efc52d8e5578551d70d2c7d9cd74df96005604051610b5091906132a4565b60405180910390a150565b6000546001600160a01b03163314610ba35760405162461bcd60e51b815260206004820181905260248201526000805160206135ac833981519152604482015260640161059c565b6040514790339082156108fc029083906000818181858888f19350505050158015610bd2573d6000803e3d6000fd5b5050565b6000546001600160a01b03163314610c1e5760405162461bcd60e51b815260206004820181905260248201526000805160206135ac833981519152604482015260640161059c565b60045460ff16610c705760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015260640161059c565b610c78611cc1565b565b60075460609067ffffffffffffffff811115610ca657634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610d0657816020015b6040805160c08101825260008082526020808301829052928201819052606082018190526080820181905260a08201528252600019909201910181610cc45790505b50905060005b600754811015610dee576006600060078381548110610d3b57634e487b7160e01b600052603260045260246000fd5b600091825260208083209091015483528281019390935260409182019020815160c08101835281546001600160a01b03168152600182015493810193909352600281015491830191909152600381015460608301526004015460ff8082161515608084015261010090910416151560a08201528251839083908110610dd057634e487b7160e01b600052603260045260246000fd5b60200260200101819052508080610de690613474565b915050610d0c565b5090565b60608151835114610e6b5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e67746860448201527f206d69736d617463680000000000000000000000000000000000000000000000606482015260840161059c565b6000835167ffffffffffffffff811115610e9557634e487b7160e01b600052604160045260246000fd5b604051908082528060200260200182016040528015610ebe578160200160208202803683370190505b50905060005b8451811015610f6057610f25858281518110610ef057634e487b7160e01b600052603260045260246000fd5b6020026020010151858381518110610f1857634e487b7160e01b600052603260045260246000fd5b6020026020010151610522565b828281518110610f4557634e487b7160e01b600052603260045260246000fd5b6020908102919091010152610f5981613474565b9050610ec4565b509392505050565b60075482908110610faf5760405162461bcd60e51b81526020600482015260116024820152701a5d195b57db9bdb97d95e1a5cdd195b9d607a1b604482015260640161059c565b60045460ff1615610ff55760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161059c565b611000338484611d5d565b60408051338152602081018590529081018390527fd5a6b92e9ce7526b6436f01b4bf0d6647dfef511352212f6efab3e71cc4f67a39060600160405180910390a1505050565b6000546001600160a01b0316331461108e5760405162461bcd60e51b815260206004820181905260248201526000805160206135ac833981519152604482015260640161059c565b600754819081106110d55760405162461bcd60e51b81526020600482015260116024820152701a5d195b57db9bdb97d95e1a5cdd195b9d607a1b604482015260640161059c565b610bd23033846110e53087610522565b60405180602001604052806000815250611612565b6000546001600160a01b031633146111425760405162461bcd60e51b815260206004820181905260248201526000805160206135ac833981519152604482015260640161059c565b610c786000611f0d565b6000546001600160a01b031633146111945760405162461bcd60e51b815260206004820181905260248201526000805160206135ac833981519152604482015260640161059c565b60045460ff16156111da5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161059c565b610c78611f6a565b6000546001600160a01b0316331461122a5760405162461bcd60e51b815260206004820181905260248201526000805160206135ac833981519152604482015260640161059c565b60008181526006602052604090819020600401805461ff0019169055517f39f89f0510aa178a7f60657f01d3db17fd8598d75836cbe0d02fbacd2119662590610b509083815260200190565b610bd2338383611fe5565b6000546001600160a01b031633146112c95760405162461bcd60e51b815260206004820181905260248201526000805160206135ac833981519152604482015260640161059c565b600754829081106113105760405162461bcd60e51b81526020600482015260116024820152701a5d195b57db9bdb97d95e1a5cdd195b9d607a1b604482015260640161059c565b600083815260066020908152604091829020600181018054908690558351818152928301869052909290917f5bafb764641bca5020da0d7bf013dc61205051f17d7214c6dfd0b28909399191910160405180910390a15050505050565b6007818154811061137d57600080fd5b600091825260209091200154905081565b6000546001600160a01b031633146113d65760405162461bcd60e51b815260206004820181905260248201526000805160206135ac833981519152604482015260640161059c565b610bd26113eb6000546001600160a01b031690565b8383604051806020016040528060008152506120da565b6000546001600160a01b0316331461144a5760405162461bcd60e51b815260206004820181905260248201526000805160206135ac833981519152604482015260640161059c565b611465818484604051806020016040528060008152506120da565b505050565b600754829081106114b15760405162461bcd60e51b81526020600482015260116024820152701a5d195b57db9bdb97d95e1a5cdd195b9d607a1b604482015260640161059c565b600083815260066020908152604091829020825160c08101845281546001600160a01b0316808252600183015493820193909352600282015493810193909352600381015460608401526004015460ff8082161515608085015261010090910416151560a08301528491901561157a5780516001600160a01b0316331461157a5760405162461bcd60e51b815260206004820152601360248201527f73656e6465725f6e6f745f6578656375746f7200000000000000000000000000604482015260640161059c565b60045460ff16156115c05760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161059c565b6115cb868686611d5d565b604080516001600160a01b0388168152602081018790529081018590527fd5a6b92e9ce7526b6436f01b4bf0d6647dfef511352212f6efab3e71cc4f67a390606001610aab565b6001600160a01b03851633148061162e575061162e85336104af565b6116a05760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2063616c6c6572206973206e6f74206f776e6572206e6f7260448201527f20617070726f7665640000000000000000000000000000000000000000000000606482015260840161059c565b6107dc85858585856122cc565b6000546001600160a01b031633146116f55760405162461bcd60e51b815260206004820181905260248201526000805160206135ac833981519152604482015260640161059c565b6001600160a01b0381166117715760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f6464726573730000000000000000000000000000000000000000000000000000606482015260840161059c565b61177a81611f0d565b50565b60006001600160e01b031982167f4e2312e00000000000000000000000000000000000000000000000000000000014806105ca57506105ca8261246e565b6060816117fb57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b8115611825578061180f81613474565b915061181e9050600a836133b1565b91506117ff565b60008167ffffffffffffffff81111561184e57634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611878576020820181803683370190505b5090505b84156119095761188d6001836133c5565b915061189a600a8661348f565b6118a5906030613399565b60f81b8183815181106118c857634e487b7160e01b600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350611902600a866133b1565b945061187c565b949350505050565b81518351146119735760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b606482015260840161059c565b6001600160a01b0384166119d75760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b606482015260840161059c565b336119e6818787878787612509565b60005b8451811015611b2e576000858281518110611a1457634e487b7160e01b600052603260045260246000fd5b602002602001015190506000858381518110611a4057634e487b7160e01b600052603260045260246000fd5b60209081029190910181015160008481526001835260408082206001600160a01b038e168352909352919091205490915081811015611ad45760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201526939103a3930b739b332b960b11b606482015260840161059c565b60008381526001602090815260408083206001600160a01b038e8116855292528083208585039055908b16825281208054849290611b13908490613399565b9250508190555050505080611b2790613474565b90506119e9565b50846001600160a01b0316866001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8787604051611b7e929190613263565b60405180910390a4611b94818787878787612666565b505050505050565b6001600160a01b038416611bfc5760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b606482015260840161059c565b33611c1c81600087611c0d8861281b565b611c168861281b565b87612509565b60008481526001602090815260408083206001600160a01b038916845290915281208054859290611c4e908490613399565b909155505060408051858152602081018590526001600160a01b0380881692600092918516917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a46107dc81600087878787612874565b8051610bd29060039060208401906129f8565b60045460ff16611d135760405162461bcd60e51b815260206004820152601460248201527f5061757361626c653a206e6f7420706175736564000000000000000000000000604482015260640161059c565b6004805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6001600160a01b038316611dd95760405162461bcd60e51b815260206004820152602360248201527f455243313135353a206275726e2066726f6d20746865207a65726f206164647260448201527f6573730000000000000000000000000000000000000000000000000000000000606482015260840161059c565b33611e0881856000611dea8761281b565b611df38761281b565b60405180602001604052806000815250612509565b60008381526001602090815260408083206001600160a01b038816845290915290205482811015611ea05760405162461bcd60e51b8152602060048201526024808201527f455243313135353a206275726e20616d6f756e7420657863656564732062616c60448201527f616e636500000000000000000000000000000000000000000000000000000000606482015260840161059c565b60008481526001602090815260408083206001600160a01b03898116808652918452828520888703905582518981529384018890529092908616917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a45050505050565b600080546001600160a01b0383811673ffffffffffffffffffffffffffffffffffffffff19831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60045460ff1615611fb05760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640161059c565b6004805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611d403390565b816001600160a01b0316836001600160a01b0316141561206d5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c2073746174757360448201527f20666f722073656c660000000000000000000000000000000000000000000000606482015260840161059c565b6001600160a01b03838116600081815260026020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b6001600160a01b03841661213a5760405162461bcd60e51b815260206004820152602160248201527f455243313135353a206d696e7420746f20746865207a65726f206164647265736044820152607360f81b606482015260840161059c565b815183511461219c5760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b606482015260840161059c565b336121ac81600087878787612509565b60005b8451811015612264578381815181106121d857634e487b7160e01b600052603260045260246000fd5b60200260200101516001600087848151811061220457634e487b7160e01b600052603260045260246000fd5b602002602001015181526020019081526020016000206000886001600160a01b03166001600160a01b03168152602001908152602001600020600082825461224c9190613399565b9091555081905061225c81613474565b9150506121af565b50846001600160a01b031660006001600160a01b0316826001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb87876040516122b5929190613263565b60405180910390a46107dc81600087878787612666565b6001600160a01b0384166123305760405162461bcd60e51b815260206004820152602560248201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604482015264647265737360d81b606482015260840161059c565b33612340818787611c0d8861281b565b60008481526001602090815260408083206001600160a01b038a168452909152902054838110156123c65760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60448201526939103a3930b739b332b960b11b606482015260840161059c565b60008581526001602090815260408083206001600160a01b038b8116855292528083208785039055908816825281208054869290612405908490613399565b909155505060408051868152602081018690526001600160a01b03808916928a821692918616917fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f62910160405180910390a4612465828888888888612874565b50505050505050565b60006001600160e01b031982167fd9b67a260000000000000000000000000000000000000000000000000000000014806124d157506001600160e01b031982167f0e89341c00000000000000000000000000000000000000000000000000000000145b806105ca57507f01ffc9a7000000000000000000000000000000000000000000000000000000006001600160e01b03198316146105ca565b61251786868686868661297f565b60008360008151811061253a57634e487b7160e01b600052603260045260246000fd5b602002602001015190505b835181101561246557600081815260066020908152604091829020825160c08101845281546001600160a01b0316808252600183015493820193909352600282015493810193909352600381015460608401526004015460ff8082161515608085015261010090910416151560a0830152156126535780516040517fd2346419000000000000000000000000000000000000000000000000000000008152600481018490526001600160a01b039091169063d234641990602401602060405180830381600087803b15801561261957600080fd5b505af115801561262d573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906126519190612f08565b505b508061265e81613474565b915050612545565b6001600160a01b0384163b15611b945760405163bc197c8160e01b81526001600160a01b0385169063bc197c81906126aa908990899088908890889060040161311f565b602060405180830381600087803b1580156126c457600080fd5b505af19250505080156126f4575060408051601f3d908101601f191682019092526126f191810190612f40565b60015b6127aa576127006134e5565b806308c379a0141561273a57506127156134fd565b80612720575061273c565b8060405162461bcd60e51b815260040161059c9190613291565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e204552433131353560448201527f526563656976657220696d706c656d656e746572000000000000000000000000606482015260840161059c565b6001600160e01b0319811663bc197c8160e01b146124655760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a656374656044820152676420746f6b656e7360c01b606482015260840161059c565b6040805160018082528183019092526060916000919060208083019080368337019050509050828160008151811061286357634e487b7160e01b600052603260045260246000fd5b602090810291909101015292915050565b6001600160a01b0384163b15611b945760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e61906128b8908990899088908890889060040161317d565b602060405180830381600087803b1580156128d257600080fd5b505af1925050508015612902575060408051601f3d908101601f191682019092526128ff91810190612f40565b60015b61290e576127006134e5565b6001600160e01b0319811663f23a6e6160e01b146124655760405162461bcd60e51b815260206004820152602860248201527f455243313135353a204552433131353552656365697665722072656a656374656044820152676420746f6b656e7360c01b606482015260840161059c565b60045460ff1615611b945760405162461bcd60e51b815260206004820152602c60248201527f455243313135355061757361626c653a20746f6b656e207472616e736665722060448201527f7768696c65207061757365640000000000000000000000000000000000000000606482015260840161059c565b828054612a049061340c565b90600052602060002090601f016020900481019282612a265760008555612a6c565b82601f10612a3f57805160ff1916838001178555612a6c565b82800160010185558215612a6c579182015b82811115612a6c578251825591602001919060010190612a51565b50610dee9291505b80821115610dee5760008155600101612a74565b600067ffffffffffffffff831115612aa257612aa26134cf565b604051612ab9601f8501601f191660200182613447565b809150838152848484011115612ace57600080fd5b83836020830137600060208583010152509392505050565b80356001600160a01b0381168114612afd57600080fd5b919050565b600082601f830112612b12578081fd5b81356020612b1f82613375565b604051612b2c8282613447565b8381528281019150858301600585901b87018401881015612b4b578586fd5b855b85811015612b6957813584529284019290840190600101612b4d565b5090979650505050505050565b600082601f830112612b86578081fd5b612b9583833560208501612a88565b9392505050565b600060208284031215612bad578081fd5b612b9582612ae6565b60008060408385031215612bc8578081fd5b612bd183612ae6565b9150612bdf60208401612ae6565b90509250929050565b600080600080600060a08688031215612bff578081fd5b612c0886612ae6565b9450612c1660208701612ae6565b9350604086013567ffffffffffffffff80821115612c32578283fd5b612c3e89838a01612b02565b94506060880135915080821115612c53578283fd5b612c5f89838a01612b02565b93506080880135915080821115612c74578283fd5b50612c8188828901612b76565b9150509295509295909350565b600080600080600060a08688031215612ca5578081fd5b612cae86612ae6565b9450612cbc60208701612ae6565b93506040860135925060608601359150608086013567ffffffffffffffff811115612ce5578182fd5b612c8188828901612b76565b60008060408385031215612d03578182fd5b612d0c83612ae6565b91506020830135612d1c81613587565b809150509250929050565b60008060408385031215612d39578182fd5b612d4283612ae6565b946020939093013593505050565b600080600060608486031215612d64578283fd5b612d6d84612ae6565b95602085013595506040909401359392505050565b60008060408385031215612d94578182fd5b823567ffffffffffffffff80821115612dab578384fd5b818501915085601f830112612dbe578384fd5b81356020612dcb82613375565b604051612dd88282613447565b8381528281019150858301600585901b870184018b1015612df7578889fd5b8896505b84871015612e2057612e0c81612ae6565b835260019690960195918301918301612dfb565b5096505086013592505080821115612e36578283fd5b50612e4385828601612b02565b9150509250929050565b60008060408385031215612e5f578182fd5b823567ffffffffffffffff80821115612e76578384fd5b612e8286838701612b02565b93506020850135915080821115612e36578283fd5b600080600060608486031215612eab578081fd5b833567ffffffffffffffff80821115612ec2578283fd5b612ece87838801612b02565b94506020860135915080821115612ee3578283fd5b50612ef086828701612b02565b925050612eff60408501612ae6565b90509250925092565b600060208284031215612f19578081fd5b8151612b9581613587565b600060208284031215612f35578081fd5b8135612b9581613595565b600060208284031215612f51578081fd5b8151612b9581613595565b600060208284031215612f6d578081fd5b813567ffffffffffffffff811115612f83578182fd5b8201601f81018413612f93578182fd5b61190984823560208401612a88565b600060208284031215612fb3578081fd5b5035919050565b60008060408385031215612fcc578182fd5b50508035926020909101359150565b600080600080600060a08688031215612ff2578283fd5b8535945060208601359350604086013561300b81613587565b9250606086013561301b81613587565b9150608086013561302b81613587565b809150509295509295909350565b6000815180845260208085019450808401835b838110156130685781518752958201959082019060010161304c565b509495945050505050565b6000815180845261308b8160208601602086016133dc565b601f01601f19169290920160200192915050565b60008084546130ad8161340c565b600182811680156130c557600181146130d657613102565b60ff19841687528287019450613102565b8886526020808720875b858110156130f95781548a8201529084019082016130e0565b50505082870194505b5050505083516131168183602088016133dc565b01949350505050565b60006001600160a01b03808816835280871660208401525060a0604083015261314b60a0830186613039565b828103606084015261315d8186613039565b905082810360808401526131718185613073565b98975050505050505050565b60006001600160a01b03808816835280871660208401525084604083015283606083015260a060808301526131b560a0830184613073565b979650505050505050565b6020808252825182820181905260009190848201906040850190845b81811015613244576132318385516001600160a01b03815116825260208101516020830152604081015160408301526060810151606083015260808101511515608083015260a0810151151560a08301525050565b9284019260c092909201916001016131dc565b50909695505050505050565b602081526000612b956020830184613039565b6040815260006132766040830185613039565b82810360208401526132888185613039565b95945050505050565b602081526000612b956020830184613073565b600060208083528184546132b78161340c565b808487015260406001808416600081146132d857600181146132ec57613317565b60ff19851689840152606089019550613317565b898852868820885b8581101561330f5781548b82018601529083019088016132f4565b8a0184019650505b509398975050505050505050565b60c081016105ca82846001600160a01b03815116825260208101516020830152604081015160408301526060810151606083015260808101511515608083015260a0810151151560a08301525050565b600067ffffffffffffffff82111561338f5761338f6134cf565b5060051b60200190565b600082198211156133ac576133ac6134a3565b500190565b6000826133c0576133c06134b9565b500490565b6000828210156133d7576133d76134a3565b500390565b60005b838110156133f75781810151838201526020016133df565b83811115613406576000848401525b50505050565b600181811c9082168061342057607f821691505b6020821081141561344157634e487b7160e01b600052602260045260246000fd5b50919050565b601f8201601f1916810167ffffffffffffffff8111828210171561346d5761346d6134cf565b6040525050565b6000600019821415613488576134886134a3565b5060010190565b60008261349e5761349e6134b9565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b600060033d11156134fa57600481823e5160e01c5b90565b600060443d101561350b5790565b6040516003193d81016004833e81513d67ffffffffffffffff816024840111818411171561353b57505050505090565b82850191508151818111156135535750505050505090565b843d870101602082850101111561356d5750505050505090565b61357c60208286010187613447565b509095945050505050565b801515811461177a57600080fd5b6001600160e01b03198116811461177a57600080fdfe4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572a164736f6c6343000804000a

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

0000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000003168747470733a2f2f6170692e7a6f6d6269656672656e732e636f6d2f6d657461646174612f74726164696e67706f73742f000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _baseURI (string): https://api.zombiefrens.com/metadata/tradingpost/

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000031
Arg [2] : 68747470733a2f2f6170692e7a6f6d6269656672656e732e636f6d2f6d657461
Arg [3] : 646174612f74726164696e67706f73742f000000000000000000000000000000


Deployed Bytecode Sourcemap

557:5683:27:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2170:228:2;;;;;;:::i;:::-;;:::i;:::-;;;26673:25:28;;;26661:2;26646:18;2170:228:2;;;;;;;;5280:177:27;;;;;;:::i;:::-;;:::i;:::-;;;16164:14:28;;16157:22;16139:41;;16127:2;16112:18;5280:177:27;16094:92:28;4174:407:27;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;4045:430:2:-;;;;;;:::i;:::-;;:::i;:::-;;2709:201:27;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1324:604::-;;;;;;:::i;:::-;;:::i;3701:165::-;;;;;;:::i;:::-;;:::i;4587:139::-;;;:::i;6156:82::-;;;:::i;2916:325::-;;;:::i;:::-;;;;;;;:::i;2599:104::-;2682:7;:14;2599:104;;733:76;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;733:76:27;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;14215:55:28;;;14197:74;;14302:2;14287:18;;14280:34;;;;14330:18;;;14323:34;;;;14388:2;14373:18;;14366:34;14444:14;14437:22;14431:3;14416:19;;14409:51;14504:14;14497:22;14491:3;14476:19;;14469:51;14184:3;14169:19;733:76:27;14151:375:28;2555:508:2;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1098:84:1:-;1168:7;;;;1098:84;;3247:206:27;;;;;;:::i;:::-;;:::i;1934:188::-;;;;;;:::i;:::-;;:::i;1668:101:0:-;;;:::i;6069:81:27:-;;;:::i;1036:85:0:-;1082:7;1108:6;1036:85;;-1:-1:-1;;;;;1108:6:0;;;12022:74:28;;12010:2;11995:18;1036:85:0;11977:125:28;2446:147:27;;;;;;:::i;:::-;;:::i;3131:153:2:-;;;;;;:::i;:::-;;:::i;2128:312:27:-;;;;;;:::i;:::-;;:::i;816:24::-;;;;;;:::i;:::-;;:::i;477:247:7:-;;;;;;:::i;:::-;-1:-1:-1;;;477:247:7;;;;;;;;;;;-1:-1:-1;;;;;;16353:79:28;;;16335:98;;16323:2;16308:18;477:247:7;16290:149:28;3872:140:27;;;;;;:::i;:::-;;:::i;4018:150::-;;;;;;:::i;:::-;;:::i;3459:236::-;;;;;;:::i;:::-;;:::i;3351:166:2:-;;;;;;:::i;:::-;-1:-1:-1;;;;;3473:27:2;;;3450:4;3473:27;;;:18;:27;;;;;;;;:37;;;;;;;;;;;;;;;3351:166;252:219:7;;;;;;:::i;:::-;-1:-1:-1;;;252:219:7;;;;;;;;3584:389:2;;;;;;:::i;:::-;;:::i;1918:198:0:-;;;;;;:::i;:::-;;:::i;2170:228:2:-;2256:7;-1:-1:-1;;;;;2283:21:2;;2275:77;;;;-1:-1:-1;;;2275:77:2;;18992:2:28;2275:77:2;;;18974:21:28;19031:2;19011:18;;;19004:30;19070:34;19050:18;;;19043:62;19141:13;19121:18;;;19114:41;19172:19;;2275:77:2;;;;;;;;;-1:-1:-1;2369:13:2;;;;:9;:13;;;;;;;;-1:-1:-1;;;;;2369:22:2;;;;;;;;;;2170:228;;;;;:::o;5280:177:27:-;5391:4;5414:36;5438:11;5414:23;:36::i;4174:407::-;4331:23;;;;:15;:23;;;;;:31;;;4281:13;;4331:31;;;;;4310:113;;;;-1:-1:-1;;;4310:113:27;;24831:2:28;4310:113:27;;;24813:21:28;24870:2;24850:18;;;24843:30;24909:34;24889:18;;;24882:62;24980:5;24960:18;;;24953:33;25003:19;;4310:113:27;24803:225:28;4310:113:27;4476:1;4458:7;4452:21;;;;;:::i;:::-;;;:25;:122;;4567:7;4452:122;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4520:7;4529:17;:6;:15;:17::i;:::-;4503:44;;;;;;;;;:::i;:::-;;;;;;;;;;;;;4433:141;4174:407;-1:-1:-1;;4174:407:27:o;4045:430:2:-;-1:-1:-1;;;;;4270:20:2;;719:10:16;4270:20:2;;:60;;-1:-1:-1;4294:36:2;4311:4;719:10:16;3351:166:2;:::i;4294:36::-;4249:157;;;;-1:-1:-1;;;4249:157:2;;21790:2:28;4249:157:2;;;21772:21:28;21829:2;21809:18;;;21802:30;21868:34;21848:18;;;21841:62;21939:20;21919:18;;;21912:48;21977:19;;4249:157:2;21762:240:28;4249:157:2;4416:52;4439:4;4445:2;4449:3;4454:7;4463:4;4416:22;:52::i;:::-;4045:430;;;;;:::o;2709:201:27:-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4791:7:27;:14;2772:6;;4791:23;-1:-1:-1;4783:53:27;;;;-1:-1:-1;;;4783:53:27;;24075:2:28;4783:53:27;;;24057:21:28;24114:2;24094:18;;;24087:30;-1:-1:-1;;;24133:18:28;;;24126:47;24190:18;;4783:53:27;24047:167:28;4783:53:27;4916:23:::1;::::0;;;:15:::1;:23;::::0;;;;:31:::1;;::::0;:23;;:31:::1;::::0;::::1;;;4908:57;;;::::0;-1:-1:-1;;;4908:57:27;;23733:2:28;4908:57:27::1;::::0;::::1;23715:21:28::0;23772:2;23752:18;;;23745:30;23811:15;23791:18;;;23784:43;23844:18;;4908:57:27::1;23705:163:28::0;4908:57:27::1;-1:-1:-1::0;;;2880:23:27::2;::::0;;;:15:::2;:23;::::0;;;;;;;;2873:30;;::::2;::::0;::::2;::::0;;;;-1:-1:-1;;;;;2873:30:27::2;::::0;;;;::::2;::::0;;;::::2;::::0;;;;::::2;::::0;::::2;::::0;;;;;;;;::::2;::::0;::::2;::::0;;;;;::::2;::::0;;::::2;::::0;::::2;::::0;;::::2;;;::::0;;;;::::2;::::0;;::::2;;;;::::0;;;;;2709:201::o;1324:604::-;1082:7:0;1108:6;-1:-1:-1;;;;;1108:6:0;719:10:16;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;23372:2:28;1240:68:0;;;23354:21:28;;;23391:18;;;23384:30;-1:-1:-1;;;;;;;;;;;23430:18:28;;;23423:62;23502:18;;1240:68:0;23344:182:28;1240:68:0;1469:7:27::1;:14:::0;;1493:21:::1;::::0;;::::1;::::0;;;;;::::1;::::0;;;1551:243:::1;::::0;;::::1;::::0;::::1;::::0;;1451:15:::1;1551:243:::0;;;1493:21:::1;1551:243:::0;;::::1;::::0;;;;;;;;;;;;;;;;::::1;;::::0;;;;;;;::::1;;::::0;;;;;;1524:24;;;:15:::1;:24:::0;;;;;;;:270;;;;-1:-1:-1;;;;;1524:270:27;;;::::1;-1:-1:-1::0;;1524:270:27;;::::1;;::::0;;;;;;::::1;::::0;;;;;;::::1;::::0;::::1;::::0;;::::1;::::0;::::1;::::0;;;::::1;::::0;;::::1;::::0;;;;::::1;;;;-1:-1:-1::0;;1524:270:27;::::1;;::::0;;;;-1:-1:-1;;1524:270:27;;;;;;;::::1;::::0;;;1805:83;::::1;;;1828:49;1842:4;1849:7;1858:14;1828:49;;;;;;;;;;;::::0;:5:::1;:49::i;:::-;1903:18;::::0;26673:25:28;;;1903:18:27::1;::::0;26661:2:28;26646:18;1903::27::1;;;;;;;;1318:1:0;1324:604:27::0;;;;;:::o;3701:165::-;1082:7:0;1108:6;-1:-1:-1;;;;;1108:6:0;719:10:16;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;23372:2:28;1240:68:0;;;23354:21:28;;;23391:18;;;23384:30;-1:-1:-1;;;;;;;;;;;23430:18:28;;;23423:62;23502:18;;1240:68:0;23344:182:28;1240:68:0;3777:18:27;;::::1;::::0;:7:::1;::::0;:18:::1;::::0;::::1;::::0;::::1;:::i;:::-;;3805:17;3813:8;3805:7;:17::i;:::-;3837:22;3851:7;3837:22;;;;;;:::i;:::-;;;;;;;;3701:165:::0;:::o;4587:139::-;1082:7:0;1108:6;-1:-1:-1;;;;;1108:6:0;719:10:16;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;23372:2:28;1240:68:0;;;23354:21:28;;;23391:18;;;23384:30;-1:-1:-1;;;;;;;;;;;23430:18:28;;;23423:62;23502:18;;1240:68:0;23344:182:28;1240:68:0;4682:37:27::1;::::0;4651:21:::1;::::0;4690:10:::1;::::0;4682:37;::::1;;;::::0;4651:21;;4636:12:::1;4682:37:::0;4636:12;4682:37;4651:21;4690:10;4682:37;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;1318:1:0;4587:139:27:o:0;6156:82::-;1082:7:0;1108:6;-1:-1:-1;;;;;1108:6:0;719:10:16;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;23372:2:28;1240:68:0;;;23354:21:28;;;23391:18;;;23384:30;-1:-1:-1;;;;;;;;;;;23430:18:28;;;23423:62;23502:18;;1240:68:0;23344:182:28;1240:68:0;1168:7:1;;;;1669:41:::1;;;::::0;-1:-1:-1;;;1669:41:1;;18643:2:28;1669:41:1::1;::::0;::::1;18625:21:28::0;18682:2;18662:18;;;18655:30;18721:22;18701:18;;;18694:50;18761:18;;1669:41:1::1;18615:170:28::0;1669:41:1::1;6215:16:27::2;:14;:16::i;:::-;6156:82::o:0;2916:325::-;3079:7;:14;2959:54;;3039:55;;;;;;-1:-1:-1;;;3039:55:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3039:55:27;;-1:-1:-1;;3039:55:27;;;;;;;;;;;;3025:69;;3108:13;3104:131;3133:7;:14;3127:20;;3104:131;;;3193:15;:31;3209:7;3217:5;3209:14;;;;;;-1:-1:-1;;;3209:14:27;;;;;;;;;;;;;;;;;;;;;3193:31;;;;;;;;;;;;;;;3172:52;;;;;;;;;-1:-1:-1;;;;;3172:52:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:18;;:11;;3184:5;;3172:18;;;;-1:-1:-1;;;3172:18:27;;;;;;;;;;;;;;:52;;;;3149:7;;;;;:::i;:::-;;;;3104:131;;;;2916:325;:::o;2555:508:2:-;2706:16;2765:3;:10;2746:8;:15;:29;2738:83;;;;-1:-1:-1;;;2738:83:2;;25235:2:28;2738:83:2;;;25217:21:28;25274:2;25254:18;;;25247:30;25313:34;25293:18;;;25286:62;25384:11;25364:18;;;25357:39;25413:19;;2738:83:2;25207:231:28;2738:83:2;2832:30;2879:8;:15;2865:30;;;;;;-1:-1:-1;;;2865:30:2;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2865:30:2;;2832:63;;2911:9;2906:120;2930:8;:15;2926:1;:19;2906:120;;;2985:30;2995:8;3004:1;2995:11;;;;;;-1:-1:-1;;;2995:11:2;;;;;;;;;;;;;;;3008:3;3012:1;3008:6;;;;;;-1:-1:-1;;;3008:6:2;;;;;;;;;;;;;;;2985:9;:30::i;:::-;2966:13;2980:1;2966:16;;;;;;-1:-1:-1;;;2966:16:2;;;;;;;;;;;;;;;;;;:49;2947:3;;;:::i;:::-;;;2906:120;;;-1:-1:-1;3043:13:2;2555:508;-1:-1:-1;;;2555:508:2:o;3247:206:27:-;4791:7;:14;3325:6;;4791:23;-1:-1:-1;4783:53:27;;;;-1:-1:-1;;;4783:53:27;;24075:2:28;4783:53:27;;;24057:21:28;24114:2;24094:18;;;24087:30;-1:-1:-1;;;24133:18:28;;;24126:47;24190:18;;4783:53:27;24047:167:28;4783:53:27;1168:7:1;;;;1411:9:::1;1403:38;;;::::0;-1:-1:-1;;;1403:38:1;;21039:2:28;1403:38:1::1;::::0;::::1;21021:21:28::0;21078:2;21058:18;;;21051:30;-1:-1:-1;;;21097:18:28;;;21090:46;21153:18;;1403:38:1::1;21011:166:28::0;1403:38:1::1;3357:33:27::2;3363:10;3375:6;3383;3357:5;:33::i;:::-;3405:41;::::0;;3419:10:::2;13751:74:28::0;;13856:2;13841:18;;13834:34;;;13884:18;;;13877:34;;;3405:41:27::2;::::0;13739:2:28;13724:18;3405:41:27::2;;;;;;;3247:206:::0;;;:::o;1934:188::-;1082:7:0;1108:6;-1:-1:-1;;;;;1108:6:0;719:10:16;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;23372:2:28;1240:68:0;;;23354:21:28;;;23391:18;;;23384:30;-1:-1:-1;;;;;;;;;;;23430:18:28;;;23423:62;23502:18;;1240:68:0;23344:182:28;1240:68:0;4791:7:27::1;:14:::0;2008:6;;4791:23;-1:-1:-1;4783:53:27::1;;;::::0;-1:-1:-1;;;4783:53:27;;24075:2:28;4783:53:27::1;::::0;::::1;24057:21:28::0;24114:2;24094:18;;;24087:30;-1:-1:-1;;;24133:18:28;;;24126:47;24190:18;;4783:53:27::1;24047:167:28::0;4783:53:27::1;2026:89:::2;2051:4;2058:10;2070:6;2078:32;2096:4;2103:6;2078:9;:32::i;:::-;2026:89;;;;;;;;;;;::::0;:16:::2;:89::i;1668:101:0:-:0;1082:7;1108:6;-1:-1:-1;;;;;1108:6:0;719:10:16;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;23372:2:28;1240:68:0;;;23354:21:28;;;23391:18;;;23384:30;-1:-1:-1;;;;;;;;;;;23430:18:28;;;23423:62;23502:18;;1240:68:0;23344:182:28;1240:68:0;1732:30:::1;1759:1;1732:18;:30::i;6069:81:27:-:0;1082:7:0;1108:6;-1:-1:-1;;;;;1108:6:0;719:10:16;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;23372:2:28;1240:68:0;;;23354:21:28;;;23391:18;;;23384:30;-1:-1:-1;;;;;;;;;;;23430:18:28;;;23423:62;23502:18;;1240:68:0;23344:182:28;1240:68:0;1168:7:1;;;;1411:9:::1;1403:38;;;::::0;-1:-1:-1;;;1403:38:1;;21039:2:28;1403:38:1::1;::::0;::::1;21021:21:28::0;21078:2;21058:18;;;21051:30;-1:-1:-1;;;21097:18:28;;;21090:46;21153:18;;1403:38:1::1;21011:166:28::0;1403:38:1::1;6129:14:27::2;:12;:14::i;2446:147::-:0;1082:7:0;1108:6;-1:-1:-1;;;;;1108:6:0;719:10:16;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;23372:2:28;1240:68:0;;;23354:21:28;;;23391:18;;;23384:30;-1:-1:-1;;;;;;;;;;;23430:18:28;;;23423:62;23502:18;;1240:68:0;23344:182:28;1240:68:0;2546:5:27::1;2512:23:::0;;;:15:::1;:23;::::0;;;;;;:31:::1;;:39:::0;;-1:-1:-1;;2512:39:27::1;::::0;;2566:20;::::1;::::0;::::1;::::0;2528:6;26673:25:28;;26661:2;26646:18;;26628:76;3131:153:2;3225:52;719:10:16;3258:8:2;3268;3225:18;:52::i;2128:312:27:-;1082:7:0;1108:6;-1:-1:-1;;;;;1108:6:0;719:10:16;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;23372:2:28;1240:68:0;;;23354:21:28;;;23391:18;;;23384:30;-1:-1:-1;;;;;;;;;;;23430:18:28;;;23423:62;23502:18;;1240:68:0;23344:182:28;1240:68:0;4791:7:27::1;:14:::0;2217:6;;4791:23;-1:-1:-1;4783:53:27::1;;;::::0;-1:-1:-1;;;4783:53:27;;24075:2:28;4783:53:27::1;::::0;::::1;24057:21:28::0;24114:2;24094:18;;;24087:30;-1:-1:-1;;;24133:18:28;;;24126:47;24190:18;;4783:53:27::1;24047:167:28::0;4783:53:27::1;2235:52:::2;2290:23:::0;;;:15:::2;:23;::::0;;;;;;;;2341:15:::2;::::0;::::2;::::0;;2366:22;;;;2403:30;;26883:25:28;;;26924:18;;;26917:34;;;2290:23:27;;2341:15;;2403:30:::2;::::0;26856:18:28;2403:30:27::2;;;;;;;4846:1;;1318::0::1;2128:312:27::0;;:::o;816:24::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;816:24:27;:::o;3872:140::-;1082:7:0;1108:6;-1:-1:-1;;;;;1108:6:0;719:10:16;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;23372:2:28;1240:68:0;;;23354:21:28;;;23391:18;;;23384:30;-1:-1:-1;;;;;;;;;;;23430:18:28;;;23423:62;23502:18;;1240:68:0;23344:182:28;1240:68:0;3968:37:27::1;3979:7;1082::0::0;1108:6;-1:-1:-1;;;;;1108:6:0;;1036:85;3979:7:27::1;3988:3;3993:7;3968:37;;;;;;;;;;;::::0;:10:::1;:37::i;4018:150::-:0;1082:7:0;1108:6;-1:-1:-1;;;;;1108:6:0;719:10:16;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;23372:2:28;1240:68:0;;;23354:21:28;;;23391:18;;;23384:30;-1:-1:-1;;;;;;;;;;;23430:18:28;;;23423:62;23502:18;;1240:68:0;23344:182:28;1240:68:0;4129:32:27::1;4140:2;4144:3;4149:7;4129:32;;;;;;;;;;;::::0;:10:::1;:32::i;:::-;4018:150:::0;;;:::o;3459:236::-;4791:7;:14;3555:6;;4791:23;-1:-1:-1;4783:53:27;;;;-1:-1:-1;;;4783:53:27;;24075:2:28;4783:53:27;;;24057:21:28;24114:2;24094:18;;;24087:30;-1:-1:-1;;;24133:18:28;;;24126:47;24190:18;;4783:53:27;24047:167:28;4783:53:27;5039:51:::1;5093:24:::0;;;:15:::1;:24;::::0;;;;;;;;5039:78;;::::1;::::0;::::1;::::0;;;;-1:-1:-1;;;;;5039:78:27::1;::::0;;;;;::::1;::::0;;;::::1;::::0;;;;::::1;::::0;::::1;::::0;;;;;;;;::::1;::::0;::::1;::::0;;;;;::::1;;::::0;::::1;::::0;;::::1;;;::::0;;;;::::1;::::0;;::::1;;;;::::0;;;;3577:6;;5039:78;5130:35;5127:130:::1;;5203:19:::0;;-1:-1:-1;;;;;5189:33:27::1;:10;:33;5181:65;;;::::0;-1:-1:-1;;;5181:65:27;;22209:2:28;5181:65:27::1;::::0;::::1;22191:21:28::0;22248:2;22228:18;;;22221:30;22287:21;22267:18;;;22260:49;22326:18;;5181:65:27::1;22181:169:28::0;5181:65:27::1;1168:7:1::0;;;;1411:9:::2;1403:38;;;::::0;-1:-1:-1;;;1403:38:1;;21039:2:28;1403:38:1::2;::::0;::::2;21021:21:28::0;21078:2;21058:18;;;21051:30;-1:-1:-1;;;21097:18:28;;;21090:46;21153:18;;1403:38:1::2;21011:166:28::0;1403:38:1::2;3609:28:27::3;3615:5;3622:6;3630;3609:5;:28::i;:::-;3652:36;::::0;;-1:-1:-1;;;;;13769:55:28;;13751:74;;13856:2;13841:18;;13834:34;;;13884:18;;;13877:34;;;3652:36:27::3;::::0;13739:2:28;13724:18;3652:36:27::3;13706:211:28::0;3584:389:2;-1:-1:-1;;;;;3784:20:2;;719:10:16;3784:20:2;;:60;;-1:-1:-1;3808:36:2;3825:4;719:10:16;3351:166:2;:::i;3808:36::-;3763:148;;;;-1:-1:-1;;;3763:148:2;;20629:2:28;3763:148:2;;;20611:21:28;20668:2;20648:18;;;20641:30;20707:34;20687:18;;;20680:62;20778:11;20758:18;;;20751:39;20807:19;;3763:148:2;20601:231:28;3763:148:2;3921:45;3939:4;3945:2;3949;3953:6;3961:4;3921:17;:45::i;1918:198:0:-;1082:7;1108:6;-1:-1:-1;;;;;1108:6:0;719:10:16;1248:23:0;1240:68;;;;-1:-1:-1;;;1240:68:0;;23372:2:28;1240:68:0;;;23354:21:28;;;23391:18;;;23384:30;-1:-1:-1;;;;;;;;;;;23430:18:28;;;23423:62;23502:18;;1240:68:0;23344:182:28;1240:68:0;-1:-1:-1;;;;;2006:22:0;::::1;1998:73;;;::::0;-1:-1:-1;;;1998:73:0;;19404:2:28;1998:73:0::1;::::0;::::1;19386:21:28::0;19443:2;19423:18;;;19416:30;19482:34;19462:18;;;19455:62;19553:8;19533:18;;;19526:36;19579:19;;1998:73:0::1;19376:228:28::0;1998:73:0::1;2081:28;2100:8;2081:18;:28::i;:::-;1918:198:::0;:::o;387:221:8:-;489:4;-1:-1:-1;;;;;;512:49:8;;527:34;512:49;;:89;;;565:36;589:11;565:23;:36::i;328:703:17:-;384:13;601:10;597:51;;-1:-1:-1;;627:10:17;;;;;;;;;;;;;;;;;;328:703::o;597:51::-;672:5;657:12;711:75;718:9;;711:75;;743:8;;;;:::i;:::-;;-1:-1:-1;765:10:17;;-1:-1:-1;773:2:17;765:10;;:::i;:::-;;;711:75;;;795:19;827:6;817:17;;;;;;-1:-1:-1;;;817:17:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;817:17:17;;795:39;;844:150;851:10;;844:150;;877:11;887:1;877:11;;:::i;:::-;;-1:-1:-1;945:10:17;953:2;945:5;:10;:::i;:::-;932:24;;:2;:24;:::i;:::-;919:39;;902:6;909;902:14;;;;;;-1:-1:-1;;;902:14:17;;;;;;;;;;;;:56;;;;;;;;;;-1:-1:-1;972:11:17;981:2;972:11;;:::i;:::-;;;844:150;;;1017:6;328:703;-1:-1:-1;;;;328:703:17:o;6068:1045:2:-;6288:7;:14;6274:3;:10;:28;6266:81;;;;-1:-1:-1;;;6266:81:2;;25645:2:28;6266:81:2;;;25627:21:28;25684:2;25664:18;;;25657:30;25723:34;25703:18;;;25696:62;-1:-1:-1;;;25774:18:28;;;25767:38;25822:19;;6266:81:2;25617:230:28;6266:81:2;-1:-1:-1;;;;;6365:16:2;;6357:66;;;;-1:-1:-1;;;6357:66:2;;21384:2:28;6357:66:2;;;21366:21:28;21423:2;21403:18;;;21396:30;21462:34;21442:18;;;21435:62;-1:-1:-1;;;21513:18:28;;;21506:35;21558:19;;6357:66:2;21356:227:28;6357:66:2;719:10:16;6476:60:2;719:10:16;6507:4:2;6513:2;6517:3;6522:7;6531:4;6476:20;:60::i;:::-;6552:9;6547:411;6571:3;:10;6567:1;:14;6547:411;;;6602:10;6615:3;6619:1;6615:6;;;;;;-1:-1:-1;;;6615:6:2;;;;;;;;;;;;;;;6602:19;;6635:14;6652:7;6660:1;6652:10;;;;;;-1:-1:-1;;;6652:10:2;;;;;;;;;;;;;;;;;;;;6677:19;6699:13;;;:9;:13;;;;;;-1:-1:-1;;;;;6699:19:2;;;;;;;;;;;;6652:10;;-1:-1:-1;6740:21:2;;;;6732:76;;;;-1:-1:-1;;;6732:76:2;;22961:2:28;6732:76:2;;;22943:21:28;23000:2;22980:18;;;22973:30;23039:34;23019:18;;;23012:62;-1:-1:-1;;;23090:18:28;;;23083:40;23140:19;;6732:76:2;22933:232:28;6732:76:2;6850:13;;;;:9;:13;;;;;;;;-1:-1:-1;;;;;6850:19:2;;;;;;;;;;6872:20;;;6850:42;;6920:17;;;;;;;:27;;6872:20;;6850:13;6920:27;;6872:20;;6920:27;:::i;:::-;;;;;;;;6547:411;;;6583:3;;;;:::i;:::-;;;6547:411;;;;7003:2;-1:-1:-1;;;;;6973:47:2;6997:4;-1:-1:-1;;;;;6973:47:2;6987:8;-1:-1:-1;;;;;6973:47:2;;7007:3;7012:7;6973:47;;;;;;;:::i;:::-;;;;;;;;7031:75;7067:8;7077:4;7083:2;7087:3;7092:7;7101:4;7031:35;:75::i;:::-;6068:1045;;;;;;:::o;8395:553::-;-1:-1:-1;;;;;8542:16:2;;8534:62;;;;-1:-1:-1;;;8534:62:2;;26054:2:28;8534:62:2;;;26036:21:28;26093:2;26073:18;;;26066:30;26132:34;26112:18;;;26105:62;-1:-1:-1;;;26183:18:28;;;26176:31;26224:19;;8534:62:2;26026:223:28;8534:62:2;719:10:16;8649:102:2;719:10:16;8607:16:2;8692:2;8696:21;8714:2;8696:17;:21::i;:::-;8719:25;8737:6;8719:17;:25::i;:::-;8746:4;8649:20;:102::i;:::-;8762:13;;;;:9;:13;;;;;;;;-1:-1:-1;;;;;8762:17:2;;;;;;;;;:27;;8783:6;;8762:13;:27;;8783:6;;8762:27;:::i;:::-;;;;-1:-1:-1;;8804:52:2;;;26883:25:28;;;26939:2;26924:18;;26917:34;;;-1:-1:-1;;;;;8804:52:2;;;;8837:1;;8804:52;;;;;;26856:18:28;8804:52:2;;;;;;;8867:74;8898:8;8916:1;8920:2;8924;8928:6;8936:4;8867:30;:74::i;7936:86::-;8002:13;;;;:4;;:13;;;;;:::i;2110:117:1:-;1168:7;;;;1669:41;;;;-1:-1:-1;;;1669:41:1;;18643:2:28;1669:41:1;;;18625:21:28;18682:2;18662:18;;;18655:30;18721:22;18701:18;;;18694:50;18761:18;;1669:41:1;18615:170:28;1669:41:1;2168:7:::1;:15:::0;;-1:-1:-1;;2168:15:1::1;::::0;;2198:22:::1;719:10:16::0;2207:12:1::1;2198:22;::::0;-1:-1:-1;;;;;12040:55:28;;;12022:74;;12010:2;11995:18;2198:22:1::1;;;;;;;2110:117::o:0;10248:630:2:-;-1:-1:-1;;;;;10370:18:2;;10362:66;;;;-1:-1:-1;;;10362:66:2;;22557:2:28;10362:66:2;;;22539:21:28;22596:2;22576:18;;;22569:30;22635:34;22615:18;;;22608:62;22706:5;22686:18;;;22679:33;22729:19;;10362:66:2;22529:225:28;10362:66:2;719:10:16;10481:102:2;719:10:16;10512:4:2;10439:16;10530:21;10548:2;10530:17;:21::i;:::-;10553:25;10571:6;10553:17;:25::i;:::-;10481:102;;;;;;;;;;;;:20;:102::i;:::-;10594:19;10616:13;;;:9;:13;;;;;;;;-1:-1:-1;;;;;10616:19:2;;;;;;;;;;10653:21;;;;10645:70;;;;-1:-1:-1;;;10645:70:2;;19811:2:28;10645:70:2;;;19793:21:28;19850:2;19830:18;;;19823:30;19889:34;19869:18;;;19862:62;19960:6;19940:18;;;19933:34;19984:19;;10645:70:2;19783:226:28;10645:70:2;10749:13;;;;:9;:13;;;;;;;;-1:-1:-1;;;;;10749:19:2;;;;;;;;;;;;10771:20;;;10749:42;;10817:54;;26883:25:28;;;26924:18;;;26917:34;;;10749:19:2;;10817:54;;;;;;26856:18:28;10817:54:2;;;;;;;10248:630;;;;;:::o;2270:187:0:-;2343:16;2362:6;;-1:-1:-1;;;;;2378:17:0;;;-1:-1:-1;;2378:17:0;;;;;;2410:40;;2362:6;;;;;;;2410:40;;2343:16;2410:40;2270:187;;:::o;1863:115:1:-;1168:7;;;;1411:9;1403:38;;;;-1:-1:-1;;;1403:38:1;;21039:2:28;1403:38:1;;;21021:21:28;21078:2;21058:18;;;21051:30;-1:-1:-1;;;21097:18:28;;;21090:46;21153:18;;1403:38:1;21011:166:28;1403:38:1;1922:7:::1;:14:::0;;-1:-1:-1;;1922:14:1::1;1932:4;1922:14;::::0;;1951:20:::1;1958:12;719:10:16::0;;640:96;12074:323:2;12224:8;-1:-1:-1;;;;;12215:17:2;:5;-1:-1:-1;;;;;12215:17:2;;;12207:71;;;;-1:-1:-1;;;12207:71:2;;24421:2:28;12207:71:2;;;24403:21:28;24460:2;24440:18;;;24433:30;24499:34;24479:18;;;24472:62;24570:11;24550:18;;;24543:39;24599:19;;12207:71:2;24393:231:28;12207:71:2;-1:-1:-1;;;;;12288:25:2;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;12288:46:2;;;;;;;;;;12349:41;;16139::28;;;12349::2;;16112:18:28;12349:41:2;;;;;;;12074:323;;;:::o;9293:715::-;-1:-1:-1;;;;;9465:16:2;;9457:62;;;;-1:-1:-1;;;9457:62:2;;26054:2:28;9457:62:2;;;26036:21:28;26093:2;26073:18;;;26066:30;26132:34;26112:18;;;26105:62;-1:-1:-1;;;26183:18:28;;;26176:31;26224:19;;9457:62:2;26026:223:28;9457:62:2;9551:7;:14;9537:3;:10;:28;9529:81;;;;-1:-1:-1;;;9529:81:2;;25645:2:28;9529:81:2;;;25627:21:28;25684:2;25664:18;;;25657:30;25723:34;25703:18;;;25696:62;-1:-1:-1;;;25774:18:28;;;25767:38;25822:19;;9529:81:2;25617:230:28;9529:81:2;719:10:16;9663:66:2;719:10:16;9621:16:2;9706:2;9710:3;9715:7;9724:4;9663:20;:66::i;:::-;9745:9;9740:101;9764:3;:10;9760:1;:14;9740:101;;;9820:7;9828:1;9820:10;;;;;;-1:-1:-1;;;9820:10:2;;;;;;;;;;;;;;;9795:9;:17;9805:3;9809:1;9805:6;;;;;;-1:-1:-1;;;9805:6:2;;;;;;;;;;;;;;;9795:17;;;;;;;;;;;:21;9813:2;-1:-1:-1;;;;;9795:21:2;-1:-1:-1;;;;;9795:21:2;;;;;;;;;;;;;:35;;;;;;;:::i;:::-;;;;-1:-1:-1;9776:3:2;;-1:-1:-1;9776:3:2;;;:::i;:::-;;;;9740:101;;;;9892:2;-1:-1:-1;;;;;9856:53:2;9888:1;-1:-1:-1;;;;;9856:53:2;9870:8;-1:-1:-1;;;;;9856:53:2;;9896:3;9901:7;9856:53;;;;;;;:::i;:::-;;;;;;;;9920:81;9956:8;9974:1;9978:2;9982:3;9987:7;9996:4;9920:35;:81::i;4925:797::-;-1:-1:-1;;;;;5106:16:2;;5098:66;;;;-1:-1:-1;;;5098:66:2;;21384:2:28;5098:66:2;;;21366:21:28;21423:2;21403:18;;;21396:30;21462:34;21442:18;;;21435:62;-1:-1:-1;;;21513:18:28;;;21506:35;21558:19;;5098:66:2;21356:227:28;5098:66:2;719:10:16;5217:96:2;719:10:16;5248:4:2;5254:2;5258:21;5276:2;5258:17;:21::i;5217:96::-;5324:19;5346:13;;;:9;:13;;;;;;;;-1:-1:-1;;;;;5346:19:2;;;;;;;;;;5383:21;;;;5375:76;;;;-1:-1:-1;;;5375:76:2;;22961:2:28;5375:76:2;;;22943:21:28;23000:2;22980:18;;;22973:30;23039:34;23019:18;;;23012:62;-1:-1:-1;;;23090:18:28;;;23083:40;23140:19;;5375:76:2;22933:232:28;5375:76:2;5485:13;;;;:9;:13;;;;;;;;-1:-1:-1;;;;;5485:19:2;;;;;;;;;;5507:20;;;5485:42;;5547:17;;;;;;;:27;;5507:20;;5485:13;5547:27;;5507:20;;5547:27;:::i;:::-;;;;-1:-1:-1;;5590:46:2;;;26883:25:28;;;26939:2;26924:18;;26917:34;;;-1:-1:-1;;;;;5590:46:2;;;;;;;;;;;;;;26856:18:28;5590:46:2;;;;;;;5647:68;5678:8;5688:4;5694:2;5698;5702:6;5710:4;5647:30;:68::i;:::-;4925:797;;;;;;;:::o;1221:305::-;1323:4;-1:-1:-1;;;;;;1358:41:2;;1373:26;1358:41;;:109;;-1:-1:-1;;;;;;;1415:52:2;;1430:37;1415:52;1358:109;:161;;;-1:-1:-1;952:25:19;-1:-1:-1;;;;;;937:40:19;;;1483:36:2;829:155:19;5463:600:27;5694:66;5721:8;5731:4;5737:2;5741:3;5746:7;5755:4;5694:26;:66::i;:::-;5775:10;5788:3;5792:1;5788:6;;;;;;-1:-1:-1;;;5788:6:27;;;;;;;;;;;;;;;5775:19;;5771:286;5799:3;:10;5796:2;:13;5771:286;;;5831:51;5885:19;;;:15;:19;;;;;;;;;5831:73;;;;;;;;;-1:-1:-1;;;;;5831:73:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5921:35;5918:129;;5990:19;;5976:56;;;;;;;;26673:25:28;;;-1:-1:-1;;;;;5976:52:27;;;;;;26646:18:28;;5976:56:27;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;5918:129;-1:-1:-1;5811:4:27;;;;:::i;:::-;;;;5771:286;;14282:792:2;-1:-1:-1;;;;;14514:13:2;;1087:20:15;1133:8;14510:558:2;;14549:79;;-1:-1:-1;;;14549:79:2;;-1:-1:-1;;;;;14549:43:2;;;;;:79;;14593:8;;14603:4;;14609:3;;14614:7;;14623:4;;14549:79;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;14549:79:2;;;;;;;;-1:-1:-1;;14549:79:2;;;;;;;;;;;;:::i;:::-;;;14545:513;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;14934:6;14927:14;;-1:-1:-1;;;14927:14:2;;;;;;;;:::i;14545:513::-;;;14981:62;;-1:-1:-1;;;14981:62:2;;17813:2:28;14981:62:2;;;17795:21:28;17852:2;17832:18;;;17825:30;17891:34;17871:18;;;17864:62;17962:22;17942:18;;;17935:50;18002:19;;14981:62:2;17785:242:28;14545:513:2;-1:-1:-1;;;;;;14707:60:2;;-1:-1:-1;;;14707:60:2;14703:157;;14791:50;;-1:-1:-1;;;14791:50:2;;18234:2:28;14791:50:2;;;18216:21:28;18273:2;18253:18;;;18246:30;18312:34;18292:18;;;18285:62;-1:-1:-1;;;18363:18:28;;;18356:38;18411:19;;14791:50:2;18206:230:28;15080:193:2;15199:16;;;15213:1;15199:16;;;;;;;;;15146;;15174:22;;15199:16;;;;;;;;;;;;-1:-1:-1;15199:16:2;15174:41;;15236:7;15225:5;15231:1;15225:8;;;;;;-1:-1:-1;;;15225:8:2;;;;;;;;;;;;;;;;;;:18;15261:5;15080:193;-1:-1:-1;;15080:193:2:o;13551:725::-;-1:-1:-1;;;;;13758:13:2;;1087:20:15;1133:8;13754:516:2;;13793:72;;-1:-1:-1;;;13793:72:2;;-1:-1:-1;;;;;13793:38:2;;;;;:72;;13832:8;;13842:4;;13848:2;;13852:6;;13860:4;;13793:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;13793:72:2;;;;;;;;-1:-1:-1;;13793:72:2;;;;;;;;;;;;:::i;:::-;;;13789:471;;;;:::i;:::-;-1:-1:-1;;;;;;13914:55:2;;-1:-1:-1;;;13914:55:2;13910:152;;13993:50;;-1:-1:-1;;;13993:50:2;;18234:2:28;13993:50:2;;;18216:21:28;18273:2;18253:18;;;18246:30;18312:34;18292:18;;;18285:62;-1:-1:-1;;;18363:18:28;;;18356:38;18411:19;;13993:50:2;18206:230:28;709:381:5;1168:7:1;;;;1025:9:5;1017:66;;;;-1:-1:-1;;;1017:66:5;;20216:2:28;1017:66:5;;;20198:21:28;20255:2;20235:18;;;20228:30;20294:34;20274:18;;;20267:62;20365:14;20345:18;;;20338:42;20397:19;;1017:66:5;20188:234:28;-1:-1:-1;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:468:28;78:5;112:18;104:6;101:30;98:2;;;134:18;;:::i;:::-;183:2;177:9;195:69;252:2;231:15;;-1:-1:-1;;227:29:28;258:4;223:40;177:9;195:69;:::i;:::-;282:6;273:15;;312:6;304;297:22;352:3;343:6;338:3;334:16;331:25;328:2;;;369:1;366;359:12;328:2;419:6;414:3;407:4;399:6;395:17;382:44;474:1;467:4;458:6;450;446:19;442:30;435:41;;88:394;;;;;:::o;487:196::-;555:20;;-1:-1:-1;;;;;604:54:28;;594:65;;584:2;;673:1;670;663:12;584:2;536:147;;;:::o;688:755::-;742:5;795:3;788:4;780:6;776:17;772:27;762:2;;817:5;810;803:20;762:2;857:6;844:20;883:4;906:43;946:2;906:43;:::i;:::-;978:2;972:9;990:31;1018:2;1010:6;990:31;:::i;:::-;1056:18;;;1090:15;;;;-1:-1:-1;1125:15:28;;;1175:1;1171:10;;;1159:23;;1155:32;;1152:41;-1:-1:-1;1149:2:28;;;1210:5;1203;1196:20;1149:2;1236:5;1250:163;1264:2;1261:1;1258:9;1250:163;;;1321:17;;1309:30;;1359:12;;;;1391;;;;1282:1;1275:9;1250:163;;;-1:-1:-1;1431:6:28;;752:691;-1:-1:-1;;;;;;;752:691:28:o;1448:228::-;1490:5;1543:3;1536:4;1528:6;1524:17;1520:27;1510:2;;1565:5;1558;1551:20;1510:2;1591:79;1666:3;1657:6;1644:20;1637:4;1629:6;1625:17;1591:79;:::i;:::-;1582:88;1500:176;-1:-1:-1;;;1500:176:28:o;1681:196::-;1740:6;1793:2;1781:9;1772:7;1768:23;1764:32;1761:2;;;1814:6;1806;1799:22;1761:2;1842:29;1861:9;1842:29;:::i;1882:270::-;1950:6;1958;2011:2;1999:9;1990:7;1986:23;1982:32;1979:2;;;2032:6;2024;2017:22;1979:2;2060:29;2079:9;2060:29;:::i;:::-;2050:39;;2108:38;2142:2;2131:9;2127:18;2108:38;:::i;:::-;2098:48;;1969:183;;;;;:::o;2157:983::-;2311:6;2319;2327;2335;2343;2396:3;2384:9;2375:7;2371:23;2367:33;2364:2;;;2418:6;2410;2403:22;2364:2;2446:29;2465:9;2446:29;:::i;:::-;2436:39;;2494:38;2528:2;2517:9;2513:18;2494:38;:::i;:::-;2484:48;;2583:2;2572:9;2568:18;2555:32;2606:18;2647:2;2639:6;2636:14;2633:2;;;2668:6;2660;2653:22;2633:2;2696:61;2749:7;2740:6;2729:9;2725:22;2696:61;:::i;:::-;2686:71;;2810:2;2799:9;2795:18;2782:32;2766:48;;2839:2;2829:8;2826:16;2823:2;;;2860:6;2852;2845:22;2823:2;2888:63;2943:7;2932:8;2921:9;2917:24;2888:63;:::i;:::-;2878:73;;3004:3;2993:9;2989:19;2976:33;2960:49;;3034:2;3024:8;3021:16;3018:2;;;3055:6;3047;3040:22;3018:2;;3083:51;3126:7;3115:8;3104:9;3100:24;3083:51;:::i;:::-;3073:61;;;2354:786;;;;;;;;:::o;3145:626::-;3249:6;3257;3265;3273;3281;3334:3;3322:9;3313:7;3309:23;3305:33;3302:2;;;3356:6;3348;3341:22;3302:2;3384:29;3403:9;3384:29;:::i;:::-;3374:39;;3432:38;3466:2;3455:9;3451:18;3432:38;:::i;:::-;3422:48;;3517:2;3506:9;3502:18;3489:32;3479:42;;3568:2;3557:9;3553:18;3540:32;3530:42;;3623:3;3612:9;3608:19;3595:33;3651:18;3643:6;3640:30;3637:2;;;3688:6;3680;3673:22;3637:2;3716:49;3757:7;3748:6;3737:9;3733:22;3716:49;:::i;3776:325::-;3841:6;3849;3902:2;3890:9;3881:7;3877:23;3873:32;3870:2;;;3923:6;3915;3908:22;3870:2;3951:29;3970:9;3951:29;:::i;:::-;3941:39;;4030:2;4019:9;4015:18;4002:32;4043:28;4065:5;4043:28;:::i;:::-;4090:5;4080:15;;;3860:241;;;;;:::o;4106:264::-;4174:6;4182;4235:2;4223:9;4214:7;4210:23;4206:32;4203:2;;;4256:6;4248;4241:22;4203:2;4284:29;4303:9;4284:29;:::i;:::-;4274:39;4360:2;4345:18;;;;4332:32;;-1:-1:-1;;;4193:177:28:o;4375:332::-;4452:6;4460;4468;4521:2;4509:9;4500:7;4496:23;4492:32;4489:2;;;4542:6;4534;4527:22;4489:2;4570:29;4589:9;4570:29;:::i;:::-;4560:39;4646:2;4631:18;;4618:32;;-1:-1:-1;4697:2:28;4682:18;;;4669:32;;4479:228;-1:-1:-1;;;4479:228:28:o;4712:1274::-;4830:6;4838;4891:2;4879:9;4870:7;4866:23;4862:32;4859:2;;;4912:6;4904;4897:22;4859:2;4957:9;4944:23;4986:18;5027:2;5019:6;5016:14;5013:2;;;5048:6;5040;5033:22;5013:2;5091:6;5080:9;5076:22;5066:32;;5136:7;5129:4;5125:2;5121:13;5117:27;5107:2;;5163:6;5155;5148:22;5107:2;5204;5191:16;5226:4;5249:43;5289:2;5249:43;:::i;:::-;5321:2;5315:9;5333:31;5361:2;5353:6;5333:31;:::i;:::-;5399:18;;;5433:15;;;;-1:-1:-1;5468:11:28;;;5510:1;5506:10;;;5498:19;;5494:28;;5491:41;-1:-1:-1;5488:2:28;;;5550:6;5542;5535:22;5488:2;5577:6;5568:15;;5592:169;5606:2;5603:1;5600:9;5592:169;;;5663:23;5682:3;5663:23;:::i;:::-;5651:36;;5624:1;5617:9;;;;;5707:12;;;;5739;;5592:169;;;-1:-1:-1;5780:6:28;-1:-1:-1;;5824:18:28;;5811:32;;-1:-1:-1;;5855:16:28;;;5852:2;;;5889:6;5881;5874:22;5852:2;;5917:63;5972:7;5961:8;5950:9;5946:24;5917:63;:::i;:::-;5907:73;;;4849:1137;;;;;:::o;5991:625::-;6109:6;6117;6170:2;6158:9;6149:7;6145:23;6141:32;6138:2;;;6191:6;6183;6176:22;6138:2;6236:9;6223:23;6265:18;6306:2;6298:6;6295:14;6292:2;;;6327:6;6319;6312:22;6292:2;6355:61;6408:7;6399:6;6388:9;6384:22;6355:61;:::i;:::-;6345:71;;6469:2;6458:9;6454:18;6441:32;6425:48;;6498:2;6488:8;6485:16;6482:2;;;6519:6;6511;6504:22;6621:699;6748:6;6756;6764;6817:2;6805:9;6796:7;6792:23;6788:32;6785:2;;;6838:6;6830;6823:22;6785:2;6883:9;6870:23;6912:18;6953:2;6945:6;6942:14;6939:2;;;6974:6;6966;6959:22;6939:2;7002:61;7055:7;7046:6;7035:9;7031:22;7002:61;:::i;:::-;6992:71;;7116:2;7105:9;7101:18;7088:32;7072:48;;7145:2;7135:8;7132:16;7129:2;;;7166:6;7158;7151:22;7129:2;;7194:63;7249:7;7238:8;7227:9;7223:24;7194:63;:::i;:::-;7184:73;;;7276:38;7310:2;7299:9;7295:18;7276:38;:::i;:::-;7266:48;;6775:545;;;;;:::o;7325:255::-;7392:6;7445:2;7433:9;7424:7;7420:23;7416:32;7413:2;;;7466:6;7458;7451:22;7413:2;7503:9;7497:16;7522:28;7544:5;7522:28;:::i;7585:255::-;7643:6;7696:2;7684:9;7675:7;7671:23;7667:32;7664:2;;;7717:6;7709;7702:22;7664:2;7761:9;7748:23;7780:30;7804:5;7780:30;:::i;7845:259::-;7914:6;7967:2;7955:9;7946:7;7942:23;7938:32;7935:2;;;7988:6;7980;7973:22;7935:2;8025:9;8019:16;8044:30;8068:5;8044:30;:::i;8109:480::-;8178:6;8231:2;8219:9;8210:7;8206:23;8202:32;8199:2;;;8252:6;8244;8237:22;8199:2;8297:9;8284:23;8330:18;8322:6;8319:30;8316:2;;;8367:6;8359;8352:22;8316:2;8395:22;;8448:4;8440:13;;8436:27;-1:-1:-1;8426:2:28;;8482:6;8474;8467:22;8426:2;8510:73;8575:7;8570:2;8557:16;8552:2;8548;8544:11;8510:73;:::i;8594:190::-;8653:6;8706:2;8694:9;8685:7;8681:23;8677:32;8674:2;;;8727:6;8719;8712:22;8674:2;-1:-1:-1;8755:23:28;;8664:120;-1:-1:-1;8664:120:28:o;8789:258::-;8857:6;8865;8918:2;8906:9;8897:7;8893:23;8889:32;8886:2;;;8939:6;8931;8924:22;8886:2;-1:-1:-1;;8967:23:28;;;9037:2;9022:18;;;9009:32;;-1:-1:-1;8876:171:28:o;9052:659::-;9138:6;9146;9154;9162;9170;9223:3;9211:9;9202:7;9198:23;9194:33;9191:2;;;9245:6;9237;9230:22;9191:2;9286:9;9273:23;9263:33;;9343:2;9332:9;9328:18;9315:32;9305:42;;9397:2;9386:9;9382:18;9369:32;9410:28;9432:5;9410:28;:::i;:::-;9457:5;-1:-1:-1;9514:2:28;9499:18;;9486:32;9527:30;9486:32;9527:30;:::i;:::-;9576:7;-1:-1:-1;9635:3:28;9620:19;;9607:33;9649:30;9607:33;9649:30;:::i;:::-;9698:7;9688:17;;;9181:530;;;;;;;;:::o;9716:437::-;9769:3;9807:5;9801:12;9834:6;9829:3;9822:19;9860:4;9889:2;9884:3;9880:12;9873:19;;9926:2;9919:5;9915:14;9947:3;9959:169;9973:6;9970:1;9967:13;9959:169;;;10034:13;;10022:26;;10068:12;;;;10103:15;;;;9995:1;9988:9;9959:169;;;-1:-1:-1;10144:3:28;;9777:376;-1:-1:-1;;;;;9777:376:28:o;10158:257::-;10199:3;10237:5;10231:12;10264:6;10259:3;10252:19;10280:63;10336:6;10329:4;10324:3;10320:14;10313:4;10306:5;10302:16;10280:63;:::i;:::-;10397:2;10376:15;-1:-1:-1;;10372:29:28;10363:39;;;;10404:4;10359:50;;10207:208;-1:-1:-1;;10207:208:28:o;10885:986::-;11061:3;11090;11125:6;11119:13;11155:36;11181:9;11155:36;:::i;:::-;11210:1;11227:18;;;11254:104;;;;11372:1;11367:362;;;;11220:509;;11254:104;-1:-1:-1;;11287:24:28;;11275:37;;11332:16;;;;-1:-1:-1;11254:104:28;;11367:362;11400:6;11395:3;11388:19;11430:4;11477:2;11472:3;11462:18;11502:3;11518:165;11532:6;11529:1;11526:13;11518:165;;;11610:14;;11597:11;;;11590:35;11653:16;;;;11547:10;;11518:165;;;11522:3;;;11712:6;11707:3;11703:16;11696:23;;11220:509;;;;;11760:6;11754:13;11776:55;11822:8;11817:3;11810:4;11802:6;11798:17;11776:55;:::i;:::-;11847:18;;11069:802;-1:-1:-1;;;;11069:802:28:o;12107:849::-;12429:4;-1:-1:-1;;;;;12539:2:28;12531:6;12527:15;12516:9;12509:34;12591:2;12583:6;12579:15;12574:2;12563:9;12559:18;12552:43;;12631:3;12626:2;12615:9;12611:18;12604:31;12658:57;12710:3;12699:9;12695:19;12687:6;12658:57;:::i;:::-;12763:9;12755:6;12751:22;12746:2;12735:9;12731:18;12724:50;12797:44;12834:6;12826;12797:44;:::i;:::-;12783:58;;12890:9;12882:6;12878:22;12872:3;12861:9;12857:19;12850:51;12918:32;12943:6;12935;12918:32;:::i;:::-;12910:40;12438:518;-1:-1:-1;;;;;;;;12438:518:28:o;12961:583::-;13183:4;-1:-1:-1;;;;;13293:2:28;13285:6;13281:15;13270:9;13263:34;13345:2;13337:6;13333:15;13328:2;13317:9;13313:18;13306:43;;13385:6;13380:2;13369:9;13365:18;13358:34;13428:6;13423:2;13412:9;13408:18;13401:34;13472:3;13466;13455:9;13451:19;13444:32;13493:45;13533:3;13522:9;13518:19;13510:6;13493:45;:::i;:::-;13485:53;13192:352;-1:-1:-1;;;;;;;13192:352:28:o;14531:727::-;14766:2;14818:21;;;14888:13;;14791:18;;;14910:22;;;14737:4;;14766:2;14989:15;;;;14963:2;14948:18;;;14737:4;15035:197;15049:6;15046:1;15043:13;15035:197;;;15098:52;15146:3;15137:6;15131:13;-1:-1:-1;;;;;10510:5:28;10504:12;10500:61;10495:3;10488:74;10611:4;10604:5;10600:16;10594:23;10587:4;10582:3;10578:14;10571:47;10667:4;10660:5;10656:16;10650:23;10643:4;10638:3;10634:14;10627:47;10723:4;10716:5;10712:16;10706:23;10699:4;10694:3;10690:14;10683:47;10793:4;10786:5;10782:16;10776:23;10769:31;10762:39;10755:4;10750:3;10746:14;10739:63;10865:4;10858:5;10854:16;10848:23;10841:31;10834:39;10827:4;10822:3;10818:14;10811:63;10478:402;;;15098:52;15207:15;;;;15179:4;15170:14;;;;;15071:1;15064:9;15035:197;;;-1:-1:-1;15249:3:28;;14746:512;-1:-1:-1;;;;;;14746:512:28:o;15263:261::-;15442:2;15431:9;15424:21;15405:4;15462:56;15514:2;15503:9;15499:18;15491:6;15462:56;:::i;15529:465::-;15786:2;15775:9;15768:21;15749:4;15812:56;15864:2;15853:9;15849:18;15841:6;15812:56;:::i;:::-;15916:9;15908:6;15904:22;15899:2;15888:9;15884:18;15877:50;15944:44;15981:6;15973;15944:44;:::i;:::-;15936:52;15758:236;-1:-1:-1;;;;;15758:236:28:o;16444:219::-;16593:2;16582:9;16575:21;16556:4;16613:44;16653:2;16642:9;16638:18;16630:6;16613:44;:::i;16668:938::-;16777:4;16806:2;16835;16824:9;16817:21;16858:4;16894:6;16888:13;16924:36;16950:9;16924:36;:::i;:::-;16996:6;16991:2;16980:9;16976:18;16969:34;17022:2;17043:1;17075:2;17064:9;17060:18;17092:1;17087:121;;;;17222:1;17217:363;;;;17053:527;;17087:121;-1:-1:-1;;17135:24:28;;17115:18;;;17108:52;17195:2;17180:18;;;-1:-1:-1;17087:121:28;;17217:363;17251:6;17245:4;17238:20;17302:2;17296:4;17286:19;17327:4;17344:180;17358:6;17355:1;17352:13;17344:180;;;17451:14;;17427:17;;;17423:26;;17416:50;17494:16;;;;17373:10;;17344:180;;;17548:17;;17544:26;;;-1:-1:-1;;17053:527:28;-1:-1:-1;17597:3:28;;16786:820;-1:-1:-1;;;;;;;;16786:820:28:o;26254:268::-;26452:3;26437:19;;26465:51;26441:9;26498:6;-1:-1:-1;;;;;10510:5:28;10504:12;10500:61;10495:3;10488:74;10611:4;10604:5;10600:16;10594:23;10587:4;10582:3;10578:14;10571:47;10667:4;10660:5;10656:16;10650:23;10643:4;10638:3;10634:14;10627:47;10723:4;10716:5;10712:16;10706:23;10699:4;10694:3;10690:14;10683:47;10793:4;10786:5;10782:16;10776:23;10769:31;10762:39;10755:4;10750:3;10746:14;10739:63;10865:4;10858:5;10854:16;10848:23;10841:31;10834:39;10827:4;10822:3;10818:14;10811:63;10478:402;;;26962:183;27022:4;27055:18;27047:6;27044:30;27041:2;;;27077:18;;:::i;:::-;-1:-1:-1;27122:1:28;27118:14;27134:4;27114:25;;27031:114::o;27150:128::-;27190:3;27221:1;27217:6;27214:1;27211:13;27208:2;;;27227:18;;:::i;:::-;-1:-1:-1;27263:9:28;;27198:80::o;27283:120::-;27323:1;27349;27339:2;;27354:18;;:::i;:::-;-1:-1:-1;27388:9:28;;27329:74::o;27408:125::-;27448:4;27476:1;27473;27470:8;27467:2;;;27481:18;;:::i;:::-;-1:-1:-1;27518:9:28;;27457:76::o;27538:258::-;27610:1;27620:113;27634:6;27631:1;27628:13;27620:113;;;27710:11;;;27704:18;27691:11;;;27684:39;27656:2;27649:10;27620:113;;;27751:6;27748:1;27745:13;27742:2;;;27786:1;27777:6;27772:3;27768:16;27761:27;27742:2;;27591:205;;;:::o;27801:437::-;27880:1;27876:12;;;;27923;;;27944:2;;27998:4;27990:6;27986:17;27976:27;;27944:2;28051;28043:6;28040:14;28020:18;28017:38;28014:2;;;-1:-1:-1;;;28085:1:28;28078:88;28189:4;28186:1;28179:15;28217:4;28214:1;28207:15;28014:2;;27856:382;;;:::o;28243:249::-;28353:2;28334:13;;-1:-1:-1;;28330:27:28;28318:40;;28388:18;28373:34;;28409:22;;;28370:62;28367:2;;;28435:18;;:::i;:::-;28471:2;28464:22;-1:-1:-1;;28290:202:28:o;28497:135::-;28536:3;-1:-1:-1;;28557:17:28;;28554:2;;;28577:18;;:::i;:::-;-1:-1:-1;28624:1:28;28613:13;;28544:88::o;28637:112::-;28669:1;28695;28685:2;;28700:18;;:::i;:::-;-1:-1:-1;28734:9:28;;28675:74::o;28754:184::-;-1:-1:-1;;;28803:1:28;28796:88;28903:4;28900:1;28893:15;28927:4;28924:1;28917:15;28943:184;-1:-1:-1;;;28992:1:28;28985:88;29092:4;29089:1;29082:15;29116:4;29113:1;29106:15;29132:184;-1:-1:-1;;;29181:1:28;29174:88;29281:4;29278:1;29271:15;29305:4;29302:1;29295:15;29321:185;29356:3;29398:1;29380:16;29377:23;29374:2;;;29448:1;29443:3;29438;29423:27;29479:10;29474:3;29470:20;29374:2;29364:142;:::o;29511:671::-;29550:3;29592:4;29574:16;29571:26;29568:2;;;29558:624;:::o;29568:2::-;29634;29628:9;-1:-1:-1;;29699:16:28;29695:25;;29692:1;29628:9;29671:50;29750:4;29744:11;29774:16;29809:18;29880:2;29873:4;29865:6;29861:17;29858:25;29853:2;29845:6;29842:14;29839:45;29836:2;;;29887:5;;;;;29558:624;:::o;29836:2::-;29924:6;29918:4;29914:17;29903:28;;29960:3;29954:10;29987:2;29979:6;29976:14;29973:2;;;29993:5;;;;;;29558:624;:::o;29973:2::-;30077;30058:16;30052:4;30048:27;30044:36;30037:4;30028:6;30023:3;30019:16;30015:27;30012:69;30009:2;;;30084:5;;;;;;29558:624;:::o;30009:2::-;30100:57;30151:4;30142:6;30134;30130:19;30126:30;30120:4;30100:57;:::i;:::-;-1:-1:-1;30173:3:28;;29558:624;-1:-1:-1;;;;;29558:624:28:o;30187:118::-;30273:5;30266:13;30259:21;30252:5;30249:32;30239:2;;30295:1;30292;30285:12;30310:177;-1:-1:-1;;;;;;30388:5:28;30384:78;30377:5;30374:89;30364:2;;30477:1;30474;30467:12

Swarm Source

none
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.