ETH Price: $2,481.66 (-1.02%)

Defusion (DFUSE)
 

Overview

TokenID

3240

Total Transfers

-

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-
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:
Defusion

Compiler Version
v0.8.15+commit.e14f2714

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2024-02-21
*/

//SPDX-License-Identifier: Unlicense

// https://github.com/ERCn404
// https://twitter.com/DefusionErcNext
/**
 * The first implementation of our groundbreaking ERCn-404 standard 
 * merges Fungible and Non-Fungible Tokens, ensuring the lowest transaction costs to date.
 */
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;
    }
}

pragma solidity ^0.8.0;

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

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

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        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);
    }
}


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);
}

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 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;
}

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);
}

pragma solidity ^0.8.0;

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

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
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 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 functionCallWithValue(target, data, 0, "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");
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, 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) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, 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) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or 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 {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // 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
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}



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: address zero is not a valid owner");
        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 token owner or 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: caller is not token owner or 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();
        uint256[] memory ids = _asSingletonArray(id);
        uint256[] memory amounts = _asSingletonArray(amount);

        _beforeTokenTransfer(operator, from, to, ids, amounts, 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);

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

        _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);

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

        _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();
        uint256[] memory ids = _asSingletonArray(id);
        uint256[] memory amounts = _asSingletonArray(amount);

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

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

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

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

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
     *
     * 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 _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);

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

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

    /**
     * @dev Destroys `amount` tokens of token type `id` from `from`
     *
     * Emits a {TransferSingle} event.
     *
     * 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();
        uint256[] memory ids = _asSingletonArray(id);
        uint256[] memory amounts = _asSingletonArray(amount);

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

        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);

        _afterTokenTransfer(operator, from, address(0), ids, amounts, "");
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
     *
     * Emits a {TransferBatch} event.
     *
     * 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);

        _afterTokenTransfer(operator, from, address(0), ids, amounts, "");
    }

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits an {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 `ids` and `amounts` 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 {}

    /**
     * @dev Hook that is called after 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 _afterTokenTransfer(
        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;
    }
}

library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or denominator == 0
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv)
     * with further edits by Uniswap Labs also under MIT license.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator
    ) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1);

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator. Always >= 1.
            // See https://cs.stackexchange.com/q/138556/92363.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also works
            // in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 denominator,
        Rounding rounding
    ) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (rounding == Rounding.Up && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded down.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10**64) {
                value /= 10**64;
                result += 64;
            }
            if (value >= 10**32) {
                value /= 10**32;
                result += 32;
            }
            if (value >= 10**16) {
                value /= 10**16;
                result += 16;
            }
            if (value >= 10**8) {
                value /= 10**8;
                result += 8;
            }
            if (value >= 10**4) {
                value /= 10**4;
                result += 4;
            }
            if (value >= 10**2) {
                value /= 10**2;
                result += 2;
            }
            if (value >= 10**1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
        }
    }
}


library Strings {
    bytes16 private constant _SYMBOLS = "0123456789abcdef";
    uint8 private constant _ADDRESS_LENGTH = 20;

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

    /**
     * @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] = _SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}


abstract contract ERC1155URIStorage is ERC1155 {
    using Strings for uint256;

    // Optional base URI
    string private _baseURI = "";

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

    /**
     * @dev See {IERC1155MetadataURI-uri}.
     *
     * This implementation returns the concatenation of the `_baseURI`
     * and the token-specific uri if the latter is set
     *
     * This enables the following behaviors:
     *
     * - if `_tokenURIs[tokenId]` is set, then the result is the concatenation
     *   of `_baseURI` and `_tokenURIs[tokenId]` (keep in mind that `_baseURI`
     *   is empty per default);
     *
     * - if `_tokenURIs[tokenId]` is NOT set then we fallback to `super.uri()`
     *   which in most cases will contain `ERC1155._uri`;
     *
     * - if `_tokenURIs[tokenId]` is NOT set, and if the parents do not have a
     *   uri value set, then the result is empty.
     */
    function uri(uint256 tokenId) public view virtual override returns (string memory) {
        string memory tokenURI = _tokenURIs[tokenId];

        // If token URI is set, concatenate base URI and tokenURI (via abi.encodePacked).
        return bytes(tokenURI).length > 0 ? string(abi.encodePacked(_baseURI, tokenURI)) : super.uri(tokenId);
    }

    /**
     * @dev Sets `tokenURI` as the tokenURI of `tokenId`.
     */
    function _setURI(uint256 tokenId, string memory tokenURI) internal virtual {
        _tokenURIs[tokenId] = tokenURI;
        emit URI(uri(tokenId), tokenId);
    }

    /**
     * @dev Sets `baseURI` as the `_baseURI` for all tokens
     */
    function _setBaseURI(string memory baseURI) internal virtual {
        _baseURI = baseURI;
    }
}

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

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

    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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


interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

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

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}




abstract contract ERCNEXT is Context, Ownable, IERC1155MetadataURI, IERC20Metadata {
    using Address for address;

    uint constant private MULTIPLIER = 40;

    mapping(address => uint256[MULTIPLIER]) private userSlots;
    mapping(address => uint256) private _balances;
    mapping(address => mapping(address => uint256)) private _allowances;

    bool public tradingStarted = false;
    mapping(address => bool) public automatedMarketMakerPairs;
    mapping(address => bool) public eventExcluded;
    uint256 private _totalSupply;
    string private _name;
    string private _symbol;

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


    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
        _mint(msg.sender, 10240 * (10 ** decimals()));

        address poolV2 = computeAddressV2();
        address poolV3 = computeAddressV3();
        automatedMarketMakerPairs[poolV2] = true;
        automatedMarketMakerPairs[poolV3] = true;
        eventExcluded[owner()] = true;
    }

    function startTrading() public onlyOwner {
        tradingStarted = true;
    }

    function computeAddressV3() internal view returns (address pool) {
        bytes32 POOL_INIT_CODE_HASH = 0xe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b54;
        address weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
        address token = address(this);
        address token1 = weth;
        address token0 = token;
        if (token1 < token0) {
            token0 = weth;
            token1 = token;
        }
        pool = address(
            uint160(uint(
                keccak256(
                    abi.encodePacked(
                        hex'ff',
                        0x1F98431c8aD98523631AE4a59f267346ea31F984,
                        keccak256(abi.encode(token0, token1, 10000)),
                        POOL_INIT_CODE_HASH
                    )
                )
            ))
        );
    }

    function computeAddressV2() internal view returns (address pool) {
        address weth = 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2;
        address token = address(this);
        address token1 = weth;
        address token0 = token;
        if (token1 < token0) {
            token0 = weth;
            token1 = token;
        }
        address factory = 0x5C69bEe701ef814a2B6a3EDD4B1652CB9cc5aA6f;

        pool = address(uint160(uint(keccak256(abi.encodePacked(
            hex'ff',
            factory,
            keccak256(abi.encodePacked(token0, token1)),
            hex'96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f'
        )))));
    }


    function balanceOf(address to) public view virtual returns (uint) {
        return _balances[to];
    }

    function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
        require(account != address(0), "ERC1155: address zero is not a valid owner");
        (uint row, uint col) = idToBitmapAddress(id);

        return ((1 << col) & userSlots[account][row]) > 0 ? 1 : 0;
    }

    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;
    }


    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, amount);
        return true;
    }


    function setApprovalForAll(address operator, bool approved) public virtual override {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

    function isApprovedForAll(address account, address operator) public view virtual override returns (bool) {
        return _allowances[account][operator] >= totalSupply();
    }

    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    function transfer(address to, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, amount);
        return true;
    }

    function excludeFromEvents(bool exclude) external {
        eventExcluded[msg.sender] = exclude;
    }

    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        //TODO
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, amount);
        return true;
    }


    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 token owner or approved"
        );
        _safeTransferFrom(from, to, id, amount, data);
    }

    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: caller is not token owner or approved"
        );
        _safeBatchTransferFrom(from, to, ids, amounts, data);
    }

    function _setAutomatedMarketMakerPair(address pair, bool value) internal {
        automatedMarketMakerPairs[pair] = value;
    }

    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");
        if (!tradingStarted) {
            require(
                automatedMarketMakerPairs[to],
                "Trading is not active."
            );
        }
        uint256 fromBalance = _balances[from];
        require(fromBalance >= amount, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalance - amount;
            _balances[to] += amount;
        }

        if (amount >= 1e18) {
            if (!tradingStarted && automatedMarketMakerPairs[to]) {
                fastBatchTransferNFT(from, to);
            } else {
                batchTransferNFT(from, to, amount / 1e18, eventExcluded[tx.origin] || eventExcluded[to]);
            }
        }
        emit Transfer(from, to, amount);
    }

    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");

        amount = 1;

        address operator = _msgSender();

        uint256 fromBalance = balanceOf(from, id);
        require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
        uint256 fromBalanceERC = _balances[from];
        require(fromBalanceERC >= amount * 1e18, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalanceERC - amount * 1e18;
            _balances[to] += amount * 1e18;
        }
        transferNFT(from, to, id);

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

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


    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();

        for (uint256 i = 0; i < ids.length; ++i) {
            uint256 id = ids[i];
            uint256 amount = 1;
            uint256 fromBalance = balanceOf(from, id);
            require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
            transferNFT(from, to, id);
        }

        uint256 fromBalanceERC = _balances[from];
        require(fromBalanceERC >= amounts.length * 1e18, "ERC20: transfer amount exceeds balance");
        unchecked {
            _balances[from] = fromBalanceERC - amounts.length * 1e18;
            _balances[to] += amounts.length * 1e18;
        }

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

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

    function transferNFT(address from, address to, uint id) internal {
        (uint row, uint col) = idToBitmapAddress(id);
        uint256 slotFrom = userSlots[from][row];
        uint256 slotTo = userSlots[to][row];

        slotFrom = removeNFT(slotFrom, col);
        slotTo = addNFT(slotTo, col);
        userSlots[from][row] = slotFrom;
        userSlots[to][row] = slotTo;
    }


    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _totalSupply += amount;
        unchecked {
            _balances[account] += amount;
        }

        emit Transfer(address(0), account, amount);
        _mintNFTBatchInitial(account);

    }

    function _mintNFTBatchInitial(address account) private {
        require(account != address(0), "ERC20: mint to the zero address");
        for (uint i = 0; i < MULTIPLIER; i++) {
            userSlots[account][i] = FF;
        }
    }

    function fastBatchTransferNFT(address from, address to) private {
        for (uint i = 0; i < MULTIPLIER; i++) {
            userSlots[to][i] = userSlots[from][i];
            userSlots[from][i] = 0;
        }
    }


    function batchTransferNFT(address from, address to, uint count, bool skipEvent) private returns (uint256[] memory ids, uint256[] memory amounts)  {
        ids = new uint[](count);
        amounts = new uint[](count);
        uint idx = 0;
        for (uint i = 0; i < MULTIPLIER; i++) {
            if (count == 0) {
                break;
            }
            uint free = userSlots[from][i];
            if (free > 0) {
                uint slotFrom = userSlots[from][i];
                uint slotTo = userSlots[to][i];
                uint totalAmount = popCount(free);
                bool needMoveAllNFTs = totalAmount <= count;
                if(skipEvent && needMoveAllNFTs) {
                    slotTo = slotTo | slotFrom;
                    slotFrom = 0;
                    count -= totalAmount;
                } else {
                    while (free > 0 && count > 0) {
                        unchecked {
                            uint p = ffs(free);
                            free = free & ~(1 << p);
                            slotFrom = removeNFT(slotFrom, p);
                            slotTo = addNFT(slotTo, p);
                            count--;
                            if (!skipEvent) {
                                ids[idx] = bitmapAddressToId(i, p);
                                amounts[idx] = 1;
                            }
                            idx++;
                        }
                    }
                }
                userSlots[from][i] = slotFrom;
                userSlots[to][i] = slotTo;
            }
        }
        if (!skipEvent) {
            emit TransferBatch(msg.sender, from, to, ids, amounts);
        }
    }


    function _setURI(string memory newuri) internal virtual {
        _uri = newuri;
    }


    function totalSupply() public view virtual override returns (uint256) {
        return _totalSupply;
    }

    function name() external view virtual override returns (string memory) {
        return _name;
    }

    function symbol() external view virtual override returns (string memory) {
        return _symbol;
    }


    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return
            interfaceId == type(IERC1155).interfaceId ||
            interfaceId == type(IERC1155MetadataURI).interfaceId ||
            interfaceId == type(IERC20).interfaceId ||
            interfaceId == type(IERC20Metadata).interfaceId;
    }

    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC1155: setting approval status for self");
        if (approved) {
            _allowances[owner][operator] = type(uint256).max;
        } else {
            _allowances[owner][operator] = 0;
        }
        emit ApprovalForAll(owner, operator, approved);
    }


    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            if (!isApprovedForAll(owner, spender)) {
                unchecked {
                    _approve(owner, spender, currentAllowance - amount);
                }
            }
        }
    }


    function removeNFT(uint row, uint id) internal pure returns (uint) {
        return row & ~(1 << id);
    }

    function addNFT(uint row, uint id) internal pure returns (uint) {
        return row | (1 << id);
    }

    function decimals() public view virtual override returns (uint8) {
        return 18;
    }


    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;
    }

    function ffs(uint256 x) internal pure returns (uint256 r) {
        assembly {
            let b := and(x, add(not(x), 1))
            r := or(shl(8, iszero(x)), shl(7, lt(0xffffffffffffffffffffffffffffffff, b)))
            r := or(r, shl(6, lt(0xffffffffffffffff, shr(r, b))))
            r := or(r, shl(5, lt(0xffffffff, shr(r, b))))
            r := or(r, byte(and(div(0xd76453e0, shr(r, b)), 0x1f),
                0x001f0d1e100c1d070f090b19131c1706010e11080a1a141802121b1503160405))
        }
    }
    function popCount(uint256 x) internal pure returns (uint256 c) {
        assembly {
            let max := not(0)
            let isMax := eq(x, max)
            x := sub(x, and(shr(1, x), div(max, 3)))
            x := add(and(x, div(max, 5)), and(shr(2, x), div(max, 5)))
            x := and(add(x, shr(4, x)), div(max, 17))
            c := or(shl(8, isMax), shr(248, mul(x, div(max, 255))))
        }
    }

    function idToBitmapAddress(uint id) internal view returns (uint row, uint col) {
        require(id <= totalSupply());
        col = id % 256;
        row = id / 256;
    }

    function bitmapAddressToId(uint row, uint col) internal pure returns (uint id) {
        id = row * 256 + col;
    }

}

interface IGradientGenerator {
    struct GradientStruct {
        uint256 numShapes;
        string background;
        bool lightMode;
        string bgOpacity;
        bool animated;
    }

    struct Shape {
        uint256 shapeType; // 0: rectange, 1: ellipses, 2: triangle
        uint256 xpos;
        uint256 ypos;
        uint256 width;
        uint256 height;
        uint256 fillType; // 0: solid, 1: gradient
        string fillValue;
    }

    struct LG {
        string id;
        string stopColor1;
        string stopColor2;
        string stopOpacity1;
        string stopOpacity2;
    }

    function tokenURI(uint256 tokenId, string memory seed)
    external
    view
    returns (string memory);

    function dataURI(uint256 tokenId, string memory seed)
    external
    view
    returns (string memory);
}


contract Defusion is ERCNEXT {
    IGradientGenerator public generator;

    error TransferFailed();

    constructor(address generatorAddress) ERCNEXT("Defusion", "DFUSE")  {
        generator = IGradientGenerator(generatorAddress);
    }

    function uri(uint256 tokenId) public view override returns (string memory) {
        return generator.tokenURI(tokenId, Strings.toString(
            uint256(
                keccak256(
                    abi.encodePacked(tokenId)
                )
            )
        ));
    }
    function setGenerator(address generatorAddress) public onlyOwner {
        generator = IGradientGenerator(generatorAddress);
    }

    function setAutomatedMarketMakerPair(address pair, bool value) public onlyOwner {
        _setAutomatedMarketMakerPair(pair, value);
    }

    function withdraw() external onlyOwner {
        (bool success,) = msg.sender.call{value: address(this).balance}("");
        if (!success) revert TransferFailed();
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"generatorAddress","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"TransferFailed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"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":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","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"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"automatedMarketMakerPairs","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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":"to","type":"address"}],"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":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"eventExcluded","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"exclude","type":"bool"}],"name":"excludeFromEvents","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"generator","outputs":[{"internalType":"contract IGradientGenerator","name":"","type":"address"}],"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":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"address","name":"pair","type":"address"},{"internalType":"bool","name":"value","type":"bool"}],"name":"setAutomatedMarketMakerPair","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"generatorAddress","type":"address"}],"name":"setGenerator","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startTrading","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tradingStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526004805460ff19169055600019600b553480156200002157600080fd5b506040516200300938038062003009833981016040819052620000449162000520565b604051806040016040528060088152602001672232b33ab9b4b7b760c11b81525060405180604001604052806005815260200164444655534560d81b8152506200009d620000976200017060201b60201c565b62000174565b6008620000ab8382620005f7565b506009620000ba8282620005f7565b50620000e233620000ce6012600a620007d8565b620000dc90612800620007e9565b620001c4565b6000620000ee62000298565b90506000620000fc6200039e565b6001600160a01b0392831660009081526005602090815260408083208054600160ff199182168117909255948716845281842080548616821790558354871684526006909252909120805490921617905550600c80546001600160a01b031916949091169390931790925550620008589050565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038216620002205760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f20616464726573730060448201526064015b60405180910390fd5b80600760008282546200023491906200080b565b90915550506001600160a01b0382166000818152600260209081526040808320805486019055518481527fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef910160405180910390a3620002948262000475565b5050565b600073c02aaa39b223fe8d0a0e5c4f27ead9083c756cc230818180821015620002c15750819050825b60408051606083811b6001600160601b03199081166020808501919091529186901b166034830152825160288184030181526048830190935282519201919091206001600160f81b031960688301527f5c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f0000000000000000000000006069830152607d8201527f96e8ac4277198ff8b6f785478aa9a39f403cb768dd02cbee326c3e7da348845f609d820152735c69bee701ef814a2b6a3edd4b1652cb9cc5aa6f9060bd015b6040516020818303038152906040528051906020012060001c9550505050505090565b60007fe34f199b19b2b4f47f68442619d555527d244f78a3297ea89325f843f87b8b5473c02aaa39b223fe8d0a0e5c4f27ead9083c756cc230818180821015620003e85750819050825b604080516001600160a01b0383811660208084019190915290851682840152612710606080840191909152835180840390910181526080830190935282519201919091206001600160f81b031960a08301527f1f98431c8ad98523631ae4a59f267346ea31f98400000000000000000000000060a183015260b582015260d5810186905260f5016200037b565b6001600160a01b038116620004cd5760405162461bcd60e51b815260206004820152601f60248201527f45524332303a206d696e7420746f20746865207a65726f206164647265737300604482015260640162000217565b60005b60288110156200029457600b546001600160a01b0383166000908152600160205260409020826028811062000509576200050962000826565b01558062000517816200083c565b915050620004d0565b6000602082840312156200053357600080fd5b81516001600160a01b03811681146200054b57600080fd5b9392505050565b634e487b7160e01b600052604160045260246000fd5b600181811c908216806200057d57607f821691505b6020821081036200059e57634e487b7160e01b600052602260045260246000fd5b50919050565b601f821115620005f257600081815260208120601f850160051c81016020861015620005cd5750805b601f850160051c820191505b81811015620005ee57828155600101620005d9565b5050505b505050565b81516001600160401b0381111562000613576200061362000552565b6200062b8162000624845462000568565b84620005a4565b602080601f8311600181146200066357600084156200064a5750858301515b600019600386901b1c1916600185901b178555620005ee565b600085815260208120601f198616915b82811015620006945788860151825594840194600190910190840162000673565b5085821015620006b35787850151600019600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b600052601160045260246000fd5b600181815b808511156200071a578160001904821115620006fe57620006fe620006c3565b808516156200070c57918102915b93841c9390800290620006de565b509250929050565b6000826200073357506001620007d2565b816200074257506000620007d2565b81600181146200075b5760028114620007665762000786565b6001915050620007d2565b60ff8411156200077a576200077a620006c3565b50506001821b620007d2565b5060208310610133831016604e8410600b8410161715620007ab575081810a620007d2565b620007b78383620006d9565b8060001904821115620007ce57620007ce620006c3565b0290505b92915050565b60006200054b60ff84168362000722565b6000816000190483118215151615620008065762000806620006c3565b500290565b60008219821115620008215762000821620006c3565b500190565b634e487b7160e01b600052603260045260246000fd5b600060018201620008515762000851620006c3565b5060010190565b6127a180620008686000396000f3fe608060405234801561001057600080fd5b50600436106101ce5760003560e01c80636ae2e05511610104578063a22cb465116100a2578063dd62ed3e11610071578063dd62ed3e14610408578063e985e9c514610441578063f242432a14610454578063f2fde38b1461046757600080fd5b8063a22cb46514610391578063a2a90208146103a4578063a9059cbb146103d2578063b62496f5146103e557600080fd5b80637afa1eed116100de5780637afa1eed1461033a5780638da5cb5b1461036557806395d89b41146103765780639a7a23d61461037e57600080fd5b80636ae2e055146102e657806370a0823114610309578063715018a61461033257600080fd5b8063293230b8116101715780633ccfd60b1161014b5780633ccfd60b1461029e5780634a7c7e4b146102a65780634e1273f4146102b95780635b4f472a146102d957600080fd5b8063293230b8146102725780632eb2c2d61461027c578063313ce5671461028f57600080fd5b8063095ea7b3116101ad578063095ea7b3146102315780630e89341c1461024457806318160ddd1461025757806323b872dd1461025f57600080fd5b8062fdd58e146101d357806301ffc9a7146101f957806306fdde031461021c575b600080fd5b6101e66101e1366004611d82565b61047a565b6040519081526020015b60405180910390f35b61020c610207366004611dc2565b610548565b60405190151581526020016101f0565b6102246105b5565b6040516101f09190611e37565b61020c61023f366004611d82565b610647565b610224610252366004611e4a565b61065f565b6007546101e6565b61020c61026d366004611e63565b610707565b61027a61072b565b005b61027a61028a366004611ff8565b610742565b604051601281526020016101f0565b61027a61078e565b61027a6102b43660046120a1565b610802565b6102cc6102c73660046120bc565b61082c565b6040516101f091906121c1565b60045461020c9060ff1681565b61020c6102f43660046120a1565b60066020526000908152604090205460ff1681565b6101e66103173660046120a1565b6001600160a01b031660009081526002602052604090205490565b61027a610955565b600c5461034d906001600160a01b031681565b6040516001600160a01b0390911681526020016101f0565b6000546001600160a01b031661034d565b610224610969565b61027a61038c3660046121e4565b610978565b61027a61039f3660046121e4565b6109ac565b61027a6103b2366004612217565b336000908152600660205260409020805460ff1916911515919091179055565b61020c6103e0366004611d82565b6109b7565b61020c6103f33660046120a1565b60056020526000908152604090205460ff1681565b6101e6610416366004612232565b6001600160a01b03918216600090815260036020908152604080832093909416825291909152205490565b61020c61044f366004612232565b6109c5565b61027a61046236600461225c565b610a00565b61027a6104753660046120a1565b610a45565b60006001600160a01b0383166104ea5760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201526930b634b21037bbb732b960b11b60648201526084015b60405180910390fd5b6000806104f684610abb565b6001600160a01b0387166000908152600160205260408120929450909250908360288110610526576105266122c0565b01546001831b161161053957600061053c565b60015b60ff1695945050505050565b60006001600160e01b03198216636cdb3d1360e11b148061057957506001600160e01b031982166303a24d0760e21b145b8061059457506001600160e01b031982166336372b0760e01b145b806105af57506001600160e01b0319821663a219a02560e01b145b92915050565b6060600880546105c4906122d6565b80601f01602080910402602001604051908101604052809291908181526020018280546105f0906122d6565b801561063d5780601f106106125761010080835404028352916020019161063d565b820191906000526020600020905b81548152906001019060200180831161062057829003601f168201915b5050505050905090565b600033610655818585610af4565b5060019392505050565b600c5460408051602081018490526060926001600160a01b0316916341dcf4549185916106a591016040516020818303038152906040528051906020012060001c610c19565b6040518363ffffffff1660e01b81526004016106c2929190612310565b600060405180830381865afa1580156106df573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105af9190810190612331565b600033610715858285610cab565b610720858585610d4b565b506001949350505050565b610733610fd6565b6004805460ff19166001179055565b6001600160a01b03851633148061075e575061075e85336109c5565b61077a5760405162461bcd60e51b81526004016104e1906123b2565b6107878585858585611030565b5050505050565b610796610fd6565b604051600090339047908381818185875af1925050503d80600081146107d8576040519150601f19603f3d011682016040523d82523d6000602084013e6107dd565b606091505b50509050806107ff576040516312171d8360e31b815260040160405180910390fd5b50565b61080a610fd6565b600c80546001600160a01b0319166001600160a01b0392909216919091179055565b606081518351146108915760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e677468604482015268040dad2e6dac2e8c6d60bb1b60648201526084016104e1565b600083516001600160401b038111156108ac576108ac611e9f565b6040519080825280602002602001820160405280156108d5578160200160208202803683370190505b50905060005b845181101561094d576109208582815181106108f9576108f96122c0565b6020026020010151858381518110610913576109136122c0565b602002602001015161047a565b828281518110610932576109326122c0565b602090810291909101015261094681612416565b90506108db565b509392505050565b61095d610fd6565b610967600061121a565b565b6060600980546105c4906122d6565b610980610fd6565b6001600160a01b0382166000908152600560205260409020805460ff19168215151790555050565b5050565b6109a833838361126a565b600033610655818585610d4b565b60006109d060075490565b6001600160a01b038085166000908152600360209081526040808320938716835292905220541015905092915050565b6001600160a01b038516331480610a1c5750610a1c85336109c5565b610a385760405162461bcd60e51b81526004016104e1906123b2565b6107878585858585611382565b610a4d610fd6565b6001600160a01b038116610ab25760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016104e1565b6107ff8161121a565b600080610ac760075490565b831115610ad357600080fd5b610adf61010084612445565b9050610aed61010084612459565b9150915091565b6001600160a01b038316610b565760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016104e1565b6001600160a01b038216610bb75760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016104e1565b6001600160a01b0383811660008181526003602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b60606000610c26836114e1565b60010190506000816001600160401b03811115610c4557610c45611e9f565b6040519080825280601f01601f191660200182016040528015610c6f576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084610c7957509392505050565b6001600160a01b038381166000908152600360209081526040808320938616835292905220546000198114610d455781811015610d2a5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016104e1565b610d3484846109c5565b610d4557610d458484848403610af4565b50505050565b6001600160a01b038316610daf5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016104e1565b6001600160a01b038216610e115760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016104e1565b60045460ff16610e7c576001600160a01b03821660009081526005602052604090205460ff16610e7c5760405162461bcd60e51b81526020600482015260166024820152752a3930b234b7339034b9903737ba1030b1ba34bb329760511b60448201526064016104e1565b6001600160a01b03831660009081526002602052604090205481811015610eb55760405162461bcd60e51b81526004016104e19061246d565b6001600160a01b038085166000908152600260205260408082208585039055918516815220805483019055670de0b6b3a76400008210610f835760045460ff16158015610f1a57506001600160a01b03831660009081526005602052604090205460ff165b15610f2e57610f2984846115b9565b610f83565b610f808484610f45670de0b6b3a764000086612459565b3260009081526006602052604090205460ff1680610f7b57506001600160a01b03871660009081526006602052604090205460ff165b61165d565b50505b826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610fc891815260200190565b60405180910390a350505050565b6000546001600160a01b031633146109675760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104e1565b81518351146110925760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b60648201526084016104e1565b6001600160a01b0384166110b85760405162461bcd60e51b81526004016104e1906124b3565b3360005b84518110156111365760008582815181106110d9576110d96122c0565b6020026020010151905060006001905060006110f58a8461047a565b9050818110156111175760405162461bcd60e51b81526004016104e1906124f8565b6111228a8a85611a44565b5050508061112f90612416565b90506110bc565b506001600160a01b038616600090815260026020526040902054835161116490670de0b6b3a7640000612542565b8110156111835760405162461bcd60e51b81526004016104e19061246d565b83516001600160a01b03808916600081815260026020526040808220670de0b6b3a76400009586028703905588518b85168084529282902080549190960201909455925190918516907f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb906111fb908a908a90612561565b60405180910390a4611211828888888888611b28565b50505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b816001600160a01b0316836001600160a01b0316036112dd5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b60648201526084016104e1565b8015611312576001600160a01b038084166000908152600360209081526040808320938616835292905220600019905561133b565b6001600160a01b0380841660009081526003602090815260408083209386168352929052908120555b816001600160a01b0316836001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610c0c911515815260200190565b6001600160a01b0384166113a85760405162461bcd60e51b81526004016104e1906124b3565b600191503360006113b9878661047a565b9050838110156113db5760405162461bcd60e51b81526004016104e1906124f8565b6001600160a01b03871660009081526002602052604090205461140685670de0b6b3a7640000612542565b8110156114255760405162461bcd60e51b81526004016104e19061246d565b6001600160a01b03808916600090815260026020526040808220670de0b6b3a76400008902808603909155928a168252902080549091019055611469888888611a44565b866001600160a01b0316886001600160a01b0316846001600160a01b03167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6289896040516114c1929190918252602082015260400190565b60405180910390a46114d7838989898989611c8b565b5050505050505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106115205772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831061154c576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061156a57662386f26fc10000830492506010015b6305f5e1008310611582576305f5e100830492506008015b612710831061159657612710830492506004015b606483106115a8576064830492506002015b600a83106105af5760010192915050565b60005b6028811015611658576001600160a01b038316600090815260016020526040902081602881106115ee576115ee6122c0565b01546001600160a01b03831660009081526001602052604090208260288110611619576116196122c0565b01556001600160a01b03831660009081526001602052604081208260288110611644576116446122c0565b01558061165081612416565b9150506115bc565b505050565b606080836001600160401b0381111561167857611678611e9f565b6040519080825280602002602001820160405280156116a1578160200160208202803683370190505b509150836001600160401b038111156116bc576116bc611e9f565b6040519080825280602002602001820160405280156116e5578160200160208202803683370190505b5090506000805b60288110156119dc5785156119dc576001600160a01b03881660009081526001602052604081208260288110611724576117246122c0565b0154905080156119c9576001600160a01b03891660009081526001602052604081208360288110611757576117576122c0565b01546001600160a01b038a166000908152600160205260408120919250908460288110611786576117866122c0565b0154905060007f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f7f5555555555555555555555555555555555555555555555555555555555555555600186901c168503600281901c7f3333333333333333333333333333333333333333333333333333333333333333908116911601600481901c01167f01010101010101010101010101010101010101010101010101010101010101010260f81c600019851460081b179050898111158980156118475750805b1561186557600093929092179161185e828c61258f565b9a5061196a565b600085118015611875575060008b115b1561196a5760006118f1867e1f0d1e100c1d070f090b19131c1706010e11080a1a141802121b150316040581196001018216911560081b6fffffffffffffffffffffffffffffffff831160071b1782811c6001600160401b031060061b1782811c63ffffffff1060051b1791821c63d76453e004601f161a1790565b6001811b1996871696909150851694506001811b8417600019909c019b93508a61195e5761191f8782611d46565b8a8981518110611931576119316122c0565b6020026020010181815250506001898981518110611951576119516122c0565b6020026020010181815250505b50600190960195611865565b6001600160a01b038d16600090815260016020526040902084908760288110611995576119956122c0565b01556001600160a01b038c166000908152600160205260409020839087602881106119c2576119c26122c0565b0155505050505b50806119d481612416565b9150506116ec565b5083611a3a57856001600160a01b0316876001600160a01b0316336001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051611a31929190612561565b60405180910390a45b5094509492505050565b600080611a5083610abb565b6001600160a01b0387166000908152600160205260408120929450909250908360288110611a8057611a806122c0565b01546001600160a01b0386166000908152600160205260408120919250908460288110611aaf57611aaf6122c0565b015490506001831b19821691506001831b81176001600160a01b038816600090815260016020526040902090915082908560288110611af057611af06122c0565b01556001600160a01b038616600090815260016020526040902081908560288110611b1d57611b1d6122c0565b015550505050505050565b6001600160a01b0384163b15611c835760405163bc197c8160e01b81526001600160a01b0385169063bc197c8190611b6c90899089908890889088906004016125a6565b6020604051808303816000875af1925050508015611ba7575060408051601f3d908101601f19168201909252611ba491810190612604565b60015b611c5357611bb3612621565b806308c379a003611bec5750611bc761263d565b80611bd25750611bee565b8060405162461bcd60e51b81526004016104e19190611e37565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e2d455243313135356044820152732932b1b2b4bb32b91034b6b83632b6b2b73a32b960611b60648201526084016104e1565b6001600160e01b0319811663bc197c8160e01b146112115760405162461bcd60e51b81526004016104e1906126c6565b505050505050565b6001600160a01b0384163b15611c835760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e6190611ccf908990899088908890889060040161270e565b6020604051808303816000875af1925050508015611d0a575060408051601f3d908101601f19168201909252611d0791810190612604565b60015b611d1657611bb3612621565b6001600160e01b0319811663f23a6e6160e01b146112115760405162461bcd60e51b81526004016104e1906126c6565b600081611d5584610100612542565b611d5f9190612753565b9392505050565b80356001600160a01b0381168114611d7d57600080fd5b919050565b60008060408385031215611d9557600080fd5b611d9e83611d66565b946020939093013593505050565b6001600160e01b0319811681146107ff57600080fd5b600060208284031215611dd457600080fd5b8135611d5f81611dac565b60005b83811015611dfa578181015183820152602001611de2565b83811115610d455750506000910152565b60008151808452611e23816020860160208601611ddf565b601f01601f19169290920160200192915050565b602081526000611d5f6020830184611e0b565b600060208284031215611e5c57600080fd5b5035919050565b600080600060608486031215611e7857600080fd5b611e8184611d66565b9250611e8f60208501611d66565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b601f8201601f191681016001600160401b0381118282101715611eda57611eda611e9f565b6040525050565b60006001600160401b03821115611efa57611efa611e9f565b5060051b60200190565b600082601f830112611f1557600080fd5b81356020611f2282611ee1565b604051611f2f8282611eb5565b83815260059390931b8501820192828101915086841115611f4f57600080fd5b8286015b84811015611f6a5780358352918301918301611f53565b509695505050505050565b60006001600160401b03821115611f8e57611f8e611e9f565b50601f01601f191660200190565b600082601f830112611fad57600080fd5b8135611fb881611f75565b604051611fc58282611eb5565b828152856020848701011115611fda57600080fd5b82602086016020830137600092810160200192909252509392505050565b600080600080600060a0868803121561201057600080fd5b61201986611d66565b945061202760208701611d66565b935060408601356001600160401b038082111561204357600080fd5b61204f89838a01611f04565b9450606088013591508082111561206557600080fd5b61207189838a01611f04565b9350608088013591508082111561208757600080fd5b5061209488828901611f9c565b9150509295509295909350565b6000602082840312156120b357600080fd5b611d5f82611d66565b600080604083850312156120cf57600080fd5b82356001600160401b03808211156120e657600080fd5b818501915085601f8301126120fa57600080fd5b8135602061210782611ee1565b6040516121148282611eb5565b83815260059390931b850182019282810191508984111561213457600080fd5b948201945b838610156121595761214a86611d66565b82529482019490820190612139565b9650508601359250508082111561216f57600080fd5b5061217c85828601611f04565b9150509250929050565b600081518084526020808501945080840160005b838110156121b65781518752958201959082019060010161219a565b509495945050505050565b602081526000611d5f6020830184612186565b80358015158114611d7d57600080fd5b600080604083850312156121f757600080fd5b61220083611d66565b915061220e602084016121d4565b90509250929050565b60006020828403121561222957600080fd5b611d5f826121d4565b6000806040838503121561224557600080fd5b61224e83611d66565b915061220e60208401611d66565b600080600080600060a0868803121561227457600080fd5b61227d86611d66565b945061228b60208701611d66565b9350604086013592506060860135915060808601356001600160401b038111156122b457600080fd5b61209488828901611f9c565b634e487b7160e01b600052603260045260246000fd5b600181811c908216806122ea57607f821691505b60208210810361230a57634e487b7160e01b600052602260045260246000fd5b50919050565b8281526040602082015260006123296040830184611e0b565b949350505050565b60006020828403121561234357600080fd5b81516001600160401b0381111561235957600080fd5b8201601f8101841361236a57600080fd5b805161237581611f75565b6040516123828282611eb5565b82815286602084860101111561239757600080fd5b6123a8836020830160208701611ddf565b9695505050505050565b6020808252602e908201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60408201526d195c881bdc88185c1c1c9bdd995960921b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b60006001820161242857612428612400565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826124545761245461242f565b500690565b6000826124685761246861242f565b500490565b60208082526026908201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604082015265616c616e636560d01b606082015260800190565b60208082526025908201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604082015264647265737360d81b606082015260800190565b6020808252602a908201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60408201526939103a3930b739b332b960b11b606082015260800190565b600081600019048311821515161561255c5761255c612400565b500290565b6040815260006125746040830185612186565b82810360208401526125868185612186565b95945050505050565b6000828210156125a1576125a1612400565b500390565b6001600160a01b0386811682528516602082015260a0604082018190526000906125d290830186612186565b82810360608401526125e48186612186565b905082810360808401526125f88185611e0b565b98975050505050505050565b60006020828403121561261657600080fd5b8151611d5f81611dac565b600060033d111561263a5760046000803e5060005160e01c5b90565b600060443d101561264b5790565b6040516003193d81016004833e81513d6001600160401b03816024840111818411171561267a57505050505090565b82850191508151818111156126925750505050505090565b843d87010160208285010111156126ac5750505050505090565b6126bb60208286010187611eb5565b509095945050505050565b60208082526028908201527f455243313135353a204552433131353552656365697665722072656a656374656040820152676420746f6b656e7360c01b606082015260800190565b6001600160a01b03868116825285166020820152604081018490526060810183905260a06080820181905260009061274890830184611e0b565b979650505050505050565b6000821982111561276657612766612400565b50019056fea2646970667358221220c40a85e8214fb4968a77790b405815eb958ef3296e0cd897862089cfbca31ded64736f6c634300080f0033000000000000000000000000d29512ef363d87f363f4393299dd682912af6e5e

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106101ce5760003560e01c80636ae2e05511610104578063a22cb465116100a2578063dd62ed3e11610071578063dd62ed3e14610408578063e985e9c514610441578063f242432a14610454578063f2fde38b1461046757600080fd5b8063a22cb46514610391578063a2a90208146103a4578063a9059cbb146103d2578063b62496f5146103e557600080fd5b80637afa1eed116100de5780637afa1eed1461033a5780638da5cb5b1461036557806395d89b41146103765780639a7a23d61461037e57600080fd5b80636ae2e055146102e657806370a0823114610309578063715018a61461033257600080fd5b8063293230b8116101715780633ccfd60b1161014b5780633ccfd60b1461029e5780634a7c7e4b146102a65780634e1273f4146102b95780635b4f472a146102d957600080fd5b8063293230b8146102725780632eb2c2d61461027c578063313ce5671461028f57600080fd5b8063095ea7b3116101ad578063095ea7b3146102315780630e89341c1461024457806318160ddd1461025757806323b872dd1461025f57600080fd5b8062fdd58e146101d357806301ffc9a7146101f957806306fdde031461021c575b600080fd5b6101e66101e1366004611d82565b61047a565b6040519081526020015b60405180910390f35b61020c610207366004611dc2565b610548565b60405190151581526020016101f0565b6102246105b5565b6040516101f09190611e37565b61020c61023f366004611d82565b610647565b610224610252366004611e4a565b61065f565b6007546101e6565b61020c61026d366004611e63565b610707565b61027a61072b565b005b61027a61028a366004611ff8565b610742565b604051601281526020016101f0565b61027a61078e565b61027a6102b43660046120a1565b610802565b6102cc6102c73660046120bc565b61082c565b6040516101f091906121c1565b60045461020c9060ff1681565b61020c6102f43660046120a1565b60066020526000908152604090205460ff1681565b6101e66103173660046120a1565b6001600160a01b031660009081526002602052604090205490565b61027a610955565b600c5461034d906001600160a01b031681565b6040516001600160a01b0390911681526020016101f0565b6000546001600160a01b031661034d565b610224610969565b61027a61038c3660046121e4565b610978565b61027a61039f3660046121e4565b6109ac565b61027a6103b2366004612217565b336000908152600660205260409020805460ff1916911515919091179055565b61020c6103e0366004611d82565b6109b7565b61020c6103f33660046120a1565b60056020526000908152604090205460ff1681565b6101e6610416366004612232565b6001600160a01b03918216600090815260036020908152604080832093909416825291909152205490565b61020c61044f366004612232565b6109c5565b61027a61046236600461225c565b610a00565b61027a6104753660046120a1565b610a45565b60006001600160a01b0383166104ea5760405162461bcd60e51b815260206004820152602a60248201527f455243313135353a2061646472657373207a65726f206973206e6f742061207660448201526930b634b21037bbb732b960b11b60648201526084015b60405180910390fd5b6000806104f684610abb565b6001600160a01b0387166000908152600160205260408120929450909250908360288110610526576105266122c0565b01546001831b161161053957600061053c565b60015b60ff1695945050505050565b60006001600160e01b03198216636cdb3d1360e11b148061057957506001600160e01b031982166303a24d0760e21b145b8061059457506001600160e01b031982166336372b0760e01b145b806105af57506001600160e01b0319821663a219a02560e01b145b92915050565b6060600880546105c4906122d6565b80601f01602080910402602001604051908101604052809291908181526020018280546105f0906122d6565b801561063d5780601f106106125761010080835404028352916020019161063d565b820191906000526020600020905b81548152906001019060200180831161062057829003601f168201915b5050505050905090565b600033610655818585610af4565b5060019392505050565b600c5460408051602081018490526060926001600160a01b0316916341dcf4549185916106a591016040516020818303038152906040528051906020012060001c610c19565b6040518363ffffffff1660e01b81526004016106c2929190612310565b600060405180830381865afa1580156106df573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526105af9190810190612331565b600033610715858285610cab565b610720858585610d4b565b506001949350505050565b610733610fd6565b6004805460ff19166001179055565b6001600160a01b03851633148061075e575061075e85336109c5565b61077a5760405162461bcd60e51b81526004016104e1906123b2565b6107878585858585611030565b5050505050565b610796610fd6565b604051600090339047908381818185875af1925050503d80600081146107d8576040519150601f19603f3d011682016040523d82523d6000602084013e6107dd565b606091505b50509050806107ff576040516312171d8360e31b815260040160405180910390fd5b50565b61080a610fd6565b600c80546001600160a01b0319166001600160a01b0392909216919091179055565b606081518351146108915760405162461bcd60e51b815260206004820152602960248201527f455243313135353a206163636f756e747320616e6420696473206c656e677468604482015268040dad2e6dac2e8c6d60bb1b60648201526084016104e1565b600083516001600160401b038111156108ac576108ac611e9f565b6040519080825280602002602001820160405280156108d5578160200160208202803683370190505b50905060005b845181101561094d576109208582815181106108f9576108f96122c0565b6020026020010151858381518110610913576109136122c0565b602002602001015161047a565b828281518110610932576109326122c0565b602090810291909101015261094681612416565b90506108db565b509392505050565b61095d610fd6565b610967600061121a565b565b6060600980546105c4906122d6565b610980610fd6565b6001600160a01b0382166000908152600560205260409020805460ff19168215151790555050565b5050565b6109a833838361126a565b600033610655818585610d4b565b60006109d060075490565b6001600160a01b038085166000908152600360209081526040808320938716835292905220541015905092915050565b6001600160a01b038516331480610a1c5750610a1c85336109c5565b610a385760405162461bcd60e51b81526004016104e1906123b2565b6107878585858585611382565b610a4d610fd6565b6001600160a01b038116610ab25760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016104e1565b6107ff8161121a565b600080610ac760075490565b831115610ad357600080fd5b610adf61010084612445565b9050610aed61010084612459565b9150915091565b6001600160a01b038316610b565760405162461bcd60e51b8152602060048201526024808201527f45524332303a20617070726f76652066726f6d20746865207a65726f206164646044820152637265737360e01b60648201526084016104e1565b6001600160a01b038216610bb75760405162461bcd60e51b815260206004820152602260248201527f45524332303a20617070726f766520746f20746865207a65726f206164647265604482015261737360f01b60648201526084016104e1565b6001600160a01b0383811660008181526003602090815260408083209487168084529482529182902085905590518481527f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591015b60405180910390a3505050565b60606000610c26836114e1565b60010190506000816001600160401b03811115610c4557610c45611e9f565b6040519080825280601f01601f191660200182016040528015610c6f576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084610c7957509392505050565b6001600160a01b038381166000908152600360209081526040808320938616835292905220546000198114610d455781811015610d2a5760405162461bcd60e51b815260206004820152601d60248201527f45524332303a20696e73756666696369656e7420616c6c6f77616e636500000060448201526064016104e1565b610d3484846109c5565b610d4557610d458484848403610af4565b50505050565b6001600160a01b038316610daf5760405162461bcd60e51b815260206004820152602560248201527f45524332303a207472616e736665722066726f6d20746865207a65726f206164604482015264647265737360d81b60648201526084016104e1565b6001600160a01b038216610e115760405162461bcd60e51b815260206004820152602360248201527f45524332303a207472616e7366657220746f20746865207a65726f206164647260448201526265737360e81b60648201526084016104e1565b60045460ff16610e7c576001600160a01b03821660009081526005602052604090205460ff16610e7c5760405162461bcd60e51b81526020600482015260166024820152752a3930b234b7339034b9903737ba1030b1ba34bb329760511b60448201526064016104e1565b6001600160a01b03831660009081526002602052604090205481811015610eb55760405162461bcd60e51b81526004016104e19061246d565b6001600160a01b038085166000908152600260205260408082208585039055918516815220805483019055670de0b6b3a76400008210610f835760045460ff16158015610f1a57506001600160a01b03831660009081526005602052604090205460ff165b15610f2e57610f2984846115b9565b610f83565b610f808484610f45670de0b6b3a764000086612459565b3260009081526006602052604090205460ff1680610f7b57506001600160a01b03871660009081526006602052604090205460ff165b61165d565b50505b826001600160a01b0316846001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef84604051610fc891815260200190565b60405180910390a350505050565b6000546001600160a01b031633146109675760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016104e1565b81518351146110925760405162461bcd60e51b815260206004820152602860248201527f455243313135353a2069647320616e6420616d6f756e7473206c656e677468206044820152670dad2e6dac2e8c6d60c31b60648201526084016104e1565b6001600160a01b0384166110b85760405162461bcd60e51b81526004016104e1906124b3565b3360005b84518110156111365760008582815181106110d9576110d96122c0565b6020026020010151905060006001905060006110f58a8461047a565b9050818110156111175760405162461bcd60e51b81526004016104e1906124f8565b6111228a8a85611a44565b5050508061112f90612416565b90506110bc565b506001600160a01b038616600090815260026020526040902054835161116490670de0b6b3a7640000612542565b8110156111835760405162461bcd60e51b81526004016104e19061246d565b83516001600160a01b03808916600081815260026020526040808220670de0b6b3a76400009586028703905588518b85168084529282902080549190960201909455925190918516907f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb906111fb908a908a90612561565b60405180910390a4611211828888888888611b28565b50505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b816001600160a01b0316836001600160a01b0316036112dd5760405162461bcd60e51b815260206004820152602960248201527f455243313135353a2073657474696e6720617070726f76616c20737461747573604482015268103337b91039b2b63360b91b60648201526084016104e1565b8015611312576001600160a01b038084166000908152600360209081526040808320938616835292905220600019905561133b565b6001600160a01b0380841660009081526003602090815260408083209386168352929052908120555b816001600160a01b0316836001600160a01b03167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051610c0c911515815260200190565b6001600160a01b0384166113a85760405162461bcd60e51b81526004016104e1906124b3565b600191503360006113b9878661047a565b9050838110156113db5760405162461bcd60e51b81526004016104e1906124f8565b6001600160a01b03871660009081526002602052604090205461140685670de0b6b3a7640000612542565b8110156114255760405162461bcd60e51b81526004016104e19061246d565b6001600160a01b03808916600090815260026020526040808220670de0b6b3a76400008902808603909155928a168252902080549091019055611469888888611a44565b866001600160a01b0316886001600160a01b0316846001600160a01b03167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6289896040516114c1929190918252602082015260400190565b60405180910390a46114d7838989898989611c8b565b5050505050505050565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106115205772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6d04ee2d6d415b85acef8100000000831061154c576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc10000831061156a57662386f26fc10000830492506010015b6305f5e1008310611582576305f5e100830492506008015b612710831061159657612710830492506004015b606483106115a8576064830492506002015b600a83106105af5760010192915050565b60005b6028811015611658576001600160a01b038316600090815260016020526040902081602881106115ee576115ee6122c0565b01546001600160a01b03831660009081526001602052604090208260288110611619576116196122c0565b01556001600160a01b03831660009081526001602052604081208260288110611644576116446122c0565b01558061165081612416565b9150506115bc565b505050565b606080836001600160401b0381111561167857611678611e9f565b6040519080825280602002602001820160405280156116a1578160200160208202803683370190505b509150836001600160401b038111156116bc576116bc611e9f565b6040519080825280602002602001820160405280156116e5578160200160208202803683370190505b5090506000805b60288110156119dc5785156119dc576001600160a01b03881660009081526001602052604081208260288110611724576117246122c0565b0154905080156119c9576001600160a01b03891660009081526001602052604081208360288110611757576117576122c0565b01546001600160a01b038a166000908152600160205260408120919250908460288110611786576117866122c0565b0154905060007f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f0f7f5555555555555555555555555555555555555555555555555555555555555555600186901c168503600281901c7f3333333333333333333333333333333333333333333333333333333333333333908116911601600481901c01167f01010101010101010101010101010101010101010101010101010101010101010260f81c600019851460081b179050898111158980156118475750805b1561186557600093929092179161185e828c61258f565b9a5061196a565b600085118015611875575060008b115b1561196a5760006118f1867e1f0d1e100c1d070f090b19131c1706010e11080a1a141802121b150316040581196001018216911560081b6fffffffffffffffffffffffffffffffff831160071b1782811c6001600160401b031060061b1782811c63ffffffff1060051b1791821c63d76453e004601f161a1790565b6001811b1996871696909150851694506001811b8417600019909c019b93508a61195e5761191f8782611d46565b8a8981518110611931576119316122c0565b6020026020010181815250506001898981518110611951576119516122c0565b6020026020010181815250505b50600190960195611865565b6001600160a01b038d16600090815260016020526040902084908760288110611995576119956122c0565b01556001600160a01b038c166000908152600160205260409020839087602881106119c2576119c26122c0565b0155505050505b50806119d481612416565b9150506116ec565b5083611a3a57856001600160a01b0316876001600160a01b0316336001600160a01b03167f4a39dc06d4c0dbc64b70af90fd698a233a518aa5d07e595d983b8c0526c8f7fb8686604051611a31929190612561565b60405180910390a45b5094509492505050565b600080611a5083610abb565b6001600160a01b0387166000908152600160205260408120929450909250908360288110611a8057611a806122c0565b01546001600160a01b0386166000908152600160205260408120919250908460288110611aaf57611aaf6122c0565b015490506001831b19821691506001831b81176001600160a01b038816600090815260016020526040902090915082908560288110611af057611af06122c0565b01556001600160a01b038616600090815260016020526040902081908560288110611b1d57611b1d6122c0565b015550505050505050565b6001600160a01b0384163b15611c835760405163bc197c8160e01b81526001600160a01b0385169063bc197c8190611b6c90899089908890889088906004016125a6565b6020604051808303816000875af1925050508015611ba7575060408051601f3d908101601f19168201909252611ba491810190612604565b60015b611c5357611bb3612621565b806308c379a003611bec5750611bc761263d565b80611bd25750611bee565b8060405162461bcd60e51b81526004016104e19190611e37565b505b60405162461bcd60e51b815260206004820152603460248201527f455243313135353a207472616e7366657220746f206e6f6e2d455243313135356044820152732932b1b2b4bb32b91034b6b83632b6b2b73a32b960611b60648201526084016104e1565b6001600160e01b0319811663bc197c8160e01b146112115760405162461bcd60e51b81526004016104e1906126c6565b505050505050565b6001600160a01b0384163b15611c835760405163f23a6e6160e01b81526001600160a01b0385169063f23a6e6190611ccf908990899088908890889060040161270e565b6020604051808303816000875af1925050508015611d0a575060408051601f3d908101601f19168201909252611d0791810190612604565b60015b611d1657611bb3612621565b6001600160e01b0319811663f23a6e6160e01b146112115760405162461bcd60e51b81526004016104e1906126c6565b600081611d5584610100612542565b611d5f9190612753565b9392505050565b80356001600160a01b0381168114611d7d57600080fd5b919050565b60008060408385031215611d9557600080fd5b611d9e83611d66565b946020939093013593505050565b6001600160e01b0319811681146107ff57600080fd5b600060208284031215611dd457600080fd5b8135611d5f81611dac565b60005b83811015611dfa578181015183820152602001611de2565b83811115610d455750506000910152565b60008151808452611e23816020860160208601611ddf565b601f01601f19169290920160200192915050565b602081526000611d5f6020830184611e0b565b600060208284031215611e5c57600080fd5b5035919050565b600080600060608486031215611e7857600080fd5b611e8184611d66565b9250611e8f60208501611d66565b9150604084013590509250925092565b634e487b7160e01b600052604160045260246000fd5b601f8201601f191681016001600160401b0381118282101715611eda57611eda611e9f565b6040525050565b60006001600160401b03821115611efa57611efa611e9f565b5060051b60200190565b600082601f830112611f1557600080fd5b81356020611f2282611ee1565b604051611f2f8282611eb5565b83815260059390931b8501820192828101915086841115611f4f57600080fd5b8286015b84811015611f6a5780358352918301918301611f53565b509695505050505050565b60006001600160401b03821115611f8e57611f8e611e9f565b50601f01601f191660200190565b600082601f830112611fad57600080fd5b8135611fb881611f75565b604051611fc58282611eb5565b828152856020848701011115611fda57600080fd5b82602086016020830137600092810160200192909252509392505050565b600080600080600060a0868803121561201057600080fd5b61201986611d66565b945061202760208701611d66565b935060408601356001600160401b038082111561204357600080fd5b61204f89838a01611f04565b9450606088013591508082111561206557600080fd5b61207189838a01611f04565b9350608088013591508082111561208757600080fd5b5061209488828901611f9c565b9150509295509295909350565b6000602082840312156120b357600080fd5b611d5f82611d66565b600080604083850312156120cf57600080fd5b82356001600160401b03808211156120e657600080fd5b818501915085601f8301126120fa57600080fd5b8135602061210782611ee1565b6040516121148282611eb5565b83815260059390931b850182019282810191508984111561213457600080fd5b948201945b838610156121595761214a86611d66565b82529482019490820190612139565b9650508601359250508082111561216f57600080fd5b5061217c85828601611f04565b9150509250929050565b600081518084526020808501945080840160005b838110156121b65781518752958201959082019060010161219a565b509495945050505050565b602081526000611d5f6020830184612186565b80358015158114611d7d57600080fd5b600080604083850312156121f757600080fd5b61220083611d66565b915061220e602084016121d4565b90509250929050565b60006020828403121561222957600080fd5b611d5f826121d4565b6000806040838503121561224557600080fd5b61224e83611d66565b915061220e60208401611d66565b600080600080600060a0868803121561227457600080fd5b61227d86611d66565b945061228b60208701611d66565b9350604086013592506060860135915060808601356001600160401b038111156122b457600080fd5b61209488828901611f9c565b634e487b7160e01b600052603260045260246000fd5b600181811c908216806122ea57607f821691505b60208210810361230a57634e487b7160e01b600052602260045260246000fd5b50919050565b8281526040602082015260006123296040830184611e0b565b949350505050565b60006020828403121561234357600080fd5b81516001600160401b0381111561235957600080fd5b8201601f8101841361236a57600080fd5b805161237581611f75565b6040516123828282611eb5565b82815286602084860101111561239757600080fd5b6123a8836020830160208701611ddf565b9695505050505050565b6020808252602e908201527f455243313135353a2063616c6c6572206973206e6f7420746f6b656e206f776e60408201526d195c881bdc88185c1c1c9bdd995960921b606082015260800190565b634e487b7160e01b600052601160045260246000fd5b60006001820161242857612428612400565b5060010190565b634e487b7160e01b600052601260045260246000fd5b6000826124545761245461242f565b500690565b6000826124685761246861242f565b500490565b60208082526026908201527f45524332303a207472616e7366657220616d6f756e7420657863656564732062604082015265616c616e636560d01b606082015260800190565b60208082526025908201527f455243313135353a207472616e7366657220746f20746865207a65726f206164604082015264647265737360d81b606082015260800190565b6020808252602a908201527f455243313135353a20696e73756666696369656e742062616c616e636520666f60408201526939103a3930b739b332b960b11b606082015260800190565b600081600019048311821515161561255c5761255c612400565b500290565b6040815260006125746040830185612186565b82810360208401526125868185612186565b95945050505050565b6000828210156125a1576125a1612400565b500390565b6001600160a01b0386811682528516602082015260a0604082018190526000906125d290830186612186565b82810360608401526125e48186612186565b905082810360808401526125f88185611e0b565b98975050505050505050565b60006020828403121561261657600080fd5b8151611d5f81611dac565b600060033d111561263a5760046000803e5060005160e01c5b90565b600060443d101561264b5790565b6040516003193d81016004833e81513d6001600160401b03816024840111818411171561267a57505050505090565b82850191508151818111156126925750505050505090565b843d87010160208285010111156126ac5750505050505090565b6126bb60208286010187611eb5565b509095945050505050565b60208082526028908201527f455243313135353a204552433131353552656365697665722072656a656374656040820152676420746f6b656e7360c01b606082015260800190565b6001600160a01b03868116825285166020820152604081018490526060810183905260a06080820181905260009061274890830184611e0b565b979650505050505050565b6000821982111561276657612766612400565b50019056fea2646970667358221220c40a85e8214fb4968a77790b405815eb958ef3296e0cd897862089cfbca31ded64736f6c634300080f0033

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

000000000000000000000000d29512ef363d87f363f4393299dd682912af6e5e

-----Decoded View---------------
Arg [0] : generatorAddress (address): 0xd29512EF363d87F363f4393299Dd682912af6E5E

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000d29512ef363d87f363f4393299dd682912af6e5e


Deployed Bytecode Sourcemap

76032:1013:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60225:315;;;;;;:::i;:::-;;:::i;:::-;;;597:25:1;;;585:2;570:18;60225:315:0;;;;;;;;70042:360;;;;;;:::i;:::-;;:::i;:::-;;;1184:14:1;;1177:22;1159:41;;1147:2;1132:18;70042:360:0;1019:187:1;69816:102:0;;;:::i;:::-;;;;;;;:::i;61056:201::-;;;;;;:::i;:::-;;:::i;76286:289::-;;;;;;:::i;:::-;;:::i;69700:108::-;69788:12;;69700:108;;62088:311;;;;;;:::i;:::-;;:::i;58459:81::-;;;:::i;:::-;;62823:438;;;;;;:::i;:::-;;:::i;72020:93::-;;;72103:2;5577:36:1;;5565:2;5550:18;72020:93:0;5435:184:1;76869:173:0;;;:::i;76581:132::-;;;;;;:::i;:::-;;:::i;60548:498::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;57617:34::-;;;;;;;;;57722:45;;;;;;:::i;:::-;;;;;;;;;;;;;;;;60112:105;;;;;;:::i;:::-;-1:-1:-1;;;;;60196:13:0;60172:4;60196:13;;;:9;:13;;;;;;;60112:105;2816:103;;;:::i;76068:35::-;;;;;-1:-1:-1;;;;;76068:35:0;;;;;;-1:-1:-1;;;;;7925:32:1;;;7907:51;;7895:2;7880:18;76068:35:0;7734:230:1;2168:87:0;2214:7;2241:6;-1:-1:-1;;;;;2241:6:0;2168:87;;69926:106;;;:::i;76721:140::-;;;;;;:::i;:::-;;:::i;61267:155::-;;;;;;:::i;:::-;;:::i;61976:104::-;;;;;;:::i;:::-;62051:10;62037:25;;;;:13;:25;;;;;:35;;-1:-1:-1;;62037:35:0;;;;;;;;;;61976:104;61775:193;;;;;;:::i;:::-;;:::i;57658:57::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;61616:151;;;;;;:::i;:::-;-1:-1:-1;;;;;61732:18:0;;;61705:7;61732:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;61616:151;61430:178;;;;;;:::i;:::-;;:::i;62409:406::-;;;;;;:::i;:::-;;:::i;3074:201::-;;;;;;:::i;:::-;;:::i;60225:315::-;60311:7;-1:-1:-1;;;;;60339:21:0;;60331:76;;;;-1:-1:-1;;;60331:76:0;;9864:2:1;60331:76:0;;;9846:21:1;9903:2;9883:18;;;9876:30;9942:34;9922:18;;;9915:62;-1:-1:-1;;;9993:18:1;;;9986:40;10043:19;;60331:76:0;;;;;;;;;60419:8;60429;60441:21;60459:2;60441:17;:21::i;:::-;-1:-1:-1;;;;;60496:18:0;;60523:1;60496:18;;;:9;:18;;;;;60418:44;;-1:-1:-1;60418:44:0;;-1:-1:-1;60523:1:0;60418:44;60496:23;;;;;;;:::i;:::-;;;60484:1;:8;;60483:36;60482:42;:50;;60531:1;60482:50;;;60527:1;60482:50;60475:57;;;60225:315;-1:-1:-1;;;;;60225:315:0:o;70042:360::-;70127:4;-1:-1:-1;;;;;;70164:41:0;;-1:-1:-1;;;70164:41:0;;:110;;-1:-1:-1;;;;;;;70222:52:0;;-1:-1:-1;;;70222:52:0;70164:110;:166;;;-1:-1:-1;;;;;;;70291:39:0;;-1:-1:-1;;;70291:39:0;70164:166;:230;;;-1:-1:-1;;;;;;;70347:47:0;;-1:-1:-1;;;70347:47:0;70164:230;70144:250;70042:360;-1:-1:-1;;70042:360:0:o;69816:102::-;69872:13;69905:5;69898:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69816:102;:::o;61056:201::-;61139:4;930:10;61195:32;930:10;61211:7;61220:6;61195:8;:32::i;:::-;-1:-1:-1;61245:4:0;;61056:201;-1:-1:-1;;;61056:201:0:o;76286:289::-;76379:9;;76496:25;;;;;;10719:19:1;;;76346:13:0;;-1:-1:-1;;;;;76379:9:0;;:18;;76398:7;;76407:159;;10754:12:1;76496:25:0;;;;;;;;;;;;76464:76;;;;;;76438:117;;76407:16;:159::i;:::-;76379:188;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;76379:188:0;;;;;;;;;;;;:::i;62088:311::-;62219:4;930:10;62293:38;62309:4;930:10;62324:6;62293:15;:38::i;:::-;62342:27;62352:4;62358:2;62362:6;62342:9;:27::i;:::-;-1:-1:-1;62387:4:0;;62088:311;-1:-1:-1;;;;62088:311:0:o;58459:81::-;2054:13;:11;:13::i;:::-;58511:14:::1;:21:::0;;-1:-1:-1;;58511:21:0::1;58528:4;58511:21;::::0;;58459:81::o;62823:438::-;-1:-1:-1;;;;;63056:20:0;;930:10;63056:20;;:60;;-1:-1:-1;63080:36:0;63097:4;930:10;61430:178;:::i;63080:36::-;63034:156;;;;-1:-1:-1;;;63034:156:0;;;;;;;:::i;:::-;63201:52;63224:4;63230:2;63234:3;63239:7;63248:4;63201:22;:52::i;:::-;62823:438;;;;;:::o;76869:173::-;2054:13;:11;:13::i;:::-;76937:49:::1;::::0;76920:12:::1;::::0;76937:10:::1;::::0;76960:21:::1;::::0;76920:12;76937:49;76920:12;76937:49;76960:21;76937:10;:49:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;76919:67;;;77002:7;76997:37;;77018:16;;-1:-1:-1::0;;;77018:16:0::1;;;;;;;;;;;76997:37;76908:134;76869:173::o:0;76581:132::-;2054:13;:11;:13::i;:::-;76657:9:::1;:48:::0;;-1:-1:-1;;;;;;76657:48:0::1;-1:-1:-1::0;;;;;76657:48:0;;;::::1;::::0;;;::::1;::::0;;76581:132::o;60548:498::-;60684:16;60745:3;:10;60726:8;:15;:29;60718:83;;;;-1:-1:-1;;;60718:83:0;;12595:2:1;60718:83:0;;;12577:21:1;12634:2;12614:18;;;12607:30;12673:34;12653:18;;;12646:62;-1:-1:-1;;;12724:18:1;;;12717:39;12773:19;;60718:83:0;12393:405:1;60718:83:0;60812:30;60859:8;:15;-1:-1:-1;;;;;60845:30:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;60845:30:0;;60812:63;;60891:9;60886:122;60910:8;:15;60906:1;:19;60886:122;;;60966:30;60976:8;60985:1;60976:11;;;;;;;;:::i;:::-;;;;;;;60989:3;60993:1;60989:6;;;;;;;;:::i;:::-;;;;;;;60966:9;:30::i;:::-;60947:13;60961:1;60947:16;;;;;;;;:::i;:::-;;;;;;;;;;:49;60927:3;;;:::i;:::-;;;60886:122;;;-1:-1:-1;61025:13:0;60548:498;-1:-1:-1;;;60548:498:0:o;2816:103::-;2054:13;:11;:13::i;:::-;2881:30:::1;2908:1;2881:18;:30::i;:::-;2816:103::o:0;69926:106::-;69984:13;70017:7;70010:14;;;;;:::i;76721:140::-;2054:13;:11;:13::i;:::-;-1:-1:-1;;;;;63353:31:0;;;;;;:25;:31;;;;;:39;;-1:-1:-1;;63353:39:0;;;;;;;76721:140;;:::o;76812:41::-:1;76721:140:::0;;:::o;61267:155::-;61362:52;930:10;61395:8;61405;61362:18;:52::i;61775:193::-;61854:4;930:10;61910:28;930:10;61927:2;61931:6;61910:9;:28::i;61430:178::-;61529:4;61587:13;69788:12;;;69700:108;61587:13;-1:-1:-1;;;;;61553:20:0;;;;;;;:11;:20;;;;;;;;:30;;;;;;;;;;:47;;;-1:-1:-1;61430:178:0;;;;:::o;62409:406::-;-1:-1:-1;;;;;62617:20:0;;930:10;62617:20;;:60;;-1:-1:-1;62641:36:0;62658:4;930:10;61430:178;:::i;62641:36::-;62595:156;;;;-1:-1:-1;;;62595:156:0;;;;;;;:::i;:::-;62762:45;62780:4;62786:2;62790;62794:6;62802:4;62762:17;:45::i;3074:201::-;2054:13;:11;:13::i;:::-;-1:-1:-1;;;;;3163:22:0;::::1;3155:73;;;::::0;-1:-1:-1;;;3155:73:0;;13277:2:1;3155:73:0::1;::::0;::::1;13259:21:1::0;13316:2;13296:18;;;13289:30;13355:34;13335:18;;;13328:62;-1:-1:-1;;;13406:18:1;;;13399:36;13452:19;;3155:73:0::1;13075:402:1::0;3155:73:0::1;3239:28;3258:8;3239:18;:28::i;74849:176::-:0;74908:8;74918;74953:13;69788:12;;;69700:108;74953:13;74947:2;:19;;74939:28;;;;;;74984:8;74989:3;74984:2;:8;:::i;:::-;74978:14;-1:-1:-1;75009:8:0;75014:3;75009:2;:8;:::i;:::-;75003:14;;74849:176;;;:::o;70410:380::-;-1:-1:-1;;;;;70546:19:0;;70538:68;;;;-1:-1:-1;;;70538:68:0;;14058:2:1;70538:68:0;;;14040:21:1;14097:2;14077:18;;;14070:30;14136:34;14116:18;;;14109:62;-1:-1:-1;;;14187:18:1;;;14180:34;14231:19;;70538:68:0;13856:400:1;70538:68:0;-1:-1:-1;;;;;70625:21:0;;70617:68;;;;-1:-1:-1;;;70617:68:0;;14463:2:1;70617:68:0;;;14445:21:1;14502:2;14482:18;;;14475:30;14541:34;14521:18;;;14514:62;-1:-1:-1;;;14592:18:1;;;14585:32;14634:19;;70617:68:0;14261:398:1;70617:68:0;-1:-1:-1;;;;;70698:18:0;;;;;;;:11;:18;;;;;;;;:27;;;;;;;;;;;;;:36;;;70750:32;;597:25:1;;;70750:32:0;;570:18:1;70750:32:0;;;;;;;;70410:380;;;:::o;50508:716::-;50564:13;50615:14;50632:17;50643:5;50632:10;:17::i;:::-;50652:1;50632:21;50615:38;;50668:20;50702:6;-1:-1:-1;;;;;50691:18:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;50691:18:0;-1:-1:-1;50668:41:0;-1:-1:-1;50833:28:0;;;50849:2;50833:28;50890:288;-1:-1:-1;;50922:5:0;-1:-1:-1;;;51059:2:0;51048:14;;51043:30;50922:5;51030:44;51120:2;51111:11;;;-1:-1:-1;51141:21:0;50890:288;51141:21;-1:-1:-1;51199:6:0;50508:716;-1:-1:-1;;;50508:716:0:o;71246:534::-;-1:-1:-1;;;;;61732:18:0;;;71381:24;61732:18;;;:11;:18;;;;;;;;:27;;;;;;;;;;-1:-1:-1;;71448:37:0;;71444:329;;71530:6;71510:16;:26;;71502:68;;;;-1:-1:-1;;;71502:68:0;;14866:2:1;71502:68:0;;;14848:21:1;14905:2;14885:18;;;14878:30;14944:31;14924:18;;;14917:59;14993:18;;71502:68:0;14664:353:1;71502:68:0;71590:32;71607:5;71614:7;71590:16;:32::i;:::-;71585:177;;71676:51;71685:5;71692:7;71720:6;71701:16;:25;71676:8;:51::i;:::-;71370:410;71246:534;;;:::o;63408:1047::-;-1:-1:-1;;;;;63539:18:0;;63531:68;;;;-1:-1:-1;;;63531:68:0;;15224:2:1;63531:68:0;;;15206:21:1;15263:2;15243:18;;;15236:30;15302:34;15282:18;;;15275:62;-1:-1:-1;;;15353:18:1;;;15346:35;15398:19;;63531:68:0;15022:401:1;63531:68:0;-1:-1:-1;;;;;63618:16:0;;63610:64;;;;-1:-1:-1;;;63610:64:0;;15630:2:1;63610:64:0;;;15612:21:1;15669:2;15649:18;;;15642:30;15708:34;15688:18;;;15681:62;-1:-1:-1;;;15759:18:1;;;15752:33;15802:19;;63610:64:0;15428:399:1;63610:64:0;63690:14;;;;63685:161;;-1:-1:-1;;;;;63747:29:0;;;;;;:25;:29;;;;;;;;63721:113;;;;-1:-1:-1;;;63721:113:0;;16034:2:1;63721:113:0;;;16016:21:1;16073:2;16053:18;;;16046:30;-1:-1:-1;;;16092:18:1;;;16085:52;16154:18;;63721:113:0;15832:346:1;63721:113:0;-1:-1:-1;;;;;63878:15:0;;63856:19;63878:15;;;:9;:15;;;;;;63912:21;;;;63904:72;;;;-1:-1:-1;;;63904:72:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;64012:15:0;;;;;;;:9;:15;;;;;;64030:20;;;64012:38;;64065:13;;;;;;:23;;;;;;64126:4;64116:14;;64112:294;;64152:14;;;;64151:15;:48;;;;-1:-1:-1;;;;;;64170:29:0;;;;;;:25;:29;;;;;;;;64151:48;64147:248;;;64220:30;64241:4;64247:2;64220:20;:30::i;:::-;64147:248;;;64291:88;64308:4;64314:2;64318:13;64327:4;64318:6;:13;:::i;:::-;64347:9;64333:24;;;;:13;:24;;;;;;;;;:45;;-1:-1:-1;;;;;;64361:17:0;;;;;;:13;:17;;;;;;;;64333:45;64291:16;:88::i;:::-;;;64147:248;64436:2;-1:-1:-1;;;;;64421:26:0;64430:4;-1:-1:-1;;;;;64421:26:0;;64440:6;64421:26;;;;597:25:1;;585:2;570:18;;451:177;64421:26:0;;;;;;;;63520:935;63408:1047;;;:::o;2333:132::-;2214:7;2241:6;-1:-1:-1;;;;;2241:6:0;930:10;2397:23;2389:68;;;;-1:-1:-1;;;2389:68:0;;16792:2:1;2389:68:0;;;16774:21:1;;;16811:18;;;16804:30;16870:34;16850:18;;;16843:62;16922:18;;2389:68:0;16590:356:1;65400:1197:0;65627:7;:14;65613:3;:10;:28;65605:81;;;;-1:-1:-1;;;65605:81:0;;17153:2:1;65605:81:0;;;17135:21:1;17192:2;17172:18;;;17165:30;17231:34;17211:18;;;17204:62;-1:-1:-1;;;17282:18:1;;;17275:38;17330:19;;65605:81:0;16951:404:1;65605:81:0;-1:-1:-1;;;;;65705:16:0;;65697:66;;;;-1:-1:-1;;;65697:66:0;;;;;;;:::i;:::-;930:10;65776:16;65820:307;65844:3;:10;65840:1;:14;65820:307;;;65876:10;65889:3;65893:1;65889:6;;;;;;;;:::i;:::-;;;;;;;65876:19;;65910:14;65927:1;65910:18;;65943:19;65965;65975:4;65981:2;65965:9;:19::i;:::-;65943:41;;66022:6;66007:11;:21;;65999:76;;;;-1:-1:-1;;;65999:76:0;;;;;;;:::i;:::-;66090:25;66102:4;66108:2;66112;66090:11;:25::i;:::-;65861:266;;;65856:3;;;;:::i;:::-;;;65820:307;;;-1:-1:-1;;;;;;66164:15:0;;66139:22;66164:15;;;:9;:15;;;;;;66216:14;;:21;;66233:4;66216:21;:::i;:::-;66198:14;:39;;66190:90;;;;-1:-1:-1;;;66190:90:0;;;;;;;:::i;:::-;66351:14;;-1:-1:-1;;;;;66316:15:0;;;;;;;:9;:15;;;;;;66368:4;66351:21;;;66334:38;;66316:56;;66404:14;;66387:13;;;;;;;;;;:38;;66404:21;;;;66387:38;;;;66454:47;;66316:15;;66454:47;;;;;;;66488:3;;66351:7;;66454:47;:::i;:::-;;;;;;;;66514:75;66550:8;66560:4;66566:2;66570:3;66575:7;66584:4;66514:35;:75::i;:::-;65594:1003;;65400:1197;;;;;:::o;3435:191::-;3509:16;3528:6;;-1:-1:-1;;;;;3545:17:0;;;-1:-1:-1;;;;;;3545:17:0;;;;;;3578:40;;3528:6;;;;;;;3578:40;;3509:16;3578:40;3498:128;3435:191;:::o;70798:438::-;70953:8;-1:-1:-1;;;;;70944:17:0;:5;-1:-1:-1;;;;;70944:17:0;;70936:71;;;;-1:-1:-1;;;70936:71:0;;19022:2:1;70936:71:0;;;19004:21:1;19061:2;19041:18;;;19034:30;19100:34;19080:18;;;19073:62;-1:-1:-1;;;19151:18:1;;;19144:39;19200:19;;70936:71:0;18820:405:1;70936:71:0;71022:8;71018:154;;;-1:-1:-1;;;;;71047:18:0;;;;;;;:11;:18;;;;;;;;:28;;;;;;;;;-1:-1:-1;;71047:48:0;;71018:154;;;-1:-1:-1;;;;;71128:18:0;;;71159:1;71128:18;;;:11;:18;;;;;;;;:28;;;;;;;;;;;:32;71018:154;71209:8;-1:-1:-1;;;;;71187:41:0;71202:5;-1:-1:-1;;;;;71187:41:0;;71219:8;71187:41;;;;1184:14:1;1177:22;1159:41;;1147:2;1132:18;;1019:187;64463:927:0;-1:-1:-1;;;;;64651:16:0;;64643:66;;;;-1:-1:-1;;;64643:66:0;;;;;;;:::i;:::-;64731:1;;-1:-1:-1;930:10:0;64745:16;64811:19;64821:4;64827:2;64811:9;:19::i;:::-;64789:41;;64864:6;64849:11;:21;;64841:76;;;;-1:-1:-1;;;64841:76:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;64953:15:0;;64928:22;64953:15;;;:9;:15;;;;;;65005:13;:6;65014:4;65005:13;:::i;:::-;64987:14;:31;;64979:82;;;;-1:-1:-1;;;64979:82:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;65097:15:0;;;;;;;:9;:15;;;;;;65141:4;65132:13;;65115:30;;;65097:48;;;65160:13;;;;;;;:30;;;;;;;65212:25;65107:4;65170:2;65234;65212:11;:25::i;:::-;65286:2;-1:-1:-1;;;;;65255:46:0;65280:4;-1:-1:-1;;;;;65255:46:0;65270:8;-1:-1:-1;;;;;65255:46:0;;65290:2;65294:6;65255:46;;;;;;19404:25:1;;;19460:2;19445:18;;19438:34;19392:2;19377:18;;19230:248;65255:46:0;;;;;;;;65314:68;65345:8;65355:4;65361:2;65365;65369:6;65377:4;65314:30;:68::i;:::-;64632:758;;;64463:927;;;;;:::o;47566:922::-;47619:7;;-1:-1:-1;;;47697:15:0;;47693:102;;-1:-1:-1;;;47733:15:0;;;-1:-1:-1;47777:2:0;47767:12;47693:102;47822:6;47813:5;:15;47809:102;;47858:6;47849:15;;;-1:-1:-1;47893:2:0;47883:12;47809:102;47938:6;47929:5;:15;47925:102;;47974:6;47965:15;;;-1:-1:-1;48009:2:0;47999:12;47925:102;48054:5;48045;:14;48041:99;;48089:5;48080:14;;;-1:-1:-1;48123:1:0;48113:11;48041:99;48167:5;48158;:14;48154:99;;48202:5;48193:14;;;-1:-1:-1;48236:1:0;48226:11;48154:99;48280:5;48271;:14;48267:99;;48315:5;48306:14;;;-1:-1:-1;48349:1:0;48339:11;48267:99;48393:5;48384;:14;48380:66;;48429:1;48419:11;48474:6;47566:922;-1:-1:-1;;47566:922:0:o;67618:221::-;67698:6;67693:139;57414:2;67710:1;:14;67693:139;;;-1:-1:-1;;;;;67765:15:0;;;;;;:9;:15;;;;;67781:1;67765:18;;;;;;;:::i;:::-;;;-1:-1:-1;;;;;67746:13:0;;;;;;:9;:13;;;;;67760:1;67746:16;;;;;;;:::i;:::-;;:37;-1:-1:-1;;;;;67798:15:0;;67819:1;67798:15;;;:9;:15;;;;;67814:1;67798:18;;;;;;;:::i;:::-;;:22;67726:3;;;;:::i;:::-;;;;67693:139;;;;67618:221;;:::o;67849:1743::-;67946:20;67968:24;68023:5;-1:-1:-1;;;;;68012:17:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;68012:17:0;;68006:23;;68061:5;-1:-1:-1;;;;;68050:17:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;68050:17:0;;68040:27;;68078:8;68106:6;68101:1377;57414:2;68118:1;:14;68101:1377;;;68154:56;;68189:5;68154:56;-1:-1:-1;;;;;68236:15:0;;68224:9;68236:15;;;:9;:15;;;;;68252:1;68236:18;;;;;;;:::i;:::-;;;;-1:-1:-1;68273:8:0;;68269:1198;;-1:-1:-1;;;;;68318:15:0;;68302:13;68318:15;;;:9;:15;;;;;68334:1;68318:18;;;;;;;:::i;:::-;;;-1:-1:-1;;;;;68369:13:0;;68355:11;68369:13;;;:9;:13;;;;;68318:18;;-1:-1:-1;68355:11:0;68383:1;68369:16;;;;;;;:::i;:::-;;;;-1:-1:-1;68404:16:0;74741:12;74614:11;74607:1;74603:9;;;74599:27;74592:35;;74679:1;74675:9;;;74686:11;74671:27;;;74650:19;;74646:53;74733:1;74729:9;;;74722:17;74718:36;74807:13;74800:21;74795:3;74791:31;-1:-1:-1;;74563:10:0;;74780:1;74776:13;74773:50;68404:33;-1:-1:-1;68479:20:0;;;;68521:9;:28;;;;;68534:15;68521:28;68518:842;;;68634:1;;68583:17;;;;;68658:20;68667:11;68658:20;;:::i;:::-;;;68518:842;;;68741:1;68734:4;:8;:21;;;;;68754:1;68746:5;:9;68734:21;68727:614;;;68825:6;68834:9;68838:4;74329:66;74015:6;;74023:1;74011:14;74004:22;;74055:9;;74052:1;74048:17;74077:34;74074:41;-1:-1:-1;74071:1:0;74067:49;74045:72;74172:9;;;-1:-1:-1;;;;;74149:33:0;74146:1;74142:41;74136:48;74231:9;;;74219:10;74216:25;74213:1;74209:33;74203:40;74293:9;;;74281:10;74277:26;74305:4;74273:37;74268:128;74262:135;;73902:513;68834:9;68890:1;:6;;68888:9;68881:16;;;;68825:18;;-1:-1:-1;71875:16:0;;68928:33;-1:-1:-1;71996:1:0;:7;;71989:15;;-1:-1:-1;;69049:7:0;;;;68992:26;-1:-1:-1;69092:9:0;69087:168;;69149:23;69167:1;69170;69149:17;:23::i;:::-;69138:3;69142;69138:8;;;;;;;;:::i;:::-;;;;;;:34;;;;;69222:1;69207:7;69215:3;69207:12;;;;;;;;:::i;:::-;;;;;;:16;;;;;69087:168;-1:-1:-1;69285:5:0;;;;;68727:614;;;-1:-1:-1;;;;;69378:15:0;;;;;;:9;:15;;;;;69399:8;;69394:1;69378:18;;;;;;;:::i;:::-;;:29;-1:-1:-1;;;;;69426:13:0;;;;;;:9;:13;;;;;69445:6;;69440:1;69426:16;;;;;;;:::i;:::-;;:25;-1:-1:-1;;;;68269:1198:0;-1:-1:-1;68134:3:0;;;;:::i;:::-;;;;68101:1377;;;;69493:9;69488:97;;69556:2;-1:-1:-1;;;;;69524:49:0;69550:4;-1:-1:-1;;;;;69524:49:0;69538:10;-1:-1:-1;;;;;69524:49:0;;69560:3;69565:7;69524:49;;;;;;;:::i;:::-;;;;;;;;69488:97;67995:1597;67849:1743;;;;;;;:::o;66605:391::-;66682:8;66692;66704:21;66722:2;66704:17;:21::i;:::-;-1:-1:-1;;;;;66755:15:0;;66736:16;66755:15;;;:9;:15;;;;;66681:44;;-1:-1:-1;66681:44:0;;-1:-1:-1;66736:16:0;66681:44;66755:20;;;;;;;:::i;:::-;;;-1:-1:-1;;;;;66803:13:0;;66786:14;66803:13;;;:9;:13;;;;;66755:20;;-1:-1:-1;66786:14:0;66817:3;66803:18;;;;;;;:::i;:::-;;;;-1:-1:-1;71883:1:0;:7;;71881:10;71875:16;;66834:35;-1:-1:-1;71996:1:0;:7;;71989:15;;-1:-1:-1;;;;;66919:15:0;;;;;;:9;:15;;;;;66880:28;;-1:-1:-1;66942:8:0;;66935:3;66919:20;;;;;;;:::i;:::-;;:31;-1:-1:-1;;;;;66961:13:0;;;;;;:9;:13;;;;;66982:6;;66975:3;66961:18;;;;;;;:::i;:::-;;:27;-1:-1:-1;;;;;;;66605:391:0:o;72875:813::-;-1:-1:-1;;;;;73115:13:0;;12265:19;:23;73111:570;;73151:79;;-1:-1:-1;;;73151:79:0;;-1:-1:-1;;;;;73151:43:0;;;;;:79;;73195:8;;73205:4;;73211:3;;73216:7;;73225:4;;73151:79;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;73151:79:0;;;;;;;;-1:-1:-1;;73151:79:0;;;;;;;;;;;;:::i;:::-;;;73147:523;;;;:::i;:::-;;;;;;;;;:::i;:::-;;;;;;;;73543:6;73536:14;;-1:-1:-1;;;73536:14:0;;;;;;;;:::i;73147:523::-;;;73592:62;;-1:-1:-1;;;73592:62:0;;21761:2:1;73592:62:0;;;21743:21:1;21800:2;21780:18;;;21773:30;21839:34;21819:18;;;21812:62;-1:-1:-1;;;21890:18:1;;;21883:50;21950:19;;73592:62:0;21559:416:1;73147:523:0;-1:-1:-1;;;;;;73312:60:0;;-1:-1:-1;;;73312:60:0;73308:159;;73397:50;;-1:-1:-1;;;73397:50:0;;;;;;;:::i;73147:523::-;72875:813;;;;;;:::o;72123:744::-;-1:-1:-1;;;;;72338:13:0;;12265:19;:23;72334:526;;72374:72;;-1:-1:-1;;;72374:72:0;;-1:-1:-1;;;;;72374:38:0;;;;;:72;;72413:8;;72423:4;;72429:2;;72433:6;;72441:4;;72374:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;72374:72:0;;;;;;;;-1:-1:-1;;72374:72:0;;;;;;;;;;;;:::i;:::-;;;72370:479;;;;:::i;:::-;-1:-1:-1;;;;;;72496:55:0;;-1:-1:-1;;;72496:55:0;72492:154;;72576:50;;-1:-1:-1;;;72576:50:0;;;;;;;:::i;75033:118::-;75103:7;75140:3;75128:9;:3;75134;75128:9;:::i;:::-;:15;;;;:::i;:::-;75123:20;75033:118;-1:-1:-1;;;75033:118:0:o;14:173:1:-;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:70;;177:1;174;167:12;111:70;14:173;;;:::o;192:254::-;260:6;268;321:2;309:9;300:7;296:23;292:32;289:52;;;337:1;334;327:12;289:52;360:29;379:9;360:29;:::i;:::-;350:39;436:2;421:18;;;;408:32;;-1:-1:-1;;;192:254:1:o;633:131::-;-1:-1:-1;;;;;;707:32:1;;697:43;;687:71;;754:1;751;744:12;769:245;827:6;880:2;868:9;859:7;855:23;851:32;848:52;;;896:1;893;886:12;848:52;935:9;922:23;954:30;978:5;954:30;:::i;1211:258::-;1283:1;1293:113;1307:6;1304:1;1301:13;1293:113;;;1383:11;;;1377:18;1364:11;;;1357:39;1329:2;1322:10;1293:113;;;1424:6;1421:1;1418:13;1415:48;;;-1:-1:-1;;1459:1:1;1441:16;;1434:27;1211:258::o;1474:::-;1516:3;1554:5;1548:12;1581:6;1576:3;1569:19;1597:63;1653:6;1646:4;1641:3;1637:14;1630:4;1623:5;1619:16;1597:63;:::i;:::-;1714:2;1693:15;-1:-1:-1;;1689:29:1;1680:39;;;;1721:4;1676:50;;1474:258;-1:-1:-1;;1474:258:1:o;1737:220::-;1886:2;1875:9;1868:21;1849:4;1906:45;1947:2;1936:9;1932:18;1924:6;1906:45;:::i;1962:180::-;2021:6;2074:2;2062:9;2053:7;2049:23;2045:32;2042:52;;;2090:1;2087;2080:12;2042:52;-1:-1:-1;2113:23:1;;1962:180;-1:-1:-1;1962:180:1:o;2147:328::-;2224:6;2232;2240;2293:2;2281:9;2272:7;2268:23;2264:32;2261:52;;;2309:1;2306;2299:12;2261:52;2332:29;2351:9;2332:29;:::i;:::-;2322:39;;2380:38;2414:2;2403:9;2399:18;2380:38;:::i;:::-;2370:48;;2465:2;2454:9;2450:18;2437:32;2427:42;;2147:328;;;;;:::o;2480:127::-;2541:10;2536:3;2532:20;2529:1;2522:31;2572:4;2569:1;2562:15;2596:4;2593:1;2586:15;2612:249;2722:2;2703:13;;-1:-1:-1;;2699:27:1;2687:40;;-1:-1:-1;;;;;2742:34:1;;2778:22;;;2739:62;2736:88;;;2804:18;;:::i;:::-;2840:2;2833:22;-1:-1:-1;;2612:249:1:o;2866:183::-;2926:4;-1:-1:-1;;;;;2951:6:1;2948:30;2945:56;;;2981:18;;:::i;:::-;-1:-1:-1;3026:1:1;3022:14;3038:4;3018:25;;2866:183::o;3054:724::-;3108:5;3161:3;3154:4;3146:6;3142:17;3138:27;3128:55;;3179:1;3176;3169:12;3128:55;3215:6;3202:20;3241:4;3264:43;3304:2;3264:43;:::i;:::-;3336:2;3330:9;3348:31;3376:2;3368:6;3348:31;:::i;:::-;3414:18;;;3506:1;3502:10;;;;3490:23;;3486:32;;;3448:15;;;;-1:-1:-1;3530:15:1;;;3527:35;;;3558:1;3555;3548:12;3527:35;3594:2;3586:6;3582:15;3606:142;3622:6;3617:3;3614:15;3606:142;;;3688:17;;3676:30;;3726:12;;;;3639;;3606:142;;;-1:-1:-1;3766:6:1;3054:724;-1:-1:-1;;;;;;3054:724:1:o;3783:186::-;3831:4;-1:-1:-1;;;;;3856:6:1;3853:30;3850:56;;;3886:18;;:::i;:::-;-1:-1:-1;3952:2:1;3931:15;-1:-1:-1;;3927:29:1;3958:4;3923:40;;3783:186::o;3974:508::-;4016:5;4069:3;4062:4;4054:6;4050:17;4046:27;4036:55;;4087:1;4084;4077:12;4036:55;4123:6;4110:20;4149:31;4177:2;4149:31;:::i;:::-;4209:2;4203:9;4221:31;4249:2;4241:6;4221:31;:::i;:::-;4276:2;4268:6;4261:18;4322:3;4315:4;4310:2;4302:6;4298:15;4294:26;4291:35;4288:55;;;4339:1;4336;4329:12;4288:55;4403:2;4396:4;4388:6;4384:17;4377:4;4369:6;4365:17;4352:54;4450:1;4426:15;;;4443:4;4422:26;4415:37;;;;-1:-1:-1;4430:6:1;3974:508;-1:-1:-1;;;3974:508:1:o;4487:943::-;4641:6;4649;4657;4665;4673;4726:3;4714:9;4705:7;4701:23;4697:33;4694:53;;;4743:1;4740;4733:12;4694:53;4766:29;4785:9;4766:29;:::i;:::-;4756:39;;4814:38;4848:2;4837:9;4833:18;4814:38;:::i;:::-;4804:48;;4903:2;4892:9;4888:18;4875:32;-1:-1:-1;;;;;4967:2:1;4959:6;4956:14;4953:34;;;4983:1;4980;4973:12;4953:34;5006:61;5059:7;5050:6;5039:9;5035:22;5006:61;:::i;:::-;4996:71;;5120:2;5109:9;5105:18;5092:32;5076:48;;5149:2;5139:8;5136:16;5133:36;;;5165:1;5162;5155:12;5133:36;5188:63;5243:7;5232:8;5221:9;5217:24;5188:63;:::i;:::-;5178:73;;5304:3;5293:9;5289:19;5276:33;5260:49;;5334:2;5324:8;5321:16;5318:36;;;5350:1;5347;5340:12;5318:36;;5373:51;5416:7;5405:8;5394:9;5390:24;5373:51;:::i;:::-;5363:61;;;4487:943;;;;;;;;:::o;5624:186::-;5683:6;5736:2;5724:9;5715:7;5711:23;5707:32;5704:52;;;5752:1;5749;5742:12;5704:52;5775:29;5794:9;5775:29;:::i;5815:1208::-;5933:6;5941;5994:2;5982:9;5973:7;5969:23;5965:32;5962:52;;;6010:1;6007;6000:12;5962:52;6050:9;6037:23;-1:-1:-1;;;;;6120:2:1;6112:6;6109:14;6106:34;;;6136:1;6133;6126:12;6106:34;6174:6;6163:9;6159:22;6149:32;;6219:7;6212:4;6208:2;6204:13;6200:27;6190:55;;6241:1;6238;6231:12;6190:55;6277:2;6264:16;6299:4;6322:43;6362:2;6322:43;:::i;:::-;6394:2;6388:9;6406:31;6434:2;6426:6;6406:31;:::i;:::-;6472:18;;;6560:1;6556:10;;;;6548:19;;6544:28;;;6506:15;;;;-1:-1:-1;6584:19:1;;;6581:39;;;6616:1;6613;6606:12;6581:39;6640:11;;;;6660:148;6676:6;6671:3;6668:15;6660:148;;;6742:23;6761:3;6742:23;:::i;:::-;6730:36;;6693:12;;;;6786;;;;6660:148;;;6827:6;-1:-1:-1;;6871:18:1;;6858:32;;-1:-1:-1;;6902:16:1;;;6899:36;;;6931:1;6928;6921:12;6899:36;;6954:63;7009:7;6998:8;6987:9;6983:24;6954:63;:::i;:::-;6944:73;;;5815:1208;;;;;:::o;7028:435::-;7081:3;7119:5;7113:12;7146:6;7141:3;7134:19;7172:4;7201:2;7196:3;7192:12;7185:19;;7238:2;7231:5;7227:14;7259:1;7269:169;7283:6;7280:1;7277:13;7269:169;;;7344:13;;7332:26;;7378:12;;;;7413:15;;;;7305:1;7298:9;7269:169;;;-1:-1:-1;7454:3:1;;7028:435;-1:-1:-1;;;;;7028:435:1:o;7468:261::-;7647:2;7636:9;7629:21;7610:4;7667:56;7719:2;7708:9;7704:18;7696:6;7667:56;:::i;8177:160::-;8242:20;;8298:13;;8291:21;8281:32;;8271:60;;8327:1;8324;8317:12;8342:254;8407:6;8415;8468:2;8456:9;8447:7;8443:23;8439:32;8436:52;;;8484:1;8481;8474:12;8436:52;8507:29;8526:9;8507:29;:::i;:::-;8497:39;;8555:35;8586:2;8575:9;8571:18;8555:35;:::i;:::-;8545:45;;8342:254;;;;;:::o;8601:180::-;8657:6;8710:2;8698:9;8689:7;8685:23;8681:32;8678:52;;;8726:1;8723;8716:12;8678:52;8749:26;8765:9;8749:26;:::i;8786:260::-;8854:6;8862;8915:2;8903:9;8894:7;8890:23;8886:32;8883:52;;;8931:1;8928;8921:12;8883:52;8954:29;8973:9;8954:29;:::i;:::-;8944:39;;9002:38;9036:2;9025:9;9021:18;9002:38;:::i;9051:606::-;9155:6;9163;9171;9179;9187;9240:3;9228:9;9219:7;9215:23;9211:33;9208:53;;;9257:1;9254;9247:12;9208:53;9280:29;9299:9;9280:29;:::i;:::-;9270:39;;9328:38;9362:2;9351:9;9347:18;9328:38;:::i;:::-;9318:48;;9413:2;9402:9;9398:18;9385:32;9375:42;;9464:2;9453:9;9449:18;9436:32;9426:42;;9519:3;9508:9;9504:19;9491:33;-1:-1:-1;;;;;9539:6:1;9536:30;9533:50;;;9579:1;9576;9569:12;9533:50;9602:49;9643:7;9634:6;9623:9;9619:22;9602:49;:::i;10073:127::-;10134:10;10129:3;10125:20;10122:1;10115:31;10165:4;10162:1;10155:15;10189:4;10186:1;10179:15;10205:380;10284:1;10280:12;;;;10327;;;10348:61;;10402:4;10394:6;10390:17;10380:27;;10348:61;10455:2;10447:6;10444:14;10424:18;10421:38;10418:161;;10501:10;10496:3;10492:20;10489:1;10482:31;10536:4;10533:1;10526:15;10564:4;10561:1;10554:15;10418:161;;10205:380;;;:::o;10777:291::-;10954:6;10943:9;10936:25;10997:2;10992;10981:9;10977:18;10970:30;10917:4;11017:45;11058:2;11047:9;11043:18;11035:6;11017:45;:::i;:::-;11009:53;10777:291;-1:-1:-1;;;;10777:291:1:o;11073:690::-;11153:6;11206:2;11194:9;11185:7;11181:23;11177:32;11174:52;;;11222:1;11219;11212:12;11174:52;11255:9;11249:16;-1:-1:-1;;;;;11280:6:1;11277:30;11274:50;;;11320:1;11317;11310:12;11274:50;11343:22;;11396:4;11388:13;;11384:27;-1:-1:-1;11374:55:1;;11425:1;11422;11415:12;11374:55;11454:2;11448:9;11476:31;11504:2;11476:31;:::i;:::-;11536:2;11530:9;11548:31;11576:2;11568:6;11548:31;:::i;:::-;11603:2;11595:6;11588:18;11643:7;11638:2;11633;11629;11625:11;11621:20;11618:33;11615:53;;;11664:1;11661;11654:12;11615:53;11677:55;11729:2;11724;11716:6;11712:15;11707:2;11703;11699:11;11677:55;:::i;:::-;11751:6;11073:690;-1:-1:-1;;;;;;11073:690:1:o;11768:410::-;11970:2;11952:21;;;12009:2;11989:18;;;11982:30;12048:34;12043:2;12028:18;;12021:62;-1:-1:-1;;;12114:2:1;12099:18;;12092:44;12168:3;12153:19;;11768:410::o;12803:127::-;12864:10;12859:3;12855:20;12852:1;12845:31;12895:4;12892:1;12885:15;12919:4;12916:1;12909:15;12935:135;12974:3;12995:17;;;12992:43;;13015:18;;:::i;:::-;-1:-1:-1;13062:1:1;13051:13;;12935:135::o;13482:127::-;13543:10;13538:3;13534:20;13531:1;13524:31;13574:4;13571:1;13564:15;13598:4;13595:1;13588:15;13614:112;13646:1;13672;13662:35;;13677:18;;:::i;:::-;-1:-1:-1;13711:9:1;;13614:112::o;13731:120::-;13771:1;13797;13787:35;;13802:18;;:::i;:::-;-1:-1:-1;13836:9:1;;13731:120::o;16183:402::-;16385:2;16367:21;;;16424:2;16404:18;;;16397:30;16463:34;16458:2;16443:18;;16436:62;-1:-1:-1;;;16529:2:1;16514:18;;16507:36;16575:3;16560:19;;16183:402::o;17360:401::-;17562:2;17544:21;;;17601:2;17581:18;;;17574:30;17640:34;17635:2;17620:18;;17613:62;-1:-1:-1;;;17706:2:1;17691:18;;17684:35;17751:3;17736:19;;17360:401::o;17766:406::-;17968:2;17950:21;;;18007:2;17987:18;;;17980:30;18046:34;18041:2;18026:18;;18019:62;-1:-1:-1;;;18112:2:1;18097:18;;18090:40;18162:3;18147:19;;17766:406::o;18177:168::-;18217:7;18283:1;18279;18275:6;18271:14;18268:1;18265:21;18260:1;18253:9;18246:17;18242:45;18239:71;;;18290:18;;:::i;:::-;-1:-1:-1;18330:9:1;;18177:168::o;18350:465::-;18607:2;18596:9;18589:21;18570:4;18633:56;18685:2;18674:9;18670:18;18662:6;18633:56;:::i;:::-;18737:9;18729:6;18725:22;18720:2;18709:9;18705:18;18698:50;18765:44;18802:6;18794;18765:44;:::i;:::-;18757:52;18350:465;-1:-1:-1;;;;;18350:465:1:o;19483:125::-;19523:4;19551:1;19548;19545:8;19542:34;;;19556:18;;:::i;:::-;-1:-1:-1;19593:9:1;;19483:125::o;19613:827::-;-1:-1:-1;;;;;20010:15:1;;;19992:34;;20062:15;;20057:2;20042:18;;20035:43;19972:3;20109:2;20094:18;;20087:31;;;19935:4;;20141:57;;20178:19;;20170:6;20141:57;:::i;:::-;20246:9;20238:6;20234:22;20229:2;20218:9;20214:18;20207:50;20280:44;20317:6;20309;20280:44;:::i;:::-;20266:58;;20373:9;20365:6;20361:22;20355:3;20344:9;20340:19;20333:51;20401:33;20427:6;20419;20401:33;:::i;:::-;20393:41;19613:827;-1:-1:-1;;;;;;;;19613:827:1:o;20445:249::-;20514:6;20567:2;20555:9;20546:7;20542:23;20538:32;20535:52;;;20583:1;20580;20573:12;20535:52;20615:9;20609:16;20634:30;20658:5;20634:30;:::i;20699:179::-;20734:3;20776:1;20758:16;20755:23;20752:120;;;20822:1;20819;20816;20801:23;-1:-1:-1;20859:1:1;20853:8;20848:3;20844:18;20752:120;20699:179;:::o;20883:671::-;20922:3;20964:4;20946:16;20943:26;20940:39;;;20883:671;:::o;20940:39::-;21006:2;21000:9;-1:-1:-1;;21071:16:1;21067:25;;21064:1;21000:9;21043:50;21122:4;21116:11;21146:16;-1:-1:-1;;;;;21252:2:1;21245:4;21237:6;21233:17;21230:25;21225:2;21217:6;21214:14;21211:45;21208:58;;;21259:5;;;;;20883:671;:::o;21208:58::-;21296:6;21290:4;21286:17;21275:28;;21332:3;21326:10;21359:2;21351:6;21348:14;21345:27;;;21365:5;;;;;;20883:671;:::o;21345:27::-;21449:2;21430:16;21424:4;21420:27;21416:36;21409:4;21400:6;21395:3;21391:16;21387:27;21384:69;21381:82;;;21456:5;;;;;;20883:671;:::o;21381:82::-;21472:57;21523:4;21514:6;21506;21502:19;21498:30;21492:4;21472:57;:::i;:::-;-1:-1:-1;21545:3:1;;20883:671;-1:-1:-1;;;;;20883:671:1:o;21980:404::-;22182:2;22164:21;;;22221:2;22201:18;;;22194:30;22260:34;22255:2;22240:18;;22233:62;-1:-1:-1;;;22326:2:1;22311:18;;22304:38;22374:3;22359:19;;21980:404::o;22389:561::-;-1:-1:-1;;;;;22686:15:1;;;22668:34;;22738:15;;22733:2;22718:18;;22711:43;22785:2;22770:18;;22763:34;;;22828:2;22813:18;;22806:34;;;22648:3;22871;22856:19;;22849:32;;;22611:4;;22898:46;;22924:19;;22916:6;22898:46;:::i;:::-;22890:54;22389:561;-1:-1:-1;;;;;;;22389:561:1:o;22955:128::-;22995:3;23026:1;23022:6;23019:1;23016:13;23013:39;;;23032:18;;:::i;:::-;-1:-1:-1;23068:9:1;;22955:128::o

Swarm Source

ipfs://c40a85e8214fb4968a77790b405815eb958ef3296e0cd897862089cfbca31ded
Loading...
Loading
Loading...
Loading
[ 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.