Token 3DSLOTHTY

Overview CRC721

Total Supply:
3,718 3DSLOTHTY

Holders:
667 addresses
Balance
3 3DSLOTHTY
0x634a5dc4cda63ea8d0699d9387cdcfffc6408b84
Loading
[ Download CSV Export  ] 
Loading
[ Download CSV Export  ] 
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
Slothty

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at cronoscan.com on 2022-04-04
*/

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

// File @openzeppelin/contracts/utils/[email protected]


// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)

pragma solidity ^0.8.0;

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

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

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

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

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}


// File @openzeppelin/contracts/token/ERC20/[email protected]


// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)

pragma solidity ^0.8.0;

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

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

    /**
     * @dev Moves `amount` tokens from the caller's account to `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);

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


// File @openzeppelin/contracts/utils/introspection/[email protected]


// OpenZeppelin Contracts v4.4.1 (utils/introspection/IERC165.sol)

pragma solidity ^0.8.0;

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


// File @openzeppelin/contracts/token/ERC721/[email protected]


// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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


// File contracts/SafeMathLite.sol


pragma solidity ^0.8.4;
library SafeMathLite{

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }
}


// File contracts/SafePct.sol


pragma solidity ^0.8.4;

/**
 * @dev Compute percentages safely without phantom overflows.
 *
 * Intermediate operations can overflow even when the result will always
 * fit into computed type. Developers usually
 * assume that overflows raise errors. `SafePct` restores this intuition by
 * reverting the transaction when such an operation overflows.
 *
 * Using this library instead of the unchecked operations eliminates an entire
 * class of bugs, so it's recommended to use it always.
 *
 * Can be combined with {SafeMath} and {SignedSafeMath} to extend it to smaller types, by performing
 * all math on `uint256` and `int256` and then downcasting.
 */

library SafePct {
    using SafeMathLite for uint256;
    /**
     * Requirements:
     *
     * - intermediate operations must revert on overflow
     */
    function mulDiv(uint256 x, uint256 y, uint256 z) internal pure returns (uint256) {
        require(z > 0, "Division by zero");

        if (x == 0) return 0;
        uint256 xy = x * y;
        if (xy / x == y) { // no overflow happened - same as in SafeMath mul
            return xy / z;
        }

        //slither-disable-next-line divide-before-multiply
        uint256 a = x / z;
        uint256 b = x % z; // x = a * z + b

        //slither-disable-next-line divide-before-multiply
        uint256 c = y / z;
        uint256 d = y % z; // y = c * z + d

        return (a.mul(c).mul(z)).add(a.mul(d)).add(b.mul(c)).add(b.mul(d).div(z));
    }


}


// File @openzeppelin/contracts/token/ERC1155/[email protected]


// OpenZeppelin Contracts v4.4.1 (token/ERC1155/IERC1155.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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


// File @openzeppelin/contracts/token/ERC1155/[email protected]


// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)

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


// File @openzeppelin/contracts/token/ERC1155/extensions/[email protected]


// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)

pragma solidity ^0.8.0;

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


// File @openzeppelin/contracts/utils/[email protected]


// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [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 functionCall(target, data, "Address: low-level call failed");
    }

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

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

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

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

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

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

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

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

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

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

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

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


// File @openzeppelin/contracts/utils/[email protected]


// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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


// File @openzeppelin/contracts/utils/introspection/[email protected]


// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

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


// File @openzeppelin/contracts/token/ERC1155/[email protected]


// OpenZeppelin Contracts v4.4.1 (token/ERC1155/ERC1155.sol)

pragma solidity ^0.8.0;






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

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

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

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

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

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

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

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

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

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

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

        return batchBalances;
    }

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

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

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

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

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

        address operator = _msgSender();

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

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

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

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

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

        address operator = _msgSender();

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

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

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

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

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

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

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

        address operator = _msgSender();

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

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

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

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

        address operator = _msgSender();

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

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

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

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

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

        address operator = _msgSender();

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

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

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

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

        address operator = _msgSender();

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

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

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

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

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

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

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

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

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

        return array;
    }
}


// File @openzeppelin/contracts/token/ERC721/[email protected]


// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

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


// File @openzeppelin/contracts/token/ERC721/extensions/[email protected]


// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;

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

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

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


// File @openzeppelin/contracts/utils/[email protected]


// OpenZeppelin Contracts v4.4.1 (utils/Strings.sol)

pragma solidity ^0.8.0;

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

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

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

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

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


// File @openzeppelin/contracts/token/ERC721/[email protected]


// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;







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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        return owner;
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

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

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string(abi.encodePacked(baseURI, tokenId.toString())) : "";
    }

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be overriden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

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

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

        _afterTokenTransfer(address(0), to, tokenId);
    }

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

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

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

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

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

        _afterTokenTransfer(owner, address(0), tokenId);
    }

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

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId);
    }

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

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

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

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

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}


// File @openzeppelin/contracts/token/ERC721/extensions/[email protected]


// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;

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

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

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


// File @openzeppelin/contracts/token/ERC721/extensions/[email protected]


// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/ERC721Enumerable.sol)

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


// File @openzeppelin/contracts/access/[email protected]


// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

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 Returns the address of the current owner.
     */
    function owner() public view virtual returns (address) {
        return _owner;
    }

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

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

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

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


// File @openzeppelin/contracts/utils/escrow/[email protected]


// OpenZeppelin Contracts v4.4.1 (utils/escrow/Escrow.sol)

pragma solidity ^0.8.0;


/**
 * @title Escrow
 * @dev Base escrow contract, holds funds designated for a payee until they
 * withdraw them.
 *
 * Intended usage: This contract (and derived escrow contracts) should be a
 * standalone contract, that only interacts with the contract that instantiated
 * it. That way, it is guaranteed that all Ether will be handled according to
 * the `Escrow` rules, and there is no need to check for payable functions or
 * transfers in the inheritance tree. The contract that uses the escrow as its
 * payment method should be its owner, and provide public methods redirecting
 * to the escrow's deposit and withdraw.
 */
contract Escrow is Ownable {
    using Address for address payable;

    event Deposited(address indexed payee, uint256 weiAmount);
    event Withdrawn(address indexed payee, uint256 weiAmount);

    mapping(address => uint256) private _deposits;

    function depositsOf(address payee) public view returns (uint256) {
        return _deposits[payee];
    }

    /**
     * @dev Stores the sent amount as credit to be withdrawn.
     * @param payee The destination address of the funds.
     */
    function deposit(address payee) public payable virtual onlyOwner {
        uint256 amount = msg.value;
        _deposits[payee] += amount;
        emit Deposited(payee, amount);
    }

    /**
     * @dev Withdraw accumulated balance for a payee, forwarding all gas to the
     * recipient.
     *
     * WARNING: Forwarding all gas opens the door to reentrancy vulnerabilities.
     * Make sure you trust the recipient, or are either following the
     * checks-effects-interactions pattern or using {ReentrancyGuard}.
     *
     * @param payee The address whose funds will be withdrawn and transferred to.
     */
    function withdraw(address payable payee) public virtual onlyOwner {
        uint256 payment = _deposits[payee];

        _deposits[payee] = 0;

        payee.sendValue(payment);

        emit Withdrawn(payee, payment);
    }
}


// File @openzeppelin/contracts/security/[email protected]


// OpenZeppelin Contracts v4.4.1 (security/PullPayment.sol)

pragma solidity ^0.8.0;

/**
 * @dev Simple implementation of a
 * https://consensys.github.io/smart-contract-best-practices/recommendations/#favor-pull-over-push-for-external-calls[pull-payment]
 * strategy, where the paying contract doesn't interact directly with the
 * receiver account, which must withdraw its payments itself.
 *
 * Pull-payments are often considered the best practice when it comes to sending
 * Ether, security-wise. It prevents recipients from blocking execution, and
 * eliminates reentrancy concerns.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 *
 * To use, derive from the `PullPayment` contract, and use {_asyncTransfer}
 * instead of Solidity's `transfer` function. Payees can query their due
 * payments with {payments}, and retrieve them with {withdrawPayments}.
 */
abstract contract PullPayment {
    Escrow private  immutable  _escrow;

    constructor() {
        _escrow = new Escrow();
    }

    /**
     * @dev Withdraw accumulated payments, forwarding all gas to the recipient.
     *
     * Note that _any_ account can call this function, not just the `payee`.
     * This means that contracts unaware of the `PullPayment` protocol can still
     * receive funds this way, by having a separate account call
     * {withdrawPayments}.
     *
     * WARNING: Forwarding all gas opens the door to reentrancy vulnerabilities.
     * Make sure you trust the recipient, or are either following the
     * checks-effects-interactions pattern or using {ReentrancyGuard}.
     *
     * @param payee Whose payments will be withdrawn.
     */
    function withdrawPayments(address payable payee) public virtual {
        _escrow.withdraw(payee);
    }

    /**
     * @dev Returns the payments owed to an address.
     * @param dest The creditor's address.
     */
    function payments(address dest) public view returns (uint256) {
        return _escrow.depositsOf(dest);
    }

    /**
     * @dev Called by the payer to store the sent amount as credit to be pulled.
     * Funds sent in this way are stored in an intermediate {Escrow} contract, so
     * there is no danger of them being spent before withdrawal.
     *
     * @param dest The destination address of the funds.
     * @param amount The amount to transfer.
     */
    function _asyncTransfer(address dest, uint256 amount) internal virtual {
        _escrow.deposit{value: amount}(dest);
    }
}


// File @openzeppelin/contracts/security/[email protected]


// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol)

pragma solidity ^0.8.0;

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

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

    bool private _paused;

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

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

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

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

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

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


// File @openzeppelin/contracts/security/[email protected]


// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;

        _;

        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }
}


// File contracts/BaseDrop.sol


pragma solidity ^0.8.4;
abstract contract BaseDrop is ERC721Enumerable, Ownable, PullPayment, Pausable, ReentrancyGuard {
    using Address for address payable;
   
    ERC1155 public memberships;
    address public artist;
    uint128 constant internal SCALE = 10000;
    uint128 internal fee = 2500;
    uint16[] internal order;

    function isMember(address _address) public view returns (bool) {
        return memberships.balanceOf(_address, 1) > 0 || memberships.balanceOf(_address, 2) > 0;
    }

    function withdrawPayments(address payable payee) public virtual override nonReentrant{
        super.withdrawPayments(payee);
    }

    // The following functions are overrides required by Solidity.
    function _beforeTokenTransfer(address from, address to, uint256 tokenId) internal override {
        super._beforeTokenTransfer(from, to, tokenId);
    }

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

    function withdraw() public virtual onlyOwner{
        payable(msg.sender).sendValue(address(this).balance);
    }

    function pause() public onlyOwner{
        _pause();
    }

    function unpause() public onlyOwner{
        _unpause();
    }
}


// File contracts/interfaces/IDrop.sol


pragma solidity ^0.8.4;


interface IDrop {
    struct Info {
        uint256 regularCost;
        uint256 memberCost;
        uint256 whitelistCost;
        uint256 maxSupply;
        uint256 totalSupply;
        uint256 maxMintPerAddress;
        uint256 maxMintPerTx;
    }
    
    function mintCost(address _minter) external view returns(uint256);
    function canMint(address _minter) external view returns (uint256);
    function mint(uint256 _amount) external payable;
    function maxSupply() external view returns (uint256);
    function getInfo() external view returns (Info memory);
}


// File contracts/drops/Slothty.sol


pragma solidity ^0.8.4;
contract Slothty is IDrop, BaseDrop {
    using Counters for Counters.Counter;
    using SafePct for uint256;
    using SafeMathLite for uint256;
    Counters.Counter public _tokenIdCounter;
    Counters.Counter public _artistCounter;

    uint256 private memberCost = 249 ether;
    uint256 private whitelistCost = 249 ether;
    uint256 private regularCost = 299 ether;
    uint64 constant MAX_TOKENS = 8888;
    uint8 constant MAX_MINTAMOUNT = 10;
    uint8 private currentChunkIndex;
    mapping(address => bool) whitelist;
    string baseURI = "ipfs://QmNWJw5VZKkbiGKEaUEViniYQHDV3rc15R4EHBj1xPoCw3";
    bool public revealed = false;
    string public notRevealedUri = "ipfs://Qmc4bJhZqbuSi7N15AtStyBV4BvxEvqP1X1RJpfNUuYLHF/Hidden.json";
    constructor(address _memberships, address _artist) ERC721("3DSLOTHTY", "3DSLOTHTY") {
        memberships = ERC1155(_memberships);
        artist = _artist;
        fee = 1000;

        _artistCounter.increment();
    }

    function getLen() public view returns(uint) {
        return order.length;
    }

    function addWhitelistAddress(address _address) public onlyOwner {
        whitelist[_address] = true;
    }

    function addWhiteList(address[] calldata _addresses) public onlyOwner {
        uint len = _addresses.length;
        for(uint i = 0; i < len; i ++) {
            whitelist[_addresses[i]] = true;
        }        
    }

    function removeWhiteList(address _address) public onlyOwner {
        if (whitelist[_address]) {
            delete whitelist[_address];
        }
    }
    
    function isWhiteList(address _address) public view returns (bool) {
        return whitelist[_address];
    }
    
    function setSequnceChunk(uint8 _chunkIndex, uint16[] calldata _chunk) public onlyOwner {
        require(currentChunkIndex <= _chunkIndex, "chunkIndex exists");
        if (_chunkIndex == 0) {
            order = _chunk;
        } else {
            uint len = _chunk.length;
            for(uint i = 0; i < len; i ++) {
                order.push(_chunk[i]);
            }
        }
        currentChunkIndex = _chunkIndex + 1;
    }

    function getInfo() external override view returns (Info memory) {
        Info memory allInfo;

        allInfo.regularCost = regularCost;
        allInfo.memberCost = memberCost;
        allInfo.whitelistCost = whitelistCost;
        allInfo.maxSupply = MAX_TOKENS;
        allInfo.totalSupply = super.totalSupply();
        allInfo.maxMintPerTx = MAX_MINTAMOUNT;

        return allInfo;
    }

    function mintCost(address _minter) external override view returns(uint256) {
        if (isMember(_minter)) {
            return memberCost;
        } else if (isWhiteList(_minter)) {
            return whitelistCost;
        } else {
            return regularCost;
        }
    }
    
    function setMemberCost(uint256 _cost) external onlyOwner {
        memberCost = _cost;
    }

    function setWhitelistCost(uint256 _cost) external onlyOwner {
        whitelistCost = _cost;
    }

    function setRegularCost(uint256 _cost) external onlyOwner {
        regularCost = _cost;
    }

    function mintForArtist(uint256 num) external onlyOwner {
        uint256 current = _artistCounter.current();
        for (uint i = current; i < current + num; i ++) {
            _safeMint(artist, i);
            _artistCounter.increment();
        }
    }

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

    function airdropMint(address _sender, uint256 _amount) external onlyOwner{
        for (uint256 i = 0; i < _amount; i ++) {
            safeMint(_sender);
        }
    }

    function mint(uint256 _amount) external override payable whenNotPaused {
        require(_amount <= MAX_MINTAMOUNT, "not mint more than max amount");

        uint256 price;
        bool _isMember = isMember(msg.sender);
        
        if (_isMember) {
           price = memberCost.mul(_amount);  
        } else {
            bool _isDiscount = isWhiteList(msg.sender);
            if (_isDiscount) {
                price = whitelistCost.mul(_amount); 
            } else {
                price = regularCost.mul(_amount); 
            }
        }

        require(msg.value >= price, "not enough funds");
       
        uint256 amountFee = price.mulDiv(fee, SCALE); 
        for(uint256 i = 0; i < _amount; i++){
            safeMint(msg.sender);
        }

        _asyncTransfer(artist, price - amountFee);
    }

    function reveal() public onlyOwner {
        revealed = true;
    }
    
    function setNotRevealedURI(string memory _notRevealedURI) public onlyOwner {
        notRevealedUri = _notRevealedURI;
    }

    function tokenURI(uint _tokenId) public view virtual override returns (string memory) {
      require(_exists(_tokenId),"ERC721Metadata: URI query for nonexistent token");
      if(revealed == false) {
            return notRevealedUri;
        }
      string memory _tokenURI = string(abi.encodePacked(baseURI, "/", Strings.toString(_tokenId), ".json"));

      return _tokenURI;
    }

   function safeMint(address _to) private {
        uint256 tokenId;
        
        tokenId = _tokenIdCounter.current();
        
        // consider we mint 35 nfts for aritst;
        require(tokenId < MAX_TOKENS - 100, "sold out!");
        _tokenIdCounter.increment();

        _safeMint(_to, order[tokenId]);
    }

    function maxSupply() external override pure returns (uint256) {
        return MAX_TOKENS;
    }

    function canMint(address) external override pure returns (uint256) {
        return MAX_MINTAMOUNT;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_memberships","type":"address"},{"internalType":"address","name":"_artist","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"_artistCounter","outputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"_tokenIdCounter","outputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"_addresses","type":"address[]"}],"name":"addWhiteList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"addWhitelistAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_sender","type":"address"},{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"airdropMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"artist","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"canMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getInfo","outputs":[{"components":[{"internalType":"uint256","name":"regularCost","type":"uint256"},{"internalType":"uint256","name":"memberCost","type":"uint256"},{"internalType":"uint256","name":"whitelistCost","type":"uint256"},{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"uint256","name":"totalSupply","type":"uint256"},{"internalType":"uint256","name":"maxMintPerAddress","type":"uint256"},{"internalType":"uint256","name":"maxMintPerTx","type":"uint256"}],"internalType":"struct IDrop.Info","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getLen","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"isMember","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"isWhiteList","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[],"name":"memberships","outputs":[{"internalType":"contract ERC1155","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_minter","type":"address"}],"name":"mintCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"num","type":"uint256"}],"name":"mintForArtist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"notRevealedUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"dest","type":"address"}],"name":"payments","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_address","type":"address"}],"name":"removeWhiteList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cost","type":"uint256"}],"name":"setMemberCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_notRevealedURI","type":"string"}],"name":"setNotRevealedURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cost","type":"uint256"}],"name":"setRegularCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"_chunkIndex","type":"uint8"},{"internalType":"uint16[]","name":"_chunk","type":"uint16[]"}],"name":"setSequnceChunk","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cost","type":"uint256"}],"name":"setWhitelistCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"payee","type":"address"}],"name":"withdrawPayments","outputs":[],"stateMutability":"nonpayable","type":"function"}]

600e80546001600160801b0319166109c4179055680d7f91b4bdd044000060128190556013556810357563d481cc0000601455610100604052603560a08181529062003e6c60c03980516200005d9160179160209091019062000254565b506018805460ff191690556040805160808101909152604180825262003ea160208301398051620000979160199160209091019062000254565b50348015620000a557600080fd5b5060405162003ee238038062003ee2833981016040819052620000c89162000325565b6040805180820182526009808252683344534c4f5448545960b81b6020808401828152855180870190965292855284015281519192916200010c9160009162000254565b5080516200012290600190602084019062000254565b5050506200013f62000139620001f560201b60201c565b620001f9565b6040516200014d90620002e3565b604051809103906000f0801580156200016a573d6000803e3d6000fd5b5060601b6001600160601b031916608052600a805460ff60a01b191690556001600b55600c80546001600160a01b03199081166001600160a01b0385811691909117909255600d8054909116918316919091179055600e80546103e86001600160801b0319909116179055620001ed60116200024b602090811b62001b7a17901c565b505062000399565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b80546001019055565b82805462000262906200035c565b90600052602060002090601f016020900481019282620002865760008555620002d1565b82601f10620002a157805160ff1916838001178555620002d1565b82800160010185558215620002d1579182015b82811115620002d1578251825591602001919060010190620002b4565b50620002df929150620002f1565b5090565b6105ef806200387d83390190565b5b80821115620002df5760008155600101620002f2565b80516001600160a01b03811681146200032057600080fd5b919050565b6000806040838503121562000338578182fd5b620003438362000308565b9150620003536020840162000308565b90509250929050565b600181811c908216806200037157607f821691505b602082108114156200039357634e487b7160e01b600052602260045260246000fd5b50919050565b60805160601c6134b7620003c660003960008181611a2901528181611f8b01526123d801526134b76000f3fe6080604052600436106102e45760003560e01c80635e1045ec11610190578063b88d4fde116100dc578063dc09e92311610095578063e985e9c51161006f578063e985e9c5146108be578063f2c4ce1e14610907578063f2fde38b14610927578063f99031a71461094757600080fd5b8063dc09e9231461085e578063e1ec62941461087e578063e2982c211461089e57600080fd5b8063b88d4fde146107a8578063b88fe6a3146107c8578063c2ba4744146107e8578063c87b56dd14610809578063d49479eb14610829578063d5abeb011461084957600080fd5b80638da5cb5b11610149578063a0712d6811610123578063a0712d6814610740578063a22cb46514610753578063a230c52414610773578063a475b5dd1461079357600080fd5b80638da5cb5b146106ed57806394a7ef151461070b57806395d89b411461072b57600080fd5b80635e1045ec1461064c5780636352211e1461066c57806370a082311461068c578063715018a6146106ac5780638456cb59146106c157806384c4bd4b146106d657600080fd5b806331b3eb941161024f5780634a90be57116102085780635393554a116101e25780635393554a1461058257806355f804b3146105a25780635a9b0b89146105c25780635c975abb1461062d57600080fd5b80634a90be57146105335780634f6ccce714610548578063518302271461056857600080fd5b806331b3eb94146104895780633b3c523a146104a95780633ccfd60b146104c95780633f4ba83a146104de57806342842e0e146104f357806343bc16121461051357600080fd5b806318160ddd116102a157806318160ddd146103d45780632042e5c2146103e957806322ad06701461040957806323b872dd146104295780632acc659e146104495780632f745c591461046957600080fd5b806301ffc9a7146102e95780630385e9601461031e57806306fdde0314610343578063081812fc14610365578063081c8c441461039d578063095ea7b3146103b2575b600080fd5b3480156102f557600080fd5b50610309610304366004612f6c565b610980565b60405190151581526020015b60405180910390f35b34801561032a57600080fd5b506011546103359081565b604051908152602001610315565b34801561034f57600080fd5b50610358610991565b60405161031591906131e3565b34801561037157600080fd5b5061038561038036600461300c565b610a23565b6040516001600160a01b039091168152602001610315565b3480156103a957600080fd5b50610358610abd565b3480156103be57600080fd5b506103d26103cd366004612f01565b610b4b565b005b3480156103e057600080fd5b50600854610335565b3480156103f557600080fd5b506103d2610404366004612dbf565b610c61565b34801561041557600080fd5b506103d2610424366004612f01565b610cd0565b34801561043557600080fd5b506103d2610444366004612e13565b610d20565b34801561045557600080fd5b50610335610464366004612dbf565b610d51565b34801561047557600080fd5b50610335610484366004612f01565b610d9a565b34801561049557600080fd5b506103d26104a4366004612dbf565b610e30565b3480156104b557600080fd5b506103d26104c436600461303c565b610e99565b3480156104d557600080fd5b506103d2610fdf565b3480156104ea57600080fd5b506103d2611015565b3480156104ff57600080fd5b506103d261050e366004612e13565b611047565b34801561051f57600080fd5b50600d54610385906001600160a01b031681565b34801561053f57600080fd5b50600f54610335565b34801561055457600080fd5b5061033561056336600461300c565b611062565b34801561057457600080fd5b506018546103099060ff1681565b34801561058e57600080fd5b506103d261059d36600461300c565b611103565b3480156105ae57600080fd5b506103d26105bd366004612fa4565b611183565b3480156105ce57600080fd5b506105d76111c4565b6040516103159190600060e082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015292915050565b34801561063957600080fd5b50600a54600160a01b900460ff16610309565b34801561065857600080fd5b506103d2610667366004612f2c565b611275565b34801561067857600080fd5b5061038561068736600461300c565b611326565b34801561069857600080fd5b506103356106a7366004612dbf565b61139d565b3480156106b857600080fd5b506103d2611424565b3480156106cd57600080fd5b506103d2611458565b3480156106e257600080fd5b506010546103359081565b3480156106f957600080fd5b50600a546001600160a01b0316610385565b34801561071757600080fd5b506103d2610726366004612dbf565b61148a565b34801561073757600080fd5b506103586114d8565b6103d261074e36600461300c565b6114e7565b34801561075f57600080fd5b506103d261076e366004612ed0565b61169d565b34801561077f57600080fd5b5061030961078e366004612dbf565b6116a8565b34801561079f57600080fd5b506103d26117bf565b3480156107b457600080fd5b506103d26107c3366004612e53565b6117f8565b3480156107d457600080fd5b50600c54610385906001600160a01b031681565b3480156107f457600080fd5b50610335610803366004612dbf565b50600a90565b34801561081557600080fd5b5061035861082436600461300c565b61182a565b34801561083557600080fd5b506103d261084436600461300c565b61197a565b34801561085557600080fd5b506122b8610335565b34801561086a57600080fd5b506103d261087936600461300c565b6119a9565b34801561088a57600080fd5b506103d261089936600461300c565b6119d8565b3480156108aa57600080fd5b506103356108b9366004612dbf565b611a07565b3480156108ca57600080fd5b506103096108d9366004612ddb565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561091357600080fd5b506103d2610922366004612fa4565b611aa5565b34801561093357600080fd5b506103d2610942366004612dbf565b611ae2565b34801561095357600080fd5b50610309610962366004612dbf565b6001600160a01b031660009081526016602052604090205460ff1690565b600061098b82611b83565b92915050565b6060600080546109a0906133aa565b80601f01602080910402602001604051908101604052809291908181526020018280546109cc906133aa565b8015610a195780601f106109ee57610100808354040283529160200191610a19565b820191906000526020600020905b8154815290600101906020018083116109fc57829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b0316610aa15760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60198054610aca906133aa565b80601f0160208091040260200160405190810160405280929190818152602001828054610af6906133aa565b8015610b435780601f10610b1857610100808354040283529160200191610b43565b820191906000526020600020905b815481529060010190602001808311610b2657829003601f168201915b505050505081565b6000610b5682611326565b9050806001600160a01b0316836001600160a01b03161415610bc45760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610a98565b336001600160a01b0382161480610be05750610be081336108d9565b610c525760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610a98565b610c5c8383611ba8565b505050565b600a546001600160a01b03163314610c8b5760405162461bcd60e51b8152600401610a9890613248565b6001600160a01b03811660009081526016602052604090205460ff1615610ccd576001600160a01b0381166000908152601660205260409020805460ff191690555b50565b600a546001600160a01b03163314610cfa5760405162461bcd60e51b8152600401610a9890613248565b60005b81811015610c5c57610d0e83611c16565b80610d18816133e5565b915050610cfd565b610d2a3382611cce565b610d465760405162461bcd60e51b8152600401610a989061327d565b610c5c838383611dc5565b6000610d5c826116a8565b15610d6957505060125490565b6001600160a01b03821660009081526016602052604090205460ff1615610d9257505060135490565b505060145490565b6000610da58361139d565b8210610e075760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610a98565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b6002600b541415610e835760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610a98565b6002600b55610e9181611f6c565b506001600b55565b600a546001600160a01b03163314610ec35760405162461bcd60e51b8152600401610a9890613248565b60155460ff80851691161115610f0f5760405162461bcd60e51b81526020600482015260116024820152706368756e6b496e6465782065786973747360781b6044820152606401610a98565b60ff8316610f2957610f23600f8383612bc9565b50610fbb565b8060005b81811015610fb857600f848483818110610f5757634e487b7160e01b600052603260045260246000fd5b9050602002016020810190610f6c9190612fea565b81546001810183556000928352602090922060108304018054600f9093166002026101000a61ffff81810219909416929093169290920217905580610fb0816133e5565b915050610f2d565b50505b610fc68360016132e6565b6015805460ff191660ff92909216919091179055505050565b600a546001600160a01b031633146110095760405162461bcd60e51b8152600401610a9890613248565b6110133347611fea565b565b600a546001600160a01b0316331461103f5760405162461bcd60e51b8152600401610a9890613248565b611013612103565b610c5c838383604051806020016040528060008152506117f8565b600061106d60085490565b82106110d05760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610a98565b600882815481106110f157634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050919050565b600a546001600160a01b0316331461112d5760405162461bcd60e51b8152600401610a9890613248565b600061113860115490565b9050805b61114683836132ce565b811015610c5c57600d54611163906001600160a01b0316826121a0565b611171601180546001019055565b8061117b816133e5565b91505061113c565b600a546001600160a01b031633146111ad5760405162461bcd60e51b8152600401610a9890613248565b80516111c0906017906020840190612c76565b5050565b6112046040518060e00160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6112446040518060e00160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6014548152601254602082015260135460408201526122b860608201526008546080820152600a60c0820152919050565b600a546001600160a01b0316331461129f5760405162461bcd60e51b8152600401610a9890613248565b8060005b81811015611320576001601660008686858181106112d157634e487b7160e01b600052603260045260246000fd5b90506020020160208101906112e69190612dbf565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905580611318816133e5565b9150506112a3565b50505050565b6000818152600260205260408120546001600160a01b03168061098b5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610a98565b60006001600160a01b0382166114085760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610a98565b506001600160a01b031660009081526003602052604090205490565b600a546001600160a01b0316331461144e5760405162461bcd60e51b8152600401610a9890613248565b61101360006121ba565b600a546001600160a01b031633146114825760405162461bcd60e51b8152600401610a9890613248565b61101361220c565b600a546001600160a01b031633146114b45760405162461bcd60e51b8152600401610a9890613248565b6001600160a01b03166000908152601660205260409020805460ff19166001179055565b6060600180546109a0906133aa565b600a54600160a01b900460ff16156115345760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610a98565b600a8111156115855760405162461bcd60e51b815260206004820152601d60248201527f6e6f74206d696e74206d6f7265207468616e206d617820616d6f756e740000006044820152606401610a98565b600080611591336116a8565b905080156115ad576012546115a69084612294565b91506115ec565b3360009081526016602052604090205460ff1680156115da576013546115d39085612294565b92506115ea565b6014546115e79085612294565b92505b505b8134101561162f5760405162461bcd60e51b815260206004820152601060248201526f6e6f7420656e6f7567682066756e647360801b6044820152606401610a98565b600e546000906116559084906fffffffffffffffffffffffffffffffff166127106122a7565b905060005b8481101561167d5761166b33611c16565b80611675816133e5565b91505061165a565b50600d54611320906001600160a01b0316611698838661333e565b6123b9565b6111c033838361243a565b600c54604051627eeac760e11b81526001600160a01b03838116600483015260016024830152600092839291169062fdd58e9060440160206040518083038186803b1580156116f657600080fd5b505afa15801561170a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061172e9190613024565b118061098b5750600c54604051627eeac760e11b81526001600160a01b03848116600483015260026024830152600092169062fdd58e9060440160206040518083038186803b15801561178057600080fd5b505afa158015611794573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b89190613024565b1192915050565b600a546001600160a01b031633146117e95760405162461bcd60e51b8152600401610a9890613248565b6018805460ff19166001179055565b6118023383611cce565b61181e5760405162461bcd60e51b8152600401610a989061327d565b61132084848484612509565b6000818152600260205260409020546060906001600160a01b03166118a95760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610a98565b60185460ff1661194557601980546118c0906133aa565b80601f01602080910402602001604051908101604052809291908181526020018280546118ec906133aa565b80156119395780601f1061190e57610100808354040283529160200191611939565b820191906000526020600020905b81548152906001019060200180831161191c57829003601f168201915b50505050509050919050565b600060176119528461253c565b6040516020016119639291906130dc565b60408051601f198184030181529190529392505050565b600a546001600160a01b031633146119a45760405162461bcd60e51b8152600401610a9890613248565b601355565b600a546001600160a01b031633146119d35760405162461bcd60e51b8152600401610a9890613248565b601255565b600a546001600160a01b03163314611a025760405162461bcd60e51b8152600401610a9890613248565b601455565b6040516371d4ed8d60e11b81526001600160a01b0382811660048301526000917f00000000000000000000000000000000000000000000000000000000000000009091169063e3a9db1a9060240160206040518083038186803b158015611a6d57600080fd5b505afa158015611a81573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098b9190613024565b600a546001600160a01b03163314611acf5760405162461bcd60e51b8152600401610a9890613248565b80516111c0906019906020840190612c76565b600a546001600160a01b03163314611b0c5760405162461bcd60e51b8152600401610a9890613248565b6001600160a01b038116611b715760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a98565b610ccd816121ba565b80546001019055565b60006001600160e01b0319821663780e9d6360e01b148061098b575061098b82612656565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611bdd82611326565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611c2160105490565b9050611c3060646122b8613355565b67ffffffffffffffff168110611c745760405162461bcd60e51b8152602060048201526009602482015268736f6c64206f75742160b81b6044820152606401610a98565b611c82601080546001019055565b6111c082600f8381548110611ca757634e487b7160e01b600052603260045260246000fd5b60009182526020909120601082040154600f9091166002026101000a900461ffff166121a0565b6000818152600260205260408120546001600160a01b0316611d475760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610a98565b6000611d5283611326565b9050806001600160a01b0316846001600160a01b03161480611d8d5750836001600160a01b0316611d8284610a23565b6001600160a01b0316145b80611dbd57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316611dd882611326565b6001600160a01b031614611e3c5760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610a98565b6001600160a01b038216611e9e5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610a98565b611ea98383836126a6565b611eb4600082611ba8565b6001600160a01b0383166000908152600360205260408120805460019290611edd90849061333e565b90915550506001600160a01b0382166000908152600360205260408120805460019290611f0b9084906132ce565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6040516351cff8d960e01b81526001600160a01b0382811660048301527f000000000000000000000000000000000000000000000000000000000000000016906351cff8d990602401600060405180830381600087803b158015611fcf57600080fd5b505af1158015611fe3573d6000803e3d6000fd5b5050505050565b8047101561203a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610a98565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612087576040519150601f19603f3d011682016040523d82523d6000602084013e61208c565b606091505b5050905080610c5c5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610a98565b600a54600160a01b900460ff166121535760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610a98565b600a805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6111c08282604051806020016040528060008152506126b1565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600a54600160a01b900460ff16156122595760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610a98565b600a805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586121833390565b60006122a0828461331f565b9392505050565b60008082116122eb5760405162461bcd60e51b815260206004820152601060248201526f4469766973696f6e206279207a65726f60801b6044820152606401610a98565b836122f8575060006122a0565b6000612304848661331f565b905083612311868361330b565b141561232957612321838261330b565b9150506122a0565b6000612335848761330b565b905060006123438588613400565b90506000612351868861330b565b9050600061235f8789613400565b90506123ac612378886123728685612294565b906126e4565b6123a66123858686612294565b6123a66123928987612294565b6123a68d6123a08c8b612294565b90612294565b906126f0565b9998505050505050505050565b60405163f340fa0160e01b81526001600160a01b0383811660048301527f0000000000000000000000000000000000000000000000000000000000000000169063f340fa019083906024016000604051808303818588803b15801561241d57600080fd5b505af1158015612431573d6000803e3d6000fd5b50505050505050565b816001600160a01b0316836001600160a01b0316141561249c5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610a98565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b612514848484611dc5565b612520848484846126fc565b6113205760405162461bcd60e51b8152600401610a98906131f6565b6060816125605750506040805180820190915260018152600360fc1b602082015290565b8160005b811561258a5780612574816133e5565b91506125839050600a8361330b565b9150612564565b60008167ffffffffffffffff8111156125b357634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156125dd576020820181803683370190505b5090505b8415611dbd576125f260018361333e565b91506125ff600a86613400565b61260a9060306132ce565b60f81b81838151811061262d57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535061264f600a8661330b565b94506125e1565b60006001600160e01b031982166380ac58cd60e01b148061268757506001600160e01b03198216635b5e139f60e01b145b8061098b57506301ffc9a760e01b6001600160e01b031983161461098b565b610c5c838383612809565b6126bb83836128c1565b6126c860008484846126fc565b610c5c5760405162461bcd60e51b8152600401610a98906131f6565b60006122a0828461330b565b60006122a082846132ce565b60006001600160a01b0384163b156127fe57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906127409033908990889088906004016131a6565b602060405180830381600087803b15801561275a57600080fd5b505af192505050801561278a575060408051601f3d908101601f1916820190925261278791810190612f88565b60015b6127e4573d8080156127b8576040519150601f19603f3d011682016040523d82523d6000602084013e6127bd565b606091505b5080516127dc5760405162461bcd60e51b8152600401610a98906131f6565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611dbd565b506001949350505050565b6001600160a01b0383166128645761285f81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612887565b816001600160a01b0316836001600160a01b031614612887576128878382612a0f565b6001600160a01b03821661289e57610c5c81612aac565b826001600160a01b0316826001600160a01b031614610c5c57610c5c8282612b85565b6001600160a01b0382166129175760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610a98565b6000818152600260205260409020546001600160a01b03161561297c5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610a98565b612988600083836126a6565b6001600160a01b03821660009081526003602052604081208054600192906129b19084906132ce565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001612a1c8461139d565b612a26919061333e565b600083815260076020526040902054909150808214612a79576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090612abe9060019061333e565b60008381526009602052604081205460088054939450909284908110612af457634e487b7160e01b600052603260045260246000fd5b906000526020600020015490508060088381548110612b2357634e487b7160e01b600052603260045260246000fd5b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480612b6957634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905550505050565b6000612b908361139d565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b82805482825590600052602060002090600f01601090048101928215612c665791602002820160005b83821115612c3657833561ffff1683826101000a81548161ffff021916908361ffff1602179055509260200192600201602081600101049283019260010302612bf2565b8015612c645782816101000a81549061ffff0219169055600201602081600101049283019260010302612c36565b505b50612c72929150612cea565b5090565b828054612c82906133aa565b90600052602060002090601f016020900481019282612ca45760008555612c66565b82601f10612cbd57805160ff1916838001178555612c66565b82800160010185558215612c66579182015b82811115612c66578251825591602001919060010190612ccf565b5b80821115612c725760008155600101612ceb565b600067ffffffffffffffff80841115612d1a57612d1a613440565b604051601f8501601f19908116603f01168101908282118183101715612d4257612d42613440565b81604052809350858152868686011115612d5b57600080fd5b858560208301376000602087830101525050509392505050565b60008083601f840112612d86578182fd5b50813567ffffffffffffffff811115612d9d578182fd5b6020830191508360208260051b8501011115612db857600080fd5b9250929050565b600060208284031215612dd0578081fd5b81356122a081613456565b60008060408385031215612ded578081fd5b8235612df881613456565b91506020830135612e0881613456565b809150509250929050565b600080600060608486031215612e27578081fd5b8335612e3281613456565b92506020840135612e4281613456565b929592945050506040919091013590565b60008060008060808587031215612e68578081fd5b8435612e7381613456565b93506020850135612e8381613456565b925060408501359150606085013567ffffffffffffffff811115612ea5578182fd5b8501601f81018713612eb5578182fd5b612ec487823560208401612cff565b91505092959194509250565b60008060408385031215612ee2578182fd5b8235612eed81613456565b915060208301358015158114612e08578182fd5b60008060408385031215612f13578182fd5b8235612f1e81613456565b946020939093013593505050565b60008060208385031215612f3e578182fd5b823567ffffffffffffffff811115612f54578283fd5b612f6085828601612d75565b90969095509350505050565b600060208284031215612f7d578081fd5b81356122a08161346b565b600060208284031215612f99578081fd5b81516122a08161346b565b600060208284031215612fb5578081fd5b813567ffffffffffffffff811115612fcb578182fd5b8201601f81018413612fdb578182fd5b611dbd84823560208401612cff565b600060208284031215612ffb578081fd5b813561ffff811681146122a0578182fd5b60006020828403121561301d578081fd5b5035919050565b600060208284031215613035578081fd5b5051919050565b600080600060408486031215613050578081fd5b833560ff81168114613060578182fd5b9250602084013567ffffffffffffffff81111561307b578182fd5b61308786828701612d75565b9497909650939450505050565b600081518084526130ac81602086016020860161337e565b601f01601f19169290920160200192915050565b600081516130d281856020860161337e565b9290920192915050565b600080845482600182811c9150808316806130f857607f831692505b602080841082141561311857634e487b7160e01b87526022600452602487fd5b81801561312c576001811461313d57613169565b60ff19861689528489019650613169565b60008b815260209020885b868110156131615781548b820152908501908301613148565b505084890196505b50505050505061319d61318c61318683602f60f81b815260010190565b866130c0565b64173539b7b760d91b815260050190565b95945050505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906131d990830184613094565b9695505050505050565b6020815260006122a06020830184613094565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b600082198211156132e1576132e1613414565b500190565b600060ff821660ff84168060ff0382111561330357613303613414565b019392505050565b60008261331a5761331a61342a565b500490565b600081600019048311821515161561333957613339613414565b500290565b60008282101561335057613350613414565b500390565b600067ffffffffffffffff8381169083168181101561337657613376613414565b039392505050565b60005b83811015613399578181015183820152602001613381565b838111156113205750506000910152565b600181811c908216806133be57607f821691505b602082108114156133df57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156133f9576133f9613414565b5060010190565b60008261340f5761340f61342a565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610ccd57600080fd5b6001600160e01b031981168114610ccd57600080fdfea2646970667358221220a93e479e4ca625c9609b2aba6f87a745020a47c988b15f2c346d7184d7cd7f8b64736f6c63430008040033608060405234801561001057600080fd5b5061001a3361001f565b61006f565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6105718061007e6000396000f3fe6080604052600436106100555760003560e01c806351cff8d91461005a578063715018a61461007c5780638da5cb5b14610091578063e3a9db1a146100be578063f2fde38b14610102578063f340fa0114610122575b600080fd5b34801561006657600080fd5b5061007a6100753660046104aa565b610135565b005b34801561008857600080fd5b5061007a6101d7565b34801561009d57600080fd5b506000546040516001600160a01b0390911681526020015b60405180910390f35b3480156100ca57600080fd5b506100f46100d93660046104aa565b6001600160a01b031660009081526001602052604090205490565b6040519081526020016100b5565b34801561010e57600080fd5b5061007a61011d3660046104aa565b61020d565b61007a6101303660046104aa565b6102a8565b6000546001600160a01b031633146101685760405162461bcd60e51b815260040161015f906104cd565b60405180910390fd5b6001600160a01b0381166000818152600160205260408120805491905590610190908261033c565b816001600160a01b03167f7084f5476618d8e60b11ef0d7d3f06914655adb8793e28ff7f018d4c76d505d5826040516101cb91815260200190565b60405180910390a25050565b6000546001600160a01b031633146102015760405162461bcd60e51b815260040161015f906104cd565b61020b600061045a565b565b6000546001600160a01b031633146102375760405162461bcd60e51b815260040161015f906104cd565b6001600160a01b03811661029c5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840161015f565b6102a58161045a565b50565b6000546001600160a01b031633146102d25760405162461bcd60e51b815260040161015f906104cd565b6001600160a01b0381166000908152600160205260408120805434928392916102fc908490610502565b90915550506040518181526001600160a01b038316907f2da466a7b24304f47e87fa2e1e5a81b9831ce54fec19055ce277ca2f39ba42c4906020016101cb565b8047101561038c5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604482015260640161015f565b6000826001600160a01b03168260405160006040518083038185875af1925050503d80600081146103d9576040519150601f19603f3d011682016040523d82523d6000602084013e6103de565b606091505b50509050806104555760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d61792068617665207265766572746564000000000000606482015260840161015f565b505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6000602082840312156104bb578081fd5b81356104c681610526565b9392505050565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6000821982111561052157634e487b7160e01b81526011600452602481fd5b500190565b6001600160a01b03811681146102a557600080fdfea264697066735822122097aaf8330e2b679c3d08b05923d025844a488ff53c65b2f148c20b20172688e864736f6c63430008040033697066733a2f2f516d4e574a7735565a4b6b6269474b4561554556696e695951484456337263313552344548426a3178506f437733697066733a2f2f516d6334624a685a7162755369374e3135417453747942563442767845767150315831524a70664e5575594c48462f48696464656e2e6a736f6e0000000000000000000000008d9232ebc4f06b7b8005ccff0ca401675ceb25f5000000000000000000000000657190bfc694f816b6cdd9eab3275f470e26542c

Deployed Bytecode

0x6080604052600436106102e45760003560e01c80635e1045ec11610190578063b88d4fde116100dc578063dc09e92311610095578063e985e9c51161006f578063e985e9c5146108be578063f2c4ce1e14610907578063f2fde38b14610927578063f99031a71461094757600080fd5b8063dc09e9231461085e578063e1ec62941461087e578063e2982c211461089e57600080fd5b8063b88d4fde146107a8578063b88fe6a3146107c8578063c2ba4744146107e8578063c87b56dd14610809578063d49479eb14610829578063d5abeb011461084957600080fd5b80638da5cb5b11610149578063a0712d6811610123578063a0712d6814610740578063a22cb46514610753578063a230c52414610773578063a475b5dd1461079357600080fd5b80638da5cb5b146106ed57806394a7ef151461070b57806395d89b411461072b57600080fd5b80635e1045ec1461064c5780636352211e1461066c57806370a082311461068c578063715018a6146106ac5780638456cb59146106c157806384c4bd4b146106d657600080fd5b806331b3eb941161024f5780634a90be57116102085780635393554a116101e25780635393554a1461058257806355f804b3146105a25780635a9b0b89146105c25780635c975abb1461062d57600080fd5b80634a90be57146105335780634f6ccce714610548578063518302271461056857600080fd5b806331b3eb94146104895780633b3c523a146104a95780633ccfd60b146104c95780633f4ba83a146104de57806342842e0e146104f357806343bc16121461051357600080fd5b806318160ddd116102a157806318160ddd146103d45780632042e5c2146103e957806322ad06701461040957806323b872dd146104295780632acc659e146104495780632f745c591461046957600080fd5b806301ffc9a7146102e95780630385e9601461031e57806306fdde0314610343578063081812fc14610365578063081c8c441461039d578063095ea7b3146103b2575b600080fd5b3480156102f557600080fd5b50610309610304366004612f6c565b610980565b60405190151581526020015b60405180910390f35b34801561032a57600080fd5b506011546103359081565b604051908152602001610315565b34801561034f57600080fd5b50610358610991565b60405161031591906131e3565b34801561037157600080fd5b5061038561038036600461300c565b610a23565b6040516001600160a01b039091168152602001610315565b3480156103a957600080fd5b50610358610abd565b3480156103be57600080fd5b506103d26103cd366004612f01565b610b4b565b005b3480156103e057600080fd5b50600854610335565b3480156103f557600080fd5b506103d2610404366004612dbf565b610c61565b34801561041557600080fd5b506103d2610424366004612f01565b610cd0565b34801561043557600080fd5b506103d2610444366004612e13565b610d20565b34801561045557600080fd5b50610335610464366004612dbf565b610d51565b34801561047557600080fd5b50610335610484366004612f01565b610d9a565b34801561049557600080fd5b506103d26104a4366004612dbf565b610e30565b3480156104b557600080fd5b506103d26104c436600461303c565b610e99565b3480156104d557600080fd5b506103d2610fdf565b3480156104ea57600080fd5b506103d2611015565b3480156104ff57600080fd5b506103d261050e366004612e13565b611047565b34801561051f57600080fd5b50600d54610385906001600160a01b031681565b34801561053f57600080fd5b50600f54610335565b34801561055457600080fd5b5061033561056336600461300c565b611062565b34801561057457600080fd5b506018546103099060ff1681565b34801561058e57600080fd5b506103d261059d36600461300c565b611103565b3480156105ae57600080fd5b506103d26105bd366004612fa4565b611183565b3480156105ce57600080fd5b506105d76111c4565b6040516103159190600060e082019050825182526020830151602083015260408301516040830152606083015160608301526080830151608083015260a083015160a083015260c083015160c083015292915050565b34801561063957600080fd5b50600a54600160a01b900460ff16610309565b34801561065857600080fd5b506103d2610667366004612f2c565b611275565b34801561067857600080fd5b5061038561068736600461300c565b611326565b34801561069857600080fd5b506103356106a7366004612dbf565b61139d565b3480156106b857600080fd5b506103d2611424565b3480156106cd57600080fd5b506103d2611458565b3480156106e257600080fd5b506010546103359081565b3480156106f957600080fd5b50600a546001600160a01b0316610385565b34801561071757600080fd5b506103d2610726366004612dbf565b61148a565b34801561073757600080fd5b506103586114d8565b6103d261074e36600461300c565b6114e7565b34801561075f57600080fd5b506103d261076e366004612ed0565b61169d565b34801561077f57600080fd5b5061030961078e366004612dbf565b6116a8565b34801561079f57600080fd5b506103d26117bf565b3480156107b457600080fd5b506103d26107c3366004612e53565b6117f8565b3480156107d457600080fd5b50600c54610385906001600160a01b031681565b3480156107f457600080fd5b50610335610803366004612dbf565b50600a90565b34801561081557600080fd5b5061035861082436600461300c565b61182a565b34801561083557600080fd5b506103d261084436600461300c565b61197a565b34801561085557600080fd5b506122b8610335565b34801561086a57600080fd5b506103d261087936600461300c565b6119a9565b34801561088a57600080fd5b506103d261089936600461300c565b6119d8565b3480156108aa57600080fd5b506103356108b9366004612dbf565b611a07565b3480156108ca57600080fd5b506103096108d9366004612ddb565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561091357600080fd5b506103d2610922366004612fa4565b611aa5565b34801561093357600080fd5b506103d2610942366004612dbf565b611ae2565b34801561095357600080fd5b50610309610962366004612dbf565b6001600160a01b031660009081526016602052604090205460ff1690565b600061098b82611b83565b92915050565b6060600080546109a0906133aa565b80601f01602080910402602001604051908101604052809291908181526020018280546109cc906133aa565b8015610a195780601f106109ee57610100808354040283529160200191610a19565b820191906000526020600020905b8154815290600101906020018083116109fc57829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b0316610aa15760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60198054610aca906133aa565b80601f0160208091040260200160405190810160405280929190818152602001828054610af6906133aa565b8015610b435780601f10610b1857610100808354040283529160200191610b43565b820191906000526020600020905b815481529060010190602001808311610b2657829003601f168201915b505050505081565b6000610b5682611326565b9050806001600160a01b0316836001600160a01b03161415610bc45760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610a98565b336001600160a01b0382161480610be05750610be081336108d9565b610c525760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610a98565b610c5c8383611ba8565b505050565b600a546001600160a01b03163314610c8b5760405162461bcd60e51b8152600401610a9890613248565b6001600160a01b03811660009081526016602052604090205460ff1615610ccd576001600160a01b0381166000908152601660205260409020805460ff191690555b50565b600a546001600160a01b03163314610cfa5760405162461bcd60e51b8152600401610a9890613248565b60005b81811015610c5c57610d0e83611c16565b80610d18816133e5565b915050610cfd565b610d2a3382611cce565b610d465760405162461bcd60e51b8152600401610a989061327d565b610c5c838383611dc5565b6000610d5c826116a8565b15610d6957505060125490565b6001600160a01b03821660009081526016602052604090205460ff1615610d9257505060135490565b505060145490565b6000610da58361139d565b8210610e075760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610a98565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b6002600b541415610e835760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610a98565b6002600b55610e9181611f6c565b506001600b55565b600a546001600160a01b03163314610ec35760405162461bcd60e51b8152600401610a9890613248565b60155460ff80851691161115610f0f5760405162461bcd60e51b81526020600482015260116024820152706368756e6b496e6465782065786973747360781b6044820152606401610a98565b60ff8316610f2957610f23600f8383612bc9565b50610fbb565b8060005b81811015610fb857600f848483818110610f5757634e487b7160e01b600052603260045260246000fd5b9050602002016020810190610f6c9190612fea565b81546001810183556000928352602090922060108304018054600f9093166002026101000a61ffff81810219909416929093169290920217905580610fb0816133e5565b915050610f2d565b50505b610fc68360016132e6565b6015805460ff191660ff92909216919091179055505050565b600a546001600160a01b031633146110095760405162461bcd60e51b8152600401610a9890613248565b6110133347611fea565b565b600a546001600160a01b0316331461103f5760405162461bcd60e51b8152600401610a9890613248565b611013612103565b610c5c838383604051806020016040528060008152506117f8565b600061106d60085490565b82106110d05760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610a98565b600882815481106110f157634e487b7160e01b600052603260045260246000fd5b90600052602060002001549050919050565b600a546001600160a01b0316331461112d5760405162461bcd60e51b8152600401610a9890613248565b600061113860115490565b9050805b61114683836132ce565b811015610c5c57600d54611163906001600160a01b0316826121a0565b611171601180546001019055565b8061117b816133e5565b91505061113c565b600a546001600160a01b031633146111ad5760405162461bcd60e51b8152600401610a9890613248565b80516111c0906017906020840190612c76565b5050565b6112046040518060e00160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6112446040518060e00160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b6014548152601254602082015260135460408201526122b860608201526008546080820152600a60c0820152919050565b600a546001600160a01b0316331461129f5760405162461bcd60e51b8152600401610a9890613248565b8060005b81811015611320576001601660008686858181106112d157634e487b7160e01b600052603260045260246000fd5b90506020020160208101906112e69190612dbf565b6001600160a01b031681526020810191909152604001600020805460ff191691151591909117905580611318816133e5565b9150506112a3565b50505050565b6000818152600260205260408120546001600160a01b03168061098b5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610a98565b60006001600160a01b0382166114085760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610a98565b506001600160a01b031660009081526003602052604090205490565b600a546001600160a01b0316331461144e5760405162461bcd60e51b8152600401610a9890613248565b61101360006121ba565b600a546001600160a01b031633146114825760405162461bcd60e51b8152600401610a9890613248565b61101361220c565b600a546001600160a01b031633146114b45760405162461bcd60e51b8152600401610a9890613248565b6001600160a01b03166000908152601660205260409020805460ff19166001179055565b6060600180546109a0906133aa565b600a54600160a01b900460ff16156115345760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610a98565b600a8111156115855760405162461bcd60e51b815260206004820152601d60248201527f6e6f74206d696e74206d6f7265207468616e206d617820616d6f756e740000006044820152606401610a98565b600080611591336116a8565b905080156115ad576012546115a69084612294565b91506115ec565b3360009081526016602052604090205460ff1680156115da576013546115d39085612294565b92506115ea565b6014546115e79085612294565b92505b505b8134101561162f5760405162461bcd60e51b815260206004820152601060248201526f6e6f7420656e6f7567682066756e647360801b6044820152606401610a98565b600e546000906116559084906fffffffffffffffffffffffffffffffff166127106122a7565b905060005b8481101561167d5761166b33611c16565b80611675816133e5565b91505061165a565b50600d54611320906001600160a01b0316611698838661333e565b6123b9565b6111c033838361243a565b600c54604051627eeac760e11b81526001600160a01b03838116600483015260016024830152600092839291169062fdd58e9060440160206040518083038186803b1580156116f657600080fd5b505afa15801561170a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061172e9190613024565b118061098b5750600c54604051627eeac760e11b81526001600160a01b03848116600483015260026024830152600092169062fdd58e9060440160206040518083038186803b15801561178057600080fd5b505afa158015611794573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117b89190613024565b1192915050565b600a546001600160a01b031633146117e95760405162461bcd60e51b8152600401610a9890613248565b6018805460ff19166001179055565b6118023383611cce565b61181e5760405162461bcd60e51b8152600401610a989061327d565b61132084848484612509565b6000818152600260205260409020546060906001600160a01b03166118a95760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610a98565b60185460ff1661194557601980546118c0906133aa565b80601f01602080910402602001604051908101604052809291908181526020018280546118ec906133aa565b80156119395780601f1061190e57610100808354040283529160200191611939565b820191906000526020600020905b81548152906001019060200180831161191c57829003601f168201915b50505050509050919050565b600060176119528461253c565b6040516020016119639291906130dc565b60408051601f198184030181529190529392505050565b600a546001600160a01b031633146119a45760405162461bcd60e51b8152600401610a9890613248565b601355565b600a546001600160a01b031633146119d35760405162461bcd60e51b8152600401610a9890613248565b601255565b600a546001600160a01b03163314611a025760405162461bcd60e51b8152600401610a9890613248565b601455565b6040516371d4ed8d60e11b81526001600160a01b0382811660048301526000917f0000000000000000000000004c20fef4e80bad86c30538eb8a0487e5753d48e69091169063e3a9db1a9060240160206040518083038186803b158015611a6d57600080fd5b505afa158015611a81573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061098b9190613024565b600a546001600160a01b03163314611acf5760405162461bcd60e51b8152600401610a9890613248565b80516111c0906019906020840190612c76565b600a546001600160a01b03163314611b0c5760405162461bcd60e51b8152600401610a9890613248565b6001600160a01b038116611b715760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610a98565b610ccd816121ba565b80546001019055565b60006001600160e01b0319821663780e9d6360e01b148061098b575061098b82612656565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611bdd82611326565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611c2160105490565b9050611c3060646122b8613355565b67ffffffffffffffff168110611c745760405162461bcd60e51b8152602060048201526009602482015268736f6c64206f75742160b81b6044820152606401610a98565b611c82601080546001019055565b6111c082600f8381548110611ca757634e487b7160e01b600052603260045260246000fd5b60009182526020909120601082040154600f9091166002026101000a900461ffff166121a0565b6000818152600260205260408120546001600160a01b0316611d475760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610a98565b6000611d5283611326565b9050806001600160a01b0316846001600160a01b03161480611d8d5750836001600160a01b0316611d8284610a23565b6001600160a01b0316145b80611dbd57506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316611dd882611326565b6001600160a01b031614611e3c5760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610a98565b6001600160a01b038216611e9e5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610a98565b611ea98383836126a6565b611eb4600082611ba8565b6001600160a01b0383166000908152600360205260408120805460019290611edd90849061333e565b90915550506001600160a01b0382166000908152600360205260408120805460019290611f0b9084906132ce565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6040516351cff8d960e01b81526001600160a01b0382811660048301527f0000000000000000000000004c20fef4e80bad86c30538eb8a0487e5753d48e616906351cff8d990602401600060405180830381600087803b158015611fcf57600080fd5b505af1158015611fe3573d6000803e3d6000fd5b5050505050565b8047101561203a5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610a98565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114612087576040519150601f19603f3d011682016040523d82523d6000602084013e61208c565b606091505b5050905080610c5c5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610a98565b600a54600160a01b900460ff166121535760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610a98565b600a805460ff60a01b191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6111c08282604051806020016040528060008152506126b1565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600a54600160a01b900460ff16156122595760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610a98565b600a805460ff60a01b1916600160a01b1790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586121833390565b60006122a0828461331f565b9392505050565b60008082116122eb5760405162461bcd60e51b815260206004820152601060248201526f4469766973696f6e206279207a65726f60801b6044820152606401610a98565b836122f8575060006122a0565b6000612304848661331f565b905083612311868361330b565b141561232957612321838261330b565b9150506122a0565b6000612335848761330b565b905060006123438588613400565b90506000612351868861330b565b9050600061235f8789613400565b90506123ac612378886123728685612294565b906126e4565b6123a66123858686612294565b6123a66123928987612294565b6123a68d6123a08c8b612294565b90612294565b906126f0565b9998505050505050505050565b60405163f340fa0160e01b81526001600160a01b0383811660048301527f0000000000000000000000004c20fef4e80bad86c30538eb8a0487e5753d48e6169063f340fa019083906024016000604051808303818588803b15801561241d57600080fd5b505af1158015612431573d6000803e3d6000fd5b50505050505050565b816001600160a01b0316836001600160a01b0316141561249c5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610a98565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b612514848484611dc5565b612520848484846126fc565b6113205760405162461bcd60e51b8152600401610a98906131f6565b6060816125605750506040805180820190915260018152600360fc1b602082015290565b8160005b811561258a5780612574816133e5565b91506125839050600a8361330b565b9150612564565b60008167ffffffffffffffff8111156125b357634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156125dd576020820181803683370190505b5090505b8415611dbd576125f260018361333e565b91506125ff600a86613400565b61260a9060306132ce565b60f81b81838151811061262d57634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a90535061264f600a8661330b565b94506125e1565b60006001600160e01b031982166380ac58cd60e01b148061268757506001600160e01b03198216635b5e139f60e01b145b8061098b57506301ffc9a760e01b6001600160e01b031983161461098b565b610c5c838383612809565b6126bb83836128c1565b6126c860008484846126fc565b610c5c5760405162461bcd60e51b8152600401610a98906131f6565b60006122a0828461330b565b60006122a082846132ce565b60006001600160a01b0384163b156127fe57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906127409033908990889088906004016131a6565b602060405180830381600087803b15801561275a57600080fd5b505af192505050801561278a575060408051601f3d908101601f1916820190925261278791810190612f88565b60015b6127e4573d8080156127b8576040519150601f19603f3d011682016040523d82523d6000602084013e6127bd565b606091505b5080516127dc5760405162461bcd60e51b8152600401610a98906131f6565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611dbd565b506001949350505050565b6001600160a01b0383166128645761285f81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612887565b816001600160a01b0316836001600160a01b031614612887576128878382612a0f565b6001600160a01b03821661289e57610c5c81612aac565b826001600160a01b0316826001600160a01b031614610c5c57610c5c8282612b85565b6001600160a01b0382166129175760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610a98565b6000818152600260205260409020546001600160a01b03161561297c5760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610a98565b612988600083836126a6565b6001600160a01b03821660009081526003602052604081208054600192906129b19084906132ce565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006001612a1c8461139d565b612a26919061333e565b600083815260076020526040902054909150808214612a79576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090612abe9060019061333e565b60008381526009602052604081205460088054939450909284908110612af457634e487b7160e01b600052603260045260246000fd5b906000526020600020015490508060088381548110612b2357634e487b7160e01b600052603260045260246000fd5b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480612b6957634e487b7160e01b600052603160045260246000fd5b6001900381819060005260206000200160009055905550505050565b6000612b908361139d565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b82805482825590600052602060002090600f01601090048101928215612c665791602002820160005b83821115612c3657833561ffff1683826101000a81548161ffff021916908361ffff1602179055509260200192600201602081600101049283019260010302612bf2565b8015612c645782816101000a81549061ffff0219169055600201602081600101049283019260010302612c36565b505b50612c72929150612cea565b5090565b828054612c82906133aa565b90600052602060002090601f016020900481019282612ca45760008555612c66565b82601f10612cbd57805160ff1916838001178555612c66565b82800160010185558215612c66579182015b82811115612c66578251825591602001919060010190612ccf565b5b80821115612c725760008155600101612ceb565b600067ffffffffffffffff80841115612d1a57612d1a613440565b604051601f8501601f19908116603f01168101908282118183101715612d4257612d42613440565b81604052809350858152868686011115612d5b57600080fd5b858560208301376000602087830101525050509392505050565b60008083601f840112612d86578182fd5b50813567ffffffffffffffff811115612d9d578182fd5b6020830191508360208260051b8501011115612db857600080fd5b9250929050565b600060208284031215612dd0578081fd5b81356122a081613456565b60008060408385031215612ded578081fd5b8235612df881613456565b91506020830135612e0881613456565b809150509250929050565b600080600060608486031215612e27578081fd5b8335612e3281613456565b92506020840135612e4281613456565b929592945050506040919091013590565b60008060008060808587031215612e68578081fd5b8435612e7381613456565b93506020850135612e8381613456565b925060408501359150606085013567ffffffffffffffff811115612ea5578182fd5b8501601f81018713612eb5578182fd5b612ec487823560208401612cff565b91505092959194509250565b60008060408385031215612ee2578182fd5b8235612eed81613456565b915060208301358015158114612e08578182fd5b60008060408385031215612f13578182fd5b8235612f1e81613456565b946020939093013593505050565b60008060208385031215612f3e578182fd5b823567ffffffffffffffff811115612f54578283fd5b612f6085828601612d75565b90969095509350505050565b600060208284031215612f7d578081fd5b81356122a08161346b565b600060208284031215612f99578081fd5b81516122a08161346b565b600060208284031215612fb5578081fd5b813567ffffffffffffffff811115612fcb578182fd5b8201601f81018413612fdb578182fd5b611dbd84823560208401612cff565b600060208284031215612ffb578081fd5b813561ffff811681146122a0578182fd5b60006020828403121561301d578081fd5b5035919050565b600060208284031215613035578081fd5b5051919050565b600080600060408486031215613050578081fd5b833560ff81168114613060578182fd5b9250602084013567ffffffffffffffff81111561307b578182fd5b61308786828701612d75565b9497909650939450505050565b600081518084526130ac81602086016020860161337e565b601f01601f19169290920160200192915050565b600081516130d281856020860161337e565b9290920192915050565b600080845482600182811c9150808316806130f857607f831692505b602080841082141561311857634e487b7160e01b87526022600452602487fd5b81801561312c576001811461313d57613169565b60ff19861689528489019650613169565b60008b815260209020885b868110156131615781548b820152908501908301613148565b505084890196505b50505050505061319d61318c61318683602f60f81b815260010190565b866130c0565b64173539b7b760d91b815260050190565b95945050505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906131d990830184613094565b9695505050505050565b6020815260006122a06020830184613094565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b600082198211156132e1576132e1613414565b500190565b600060ff821660ff84168060ff0382111561330357613303613414565b019392505050565b60008261331a5761331a61342a565b500490565b600081600019048311821515161561333957613339613414565b500290565b60008282101561335057613350613414565b500390565b600067ffffffffffffffff8381169083168181101561337657613376613414565b039392505050565b60005b83811015613399578181015183820152602001613381565b838111156113205750506000910152565b600181811c908216806133be57607f821691505b602082108114156133df57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156133f9576133f9613414565b5060010190565b60008261340f5761340f61342a565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610ccd57600080fd5b6001600160e01b031981168114610ccd57600080fdfea2646970667358221220a93e479e4ca625c9609b2aba6f87a745020a47c988b15f2c346d7184d7cd7f8b64736f6c63430008040033

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

0000000000000000000000008d9232ebc4f06b7b8005ccff0ca401675ceb25f5000000000000000000000000657190bfc694f816b6cdd9eab3275f470e26542c

-----Decoded View---------------
Arg [0] : _memberships (address): 0x8d9232ebc4f06b7b8005ccff0ca401675ceb25f5
Arg [1] : _artist (address): 0x657190bfc694f816b6cdd9eab3275f470e26542c

-----Encoded View---------------
2 Constructor Arguments found :
Arg [0] : 0000000000000000000000008d9232ebc4f06b7b8005ccff0ca401675ceb25f5
Arg [1] : 000000000000000000000000657190bfc694f816b6cdd9eab3275f470e26542c


Deployed ByteCode Sourcemap

88276:5793:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;87128:145;;;;;;;;;;-1:-1:-1;87128:145:0;;;;;:::i;:::-;;:::i;:::-;;;10851:14:1;;10844:22;10826:41;;10814:2;10799:18;87128:145:0;;;;;;;;88476:38;;;;;;;;;;-1:-1:-1;88476:38:0;;;;;;;;;22857:25:1;;;22845:2;22830:18;88476:38:0;22812:76:1;53178:100:0;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;54737:221::-;;;;;;;;;;-1:-1:-1;54737:221:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;9351:32:1;;;9333:51;;9321:2;9306:18;54737:221:0;9288:102:1;88936:98:0;;;;;;;;;;;;;:::i;54260:411::-;;;;;;;;;;-1:-1:-1;54260:411:0;;;;;:::i;:::-;;:::i;:::-;;68090:113;;;;;;;;;;-1:-1:-1;68178:10:0;:17;68090:113;;89713:156;;;;;;;;;;-1:-1:-1;89713:156:0;;;;;:::i;:::-;;:::i;91864:174::-;;;;;;;;;;-1:-1:-1;91864:174:0;;;;;:::i;:::-;;:::i;55487:339::-;;;;;;;;;;-1:-1:-1;55487:339:0;;;;;:::i;:::-;;:::i;90871:290::-;;;;;;;;;;-1:-1:-1;90871:290:0;;;;;:::i;:::-;;:::i;67758:256::-;;;;;;;;;;-1:-1:-1;67758:256:0;;;;;:::i;:::-;;:::i;86756:133::-;;;;;;;;;;-1:-1:-1;86756:133:0;;;;;:::i;:::-;;:::i;90004:445::-;;;;;;;;;;-1:-1:-1;90004:445:0;;;;;:::i;:::-;;:::i;87281:115::-;;;;;;;;;;;;;:::i;87472:64::-;;;;;;;;;;;;;:::i;55897:185::-;;;;;;;;;;-1:-1:-1;55897:185:0;;;;;:::i;:::-;;:::i;86439:21::-;;;;;;;;;;-1:-1:-1;86439:21:0;;;;-1:-1:-1;;;;;86439:21:0;;;89274:82;;;;;;;;;;-1:-1:-1;89336:5:0;:12;89274:82;;68280:233;;;;;;;;;;-1:-1:-1;68280:233:0;;;;;:::i;:::-;;:::i;88901:28::-;;;;;;;;;;-1:-1:-1;88901:28:0;;;;;;;;91487:262;;;;;;;;;;-1:-1:-1;91487:262:0;;;;;:::i;:::-;;:::i;91757:99::-;;;;;;;;;;-1:-1:-1;91757:99:0;;;;;:::i;:::-;;:::i;90457:406::-;;;;;;;;;;;;;:::i;:::-;;;;;;22235:4:1;22277:3;22266:9;22262:19;22254:27;;22314:6;22308:13;22297:9;22290:32;22378:4;22370:6;22366:17;22360:24;22353:4;22342:9;22338:20;22331:54;22441:4;22433:6;22429:17;22423:24;22416:4;22405:9;22401:20;22394:54;22504:4;22496:6;22492:17;22486:24;22479:4;22468:9;22464:20;22457:54;22567:4;22559:6;22555:17;22549:24;22542:4;22531:9;22527:20;22520:54;22630:4;22622:6;22618:17;22612:24;22605:4;22594:9;22590:20;22583:54;22693:4;22685:6;22681:17;22675:24;22668:4;22657:9;22653:20;22646:54;22244:462;;;;;82242:86:0;;;;;;;;;;-1:-1:-1;82313:7:0;;-1:-1:-1;;;82313:7:0;;;;82242:86;;89481:224;;;;;;;;;;-1:-1:-1;89481:224:0;;;;;:::i;:::-;;:::i;52872:239::-;;;;;;;;;;-1:-1:-1;52872:239:0;;;;;:::i;:::-;;:::i;52602:208::-;;;;;;;;;;-1:-1:-1;52602:208:0;;;;;:::i;:::-;;:::i;75317:103::-;;;;;;;;;;;;;:::i;87404:60::-;;;;;;;;;;;;;:::i;88430:39::-;;;;;;;;;;-1:-1:-1;88430:39:0;;;;;;74666:87;;;;;;;;;;-1:-1:-1;74739:6:0;;-1:-1:-1;;;;;74739:6:0;74666:87;;89364:109;;;;;;;;;;-1:-1:-1;89364:109:0;;;;;:::i;:::-;;:::i;53347:104::-;;;;;;;;;;;;;:::i;92046:847::-;;;;;;:::i;:::-;;:::i;55030:155::-;;;;;;;;;;-1:-1:-1;55030:155:0;;;;;:::i;:::-;;:::i;86579:169::-;;;;;;;;;;-1:-1:-1;86579:169:0;;;;;:::i;:::-;;:::i;92901:69::-;;;;;;;;;;;;;:::i;56153:328::-;;;;;;;;;;-1:-1:-1;56153:328:0;;;;;:::i;:::-;;:::i;86406:26::-;;;;;;;;;;-1:-1:-1;86406:26:0;;;;-1:-1:-1;;;;;86406:26:0;;;93959:107;;;;;;;;;;-1:-1:-1;93959:107:0;;;;;:::i;:::-;-1:-1:-1;88734:2:0;;93959:107;93116:394;;;;;;;;;;-1:-1:-1;93116:394:0;;;;;:::i;:::-;;:::i;91275:100::-;;;;;;;;;;-1:-1:-1;91275:100:0;;;;;:::i;:::-;;:::i;93853:98::-;;;;;;;;;;-1:-1:-1;88691:4:0;93853:98;;91173:94;;;;;;;;;;-1:-1:-1;91173:94:0;;;;;:::i;:::-;;:::i;91383:96::-;;;;;;;;;;-1:-1:-1;91383:96:0;;;;;:::i;:::-;;:::i;80490:112::-;;;;;;;;;;-1:-1:-1;80490:112:0;;;;;:::i;:::-;;:::i;55256:164::-;;;;;;;;;;-1:-1:-1;55256:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;55377:25:0;;;55353:4;55377:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;55256:164;92982:126;;;;;;;;;;-1:-1:-1;92982:126:0;;;;;:::i;:::-;;:::i;75575:201::-;;;;;;;;;;-1:-1:-1;75575:201:0;;;;;:::i;:::-;;:::i;89881:111::-;;;;;;;;;;-1:-1:-1;89881:111:0;;;;;:::i;:::-;-1:-1:-1;;;;;89965:19:0;89941:4;89965:19;;;:9;:19;;;;;;;;;89881:111;87128:145;87205:4;87229:36;87253:11;87229:23;:36::i;:::-;87222:43;87128:145;-1:-1:-1;;87128:145:0:o;53178:100::-;53232:13;53265:5;53258:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53178:100;:::o;54737:221::-;54813:7;58080:16;;;:7;:16;;;;;;-1:-1:-1;;;;;58080:16:0;54833:73;;;;-1:-1:-1;;;54833:73:0;;17787:2:1;54833:73:0;;;17769:21:1;17826:2;17806:18;;;17799:30;17865:34;17845:18;;;17838:62;-1:-1:-1;;;17916:18:1;;;17909:42;17968:19;;54833:73:0;;;;;;;;;-1:-1:-1;54926:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;54926:24:0;;54737:221::o;88936:98::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;54260:411::-;54341:13;54357:23;54372:7;54357:14;:23::i;:::-;54341:39;;54405:5;-1:-1:-1;;;;;54399:11:0;:2;-1:-1:-1;;;;;54399:11:0;;;54391:57;;;;-1:-1:-1;;;54391:57:0;;19322:2:1;54391:57:0;;;19304:21:1;19361:2;19341:18;;;19334:30;19400:34;19380:18;;;19373:62;-1:-1:-1;;;19451:18:1;;;19444:31;19492:19;;54391:57:0;19294:223:1;54391:57:0;30098:10;-1:-1:-1;;;;;54483:21:0;;;;:62;;-1:-1:-1;54508:37:0;54525:5;30098:10;55256:164;:::i;54508:37::-;54461:168;;;;-1:-1:-1;;;54461:168:0;;16180:2:1;54461:168:0;;;16162:21:1;16219:2;16199:18;;;16192:30;16258:34;16238:18;;;16231:62;16329:26;16309:18;;;16302:54;16373:19;;54461:168:0;16152:246:1;54461:168:0;54642:21;54651:2;54655:7;54642:8;:21::i;:::-;54260:411;;;:::o;89713:156::-;74739:6;;-1:-1:-1;;;;;74739:6:0;30098:10;74886:23;74878:68;;;;-1:-1:-1;;;74878:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;89788:19:0;::::1;;::::0;;;:9:::1;:19;::::0;;;;;::::1;;89784:78;;;-1:-1:-1::0;;;;;89831:19:0;::::1;;::::0;;;:9:::1;:19;::::0;;;;89824:26;;-1:-1:-1;;89824:26:0::1;::::0;;89784:78:::1;89713:156:::0;:::o;91864:174::-;74739:6;;-1:-1:-1;;;;;74739:6:0;30098:10;74886:23;74878:68;;;;-1:-1:-1;;;74878:68:0;;;;;;;:::i;:::-;91953:9:::1;91948:83;91972:7;91968:1;:11;91948:83;;;92002:17;92011:7;92002:8;:17::i;:::-;91981:4:::0;::::1;::::0;::::1;:::i;:::-;;;;91948:83;;55487:339:::0;55682:41;30098:10;55715:7;55682:18;:41::i;:::-;55674:103;;;;-1:-1:-1;;;55674:103:0;;;;;;;:::i;:::-;55790:28;55800:4;55806:2;55810:7;55790:9;:28::i;90871:290::-;90937:7;90961:17;90970:7;90961:8;:17::i;:::-;90957:197;;;-1:-1:-1;;91002:10:0;;;90871:290::o;90957:197::-;-1:-1:-1;;;;;89965:19:0;;89941:4;89965:19;;;:9;:19;;;;;;;;91030:124;;;-1:-1:-1;;91078:13:0;;;90871:290::o;91030:124::-;-1:-1:-1;;91131:11:0;;;90871:290::o;67758:256::-;67855:7;67891:23;67908:5;67891:16;:23::i;:::-;67883:5;:31;67875:87;;;;-1:-1:-1;;;67875:87:0;;11877:2:1;67875:87:0;;;11859:21:1;11916:2;11896:18;;;11889:30;11955:34;11935:18;;;11928:62;-1:-1:-1;;;12006:18:1;;;11999:41;12057:19;;67875:87:0;11849:233:1;67875:87:0;-1:-1:-1;;;;;;67980:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;67758:256::o;86756:133::-;85248:1;85846:7;;:19;;85838:63;;;;-1:-1:-1;;;85838:63:0;;21604:2:1;85838:63:0;;;21586:21:1;21643:2;21623:18;;;21616:30;21682:33;21662:18;;;21655:61;21733:18;;85838:63:0;21576:181:1;85838:63:0;85248:1;85979:7;:18;86852:29:::1;86875:5:::0;86852:22:::1;:29::i;:::-;-1:-1:-1::0;85204:1:0;86158:7;:22;86756:133::o;90004:445::-;74739:6;;-1:-1:-1;;;;;74739:6:0;30098:10;74886:23;74878:68;;;;-1:-1:-1;;;74878:68:0;;;;;;;:::i;:::-;90110:17:::1;::::0;:32:::1;::::0;;::::1;:17:::0;::::1;:32;;90102:62;;;::::0;-1:-1:-1;;;90102:62:0;;21258:2:1;90102:62:0::1;::::0;::::1;21240:21:1::0;21297:2;21277:18;;;21270:30;-1:-1:-1;;;21316:18:1;;;21309:47;21373:18;;90102:62:0::1;21230:167:1::0;90102:62:0::1;90179:16;::::0;::::1;90175:221;;90212:14;:5;90220:6:::0;;90212:14:::1;:::i;:::-;;90175:221;;;90270:6:::0;90259:8:::1;90298:87;90318:3;90314:1;:7;90298:87;;;90348:5;90359:6;;90366:1;90359:9;;;;;-1:-1:-1::0;;;90359:9:0::1;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;90348:21:::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;90348:21:0;;;::::1;::::0;;;::::1;::::0;::::1;;::::0;;;;;;::::1;;;;;::::0;;::::1;;::::0;;::::1;::::0;;;::::1;::::0;;;::::1;;::::0;;90323:4;::::1;::::0;::::1;:::i;:::-;;;;90298:87;;;;90175:221;;90426:15;:11:::0;90440:1:::1;90426:15;:::i;:::-;90406:17;:35:::0;;-1:-1:-1;;90406:35:0::1;;::::0;;;::::1;::::0;;;::::1;::::0;;-1:-1:-1;;;90004:445:0:o;87281:115::-;74739:6;;-1:-1:-1;;;;;74739:6:0;30098:10;74886:23;74878:68;;;;-1:-1:-1;;;74878:68:0;;;;;;;:::i;:::-;87336:52:::1;87344:10;87366:21;87336:29;:52::i;:::-;87281:115::o:0;87472:64::-;74739:6;;-1:-1:-1;;;;;74739:6:0;30098:10;74886:23;74878:68;;;;-1:-1:-1;;;74878:68:0;;;;;;;:::i;:::-;87518:10:::1;:8;:10::i;55897:185::-:0;56035:39;56052:4;56058:2;56062:7;56035:39;;;;;;;;;;;;:16;:39::i;68280:233::-;68355:7;68391:30;68178:10;:17;;68090:113;68391:30;68383:5;:38;68375:95;;;;-1:-1:-1;;;68375:95:0;;20845:2:1;68375:95:0;;;20827:21:1;20884:2;20864:18;;;20857:30;20923:34;20903:18;;;20896:62;-1:-1:-1;;;20974:18:1;;;20967:42;21026:19;;68375:95:0;20817:234:1;68375:95:0;68488:10;68499:5;68488:17;;;;;;-1:-1:-1;;;68488:17:0;;;;;;;;;;;;;;;;;68481:24;;68280:233;;;:::o;91487:262::-;74739:6;;-1:-1:-1;;;;;74739:6:0;30098:10;74886:23;74878:68;;;;-1:-1:-1;;;74878:68:0;;;;;;;:::i;:::-;91553:15:::1;91571:24;:14;1034::::0;;942:114;91571:24:::1;91553:42:::0;-1:-1:-1;91553:42:0;91606:136:::1;91633:13;91643:3:::0;91633:7;:13:::1;:::i;:::-;91629:1;:17;91606:136;;;91679:6;::::0;91669:20:::1;::::0;-1:-1:-1;;;;;91679:6:0::1;91687:1:::0;91669:9:::1;:20::i;:::-;91704:26;:14;1153:19:::0;;1171:1;1153:19;;;1064:127;91704:26:::1;91648:4:::0;::::1;::::0;::::1;:::i;:::-;;;;91606:136;;91757:99:::0;74739:6;;-1:-1:-1;;;;;74739:6:0;30098:10;74886:23;74878:68;;;;-1:-1:-1;;;74878:68:0;;;;;;;:::i;:::-;91830:18;;::::1;::::0;:7:::1;::::0;:18:::1;::::0;::::1;::::0;::::1;:::i;:::-;;91757:99:::0;:::o;90457:406::-;90508:11;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90508:11:0;90532:19;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90532:19:0;90586:11;;90564:33;;90629:10;;90608:18;;;:31;90674:13;;90650:21;;;:37;88691:4;90698:17;;;:30;68178:10;:17;90739:19;;;:41;88734:2;90791:20;;;:37;90739:7;90457:406;-1:-1:-1;90457:406:0:o;89481:224::-;74739:6;;-1:-1:-1;;;;;74739:6:0;30098:10;74886:23;74878:68;;;;-1:-1:-1;;;74878:68:0;;;;;;;:::i;:::-;89573:10;89562:8:::1;89601:89;89621:3;89617:1;:7;89601:89;;;89674:4;89647:9;:24;89657:10;;89668:1;89657:13;;;;;-1:-1:-1::0;;;89657:13:0::1;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;89647:24:0::1;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;89647:24:0;:31;;-1:-1:-1;;89647:31:0::1;::::0;::::1;;::::0;;;::::1;::::0;;89626:4;::::1;::::0;::::1;:::i;:::-;;;;89601:89;;;;74957:1;89481:224:::0;;:::o;52872:239::-;52944:7;52980:16;;;:7;:16;;;;;;-1:-1:-1;;;;;52980:16:0;53015:19;53007:73;;;;-1:-1:-1;;;53007:73:0;;17016:2:1;53007:73:0;;;16998:21:1;17055:2;17035:18;;;17028:30;17094:34;17074:18;;;17067:62;-1:-1:-1;;;17145:18:1;;;17138:39;17194:19;;53007:73:0;16988:231:1;52602:208:0;52674:7;-1:-1:-1;;;;;52702:19:0;;52694:74;;;;-1:-1:-1;;;52694:74:0;;16605:2:1;52694:74:0;;;16587:21:1;16644:2;16624:18;;;16617:30;16683:34;16663:18;;;16656:62;-1:-1:-1;;;16734:18:1;;;16727:40;16784:19;;52694:74:0;16577:232:1;52694:74:0;-1:-1:-1;;;;;;52786:16:0;;;;;:9;:16;;;;;;;52602:208::o;75317:103::-;74739:6;;-1:-1:-1;;;;;74739:6:0;30098:10;74886:23;74878:68;;;;-1:-1:-1;;;74878:68:0;;;;;;;:::i;:::-;75382:30:::1;75409:1;75382:18;:30::i;87404:60::-:0;74739:6;;-1:-1:-1;;;;;74739:6:0;30098:10;74886:23;74878:68;;;;-1:-1:-1;;;74878:68:0;;;;;;;:::i;:::-;87448:8:::1;:6;:8::i;89364:109::-:0;74739:6;;-1:-1:-1;;;;;74739:6:0;30098:10;74886:23;74878:68;;;;-1:-1:-1;;;74878:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;89439:19:0::1;;::::0;;;:9:::1;:19;::::0;;;;:26;;-1:-1:-1;;89439:26:0::1;89461:4;89439:26;::::0;;89364:109::o;53347:104::-;53403:13;53436:7;53429:14;;;;;:::i;92046:847::-;82313:7;;-1:-1:-1;;;82313:7:0;;;;82567:9;82559:38;;;;-1:-1:-1;;;82559:38:0;;15835:2:1;82559:38:0;;;15817:21:1;15874:2;15854:18;;;15847:30;-1:-1:-1;;;15893:18:1;;;15886:46;15949:18;;82559:38:0;15807:166:1;82559:38:0;88734:2:::1;92136:25:::0;::::1;;92128:67;;;::::0;-1:-1:-1;;;92128:67:0;;20142:2:1;92128:67:0::1;::::0;::::1;20124:21:1::0;20181:2;20161:18;;;20154:30;20220:31;20200:18;;;20193:59;20269:18;;92128:67:0::1;20114:179:1::0;92128:67:0::1;92208:13;92232:14:::0;92249:20:::1;92258:10;92249:8;:20::i;:::-;92232:37;;92294:9;92290:324;;;92327:10;::::0;:23:::1;::::0;92342:7;92327:14:::1;:23::i;:::-;92319:31;;92290:324;;;92416:10;92385:16;89965:19:::0;;;:9;:19;;;;;;;;92442:161;::::1;;;92486:13;::::0;:26:::1;::::0;92504:7;92486:17:::1;:26::i;:::-;92478:34;;92442:161;;;92562:11;::::0;:24:::1;::::0;92578:7;92562:15:::1;:24::i;:::-;92554:32;;92442:161;92290:324;;92647:5;92634:9;:18;;92626:47;;;::::0;-1:-1:-1;;;92626:47:0;;20500:2:1;92626:47:0::1;::::0;::::1;20482:21:1::0;20539:2;20519:18;;;20512:30;-1:-1:-1;;;20558:18:1;;;20551:46;20614:18;;92626:47:0::1;20472:166:1::0;92626:47:0::1;92726:3;::::0;92693:17:::1;::::0;92713:24:::1;::::0;:5;;92726:3:::1;;86501:5;92713:12;:24::i;:::-;92693:44;;92753:9;92749:83;92772:7;92768:1;:11;92749:83;;;92800:20;92809:10;92800:8;:20::i;:::-;92781:3:::0;::::1;::::0;::::1;:::i;:::-;;;;92749:83;;;-1:-1:-1::0;92859:6:0::1;::::0;92844:41:::1;::::0;-1:-1:-1;;;;;92859:6:0::1;92867:17;92875:9:::0;92867:5;:17:::1;:::i;:::-;92844:14;:41::i;55030:155::-:0;55125:52;30098:10;55158:8;55168;55125:18;:52::i;86579:169::-;86660:11;;:34;;-1:-1:-1;;;86660:34:0;;-1:-1:-1;;;;;10312:32:1;;;86660:34:0;;;10294:51:1;86660:11:0;10361:18:1;;;10354:34;86636:4:0;;;;86660:11;;;:21;;10267:18:1;;86660:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:38;:80;;;-1:-1:-1;86702:11:0;;:34;;-1:-1:-1;;;86702:34:0;;-1:-1:-1;;;;;10312:32:1;;;86702:34:0;;;10294:51:1;86734:1:0;10361:18:1;;;10354:34;86739:1:0;;86702:11;;:21;;10267:18:1;;86702:34:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:38;86653:87;86579:169;-1:-1:-1;;86579:169:0:o;92901:69::-;74739:6;;-1:-1:-1;;;;;74739:6:0;30098:10;74886:23;74878:68;;;;-1:-1:-1;;;74878:68:0;;;;;;;:::i;:::-;92947:8:::1;:15:::0;;-1:-1:-1;;92947:15:0::1;92958:4;92947:15;::::0;;92901:69::o;56153:328::-;56328:41;30098:10;56361:7;56328:18;:41::i;:::-;56320:103;;;;-1:-1:-1;;;56320:103:0;;;;;;;:::i;:::-;56434:39;56448:4;56454:2;56458:7;56467:5;56434:13;:39::i;93116:394::-;58056:4;58080:16;;;:7;:16;;;;;;93187:13;;-1:-1:-1;;;;;58080:16:0;93211:76;;;;-1:-1:-1;;;93211:76:0;;18906:2:1;93211:76:0;;;18888:21:1;18945:2;18925:18;;;18918:30;18984:34;18964:18;;;18957:62;-1:-1:-1;;;19035:18:1;;;19028:45;19090:19;;93211:76:0;18878:237:1;93211:76:0;93299:8;;;;93296:70;;93340:14;93333:21;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;93116:394;;;:::o;93296:70::-;93374:23;93424:7;93438:26;93455:8;93438:16;:26::i;:::-;93407:67;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;93407:67:0;;;;;;;;;;93116:394;-1:-1:-1;;;93116:394:0:o;91275:100::-;74739:6;;-1:-1:-1;;;;;74739:6:0;30098:10;74886:23;74878:68;;;;-1:-1:-1;;;74878:68:0;;;;;;;:::i;:::-;91346:13:::1;:21:::0;91275:100::o;91173:94::-;74739:6;;-1:-1:-1;;;;;74739:6:0;30098:10;74886:23;74878:68;;;;-1:-1:-1;;;74878:68:0;;;;;;;:::i;:::-;91241:10:::1;:18:::0;91173:94::o;91383:96::-;74739:6;;-1:-1:-1;;;;;74739:6:0;30098:10;74886:23;74878:68;;;;-1:-1:-1;;;74878:68:0;;;;;;;:::i;:::-;91452:11:::1;:19:::0;91383:96::o;80490:112::-;80570:24;;-1:-1:-1;;;80570:24:0;;-1:-1:-1;;;;;9351:32:1;;;80570:24:0;;;9333:51:1;80543:7:0;;80570;:18;;;;;;9306::1;;80570:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;92982:126::-;74739:6;;-1:-1:-1;;;;;74739:6:0;30098:10;74886:23;74878:68;;;;-1:-1:-1;;;74878:68:0;;;;;;;:::i;:::-;93068:32;;::::1;::::0;:14:::1;::::0;:32:::1;::::0;::::1;::::0;::::1;:::i;75575:201::-:0;74739:6;;-1:-1:-1;;;;;74739:6:0;30098:10;74886:23;74878:68;;;;-1:-1:-1;;;74878:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;75664:22:0;::::1;75656:73;;;::::0;-1:-1:-1;;;75656:73:0;;12708:2:1;75656:73:0::1;::::0;::::1;12690:21:1::0;12747:2;12727:18;;;12720:30;12786:34;12766:18;;;12759:62;-1:-1:-1;;;12837:18:1;;;12830:36;12883:19;;75656:73:0::1;12680:228:1::0;75656:73:0::1;75740:28;75759:8;75740:18;:28::i;1064:127::-:0;1153:19;;1171:1;1153:19;;;1064:127::o;67450:224::-;67552:4;-1:-1:-1;;;;;;67576:50:0;;-1:-1:-1;;;67576:50:0;;:90;;;67630:36;67654:11;67630:23;:36::i;62137:174::-;62212:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;62212:29:0;-1:-1:-1;;;;;62212:29:0;;;;;;;;:24;;62266:23;62212:24;62266:14;:23::i;:::-;-1:-1:-1;;;;;62257:46:0;;;;;;;;;;;62137:174;;:::o;93517:328::-;93567:15;93613:25;:15;1034:14;;942:114;93613:25;93603:35;-1:-1:-1;93726:16:0;93739:3;88691:4;93726:16;:::i;:::-;93716:26;;:7;:26;93708:48;;;;-1:-1:-1;;;93708:48:0;;21964:2:1;93708:48:0;;;21946:21:1;22003:1;21983:18;;;21976:29;-1:-1:-1;;;22021:18:1;;;22014:39;22070:18;;93708:48:0;21936:158:1;93708:48:0;93767:27;:15;1153:19;;1171:1;1153:19;;;1064:127;93767:27;93807:30;93817:3;93822:5;93828:7;93822:14;;;;;;-1:-1:-1;;;93822:14:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;93807:9;:30::i;58285:348::-;58378:4;58080:16;;;:7;:16;;;;;;-1:-1:-1;;;;;58080:16:0;58395:73;;;;-1:-1:-1;;;58395:73:0;;15422:2:1;58395:73:0;;;15404:21:1;15461:2;15441:18;;;15434:30;15500:34;15480:18;;;15473:62;-1:-1:-1;;;15551:18:1;;;15544:42;15603:19;;58395:73:0;15394:234:1;58395:73:0;58479:13;58495:23;58510:7;58495:14;:23::i;:::-;58479:39;;58548:5;-1:-1:-1;;;;;58537:16:0;:7;-1:-1:-1;;;;;58537:16:0;;:51;;;;58581:7;-1:-1:-1;;;;;58557:31:0;:20;58569:7;58557:11;:20::i;:::-;-1:-1:-1;;;;;58557:31:0;;58537:51;:87;;;-1:-1:-1;;;;;;55377:25:0;;;55353:4;55377:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;58592:32;58529:96;58285:348;-1:-1:-1;;;;58285:348:0:o;61394:625::-;61553:4;-1:-1:-1;;;;;61526:31:0;:23;61541:7;61526:14;:23::i;:::-;-1:-1:-1;;;;;61526:31:0;;61518:81;;;;-1:-1:-1;;;61518:81:0;;13115:2:1;61518:81:0;;;13097:21:1;13154:2;13134:18;;;13127:30;13193:34;13173:18;;;13166:62;-1:-1:-1;;;13244:18:1;;;13237:35;13289:19;;61518:81:0;13087:227:1;61518:81:0;-1:-1:-1;;;;;61618:16:0;;61610:65;;;;-1:-1:-1;;;61610:65:0;;13878:2:1;61610:65:0;;;13860:21:1;13917:2;13897:18;;;13890:30;13956:34;13936:18;;;13929:62;-1:-1:-1;;;14007:18:1;;;14000:34;14051:19;;61610:65:0;13850:226:1;61610:65:0;61688:39;61709:4;61715:2;61719:7;61688:20;:39::i;:::-;61792:29;61809:1;61813:7;61792:8;:29::i;:::-;-1:-1:-1;;;;;61834:15:0;;;;;;:9;:15;;;;;:20;;61853:1;;61834:15;:20;;61853:1;;61834:20;:::i;:::-;;;;-1:-1:-1;;;;;;;61865:13:0;;;;;;:9;:13;;;;;:18;;61882:1;;61865:13;:18;;61882:1;;61865:18;:::i;:::-;;;;-1:-1:-1;;61894:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;61894:21:0;-1:-1:-1;;;;;61894:21:0;;;;;;;;;61933:27;;61894:16;;61933:27;;;;;;;54260:411;;;:::o;80260:106::-;80335:23;;-1:-1:-1;;;80335:23:0;;-1:-1:-1;;;;;9351:32:1;;;80335:23:0;;;9333:51:1;80335:7:0;:16;;;;9306:18:1;;80335:23:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80260:106;:::o;23322:317::-;23437:6;23412:21;:31;;23404:73;;;;-1:-1:-1;;;23404:73:0;;15064:2:1;23404:73:0;;;15046:21:1;15103:2;15083:18;;;15076:30;15142:31;15122:18;;;15115:59;15191:18;;23404:73:0;15036:179:1;23404:73:0;23491:12;23509:9;-1:-1:-1;;;;;23509:14:0;23531:6;23509:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;23490:52;;;23561:7;23553:78;;;;-1:-1:-1;;;23553:78:0;;14637:2:1;23553:78:0;;;14619:21:1;14676:2;14656:18;;;14649:30;14715:34;14695:18;;;14688:62;14786:28;14766:18;;;14759:56;14832:19;;23553:78:0;14609:248:1;83301:120:0;82313:7;;-1:-1:-1;;;82313:7:0;;;;82837:41;;;;-1:-1:-1;;;82837:41:0;;11528:2:1;82837:41:0;;;11510:21:1;11567:2;11547:18;;;11540:30;-1:-1:-1;;;11586:18:1;;;11579:50;11646:18;;82837:41:0;11500:170:1;82837:41:0;83360:7:::1;:15:::0;;-1:-1:-1;;;;83360:15:0::1;::::0;;83391:22:::1;30098:10:::0;83400:12:::1;83391:22;::::0;-1:-1:-1;;;;;9351:32:1;;;9333:51;;9321:2;9306:18;83391:22:0::1;;;;;;;83301:120::o:0;58975:110::-;59051:26;59061:2;59065:7;59051:26;;;;;;;;;;;;:9;:26::i;75936:191::-;76029:6;;;-1:-1:-1;;;;;76046:17:0;;;-1:-1:-1;;;;;;76046:17:0;;;;;;;76079:40;;76029:6;;;76046:17;76029:6;;76079:40;;76010:16;;76079:40;75936:191;;:::o;83042:118::-;82313:7;;-1:-1:-1;;;82313:7:0;;;;82567:9;82559:38;;;;-1:-1:-1;;;82559:38:0;;15835:2:1;82559:38:0;;;15817:21:1;15874:2;15854:18;;;15847:30;-1:-1:-1;;;15893:18:1;;;15886:46;15949:18;;82559:38:0;15807:166:1;82559:38:0;83102:7:::1;:14:::0;;-1:-1:-1;;;;83102:14:0::1;-1:-1:-1::0;;;83102:14:0::1;::::0;;83132:20:::1;83139:12;30098:10:::0;;30018:98;11288;11346:7;11373:5;11377:1;11373;:5;:::i;:::-;11366:12;11288:98;-1:-1:-1;;;11288:98:0:o;12671:669::-;12743:7;12775:1;12771;:5;12763:34;;;;-1:-1:-1;;;12763:34:0;;18200:2:1;12763:34:0;;;18182:21:1;18239:2;18219:18;;;18212:30;-1:-1:-1;;;18258:18:1;;;18251:46;18314:18;;12763:34:0;18172:166:1;12763:34:0;12814:6;12810:20;;-1:-1:-1;12829:1:0;12822:8;;12810:20;12841:10;12854:5;12858:1;12854;:5;:::i;:::-;12841:18;-1:-1:-1;12884:1:0;12874:6;12879:1;12841:18;12874:6;:::i;:::-;:11;12870:107;;;12959:6;12964:1;12959:2;:6;:::i;:::-;12952:13;;;;;12870:107;13049:9;13061:5;13065:1;13061;:5;:::i;:::-;13049:17;-1:-1:-1;13077:9:0;13089:5;13093:1;13089;:5;:::i;:::-;13077:17;-1:-1:-1;13184:9:0;13196:5;13200:1;13196;:5;:::i;:::-;13184:17;-1:-1:-1;13212:9:0;13224:5;13228:1;13224;:5;:::i;:::-;13212:17;-1:-1:-1;13266:66:0;13316:15;13329:1;13316:8;:1;13212:17;13316:5;:8::i;:::-;:12;;:15::i;:::-;13266:45;13302:8;:1;13308;13302:5;:8::i;:::-;13266:31;13288:8;:1;13294;13288:5;:8::i;:::-;13267:15;13280:1;13267:8;:1;13273;13267:5;:8::i;:::-;:12;;:15::i;:::-;13266:21;;:31::i;:66::-;13259:73;12671:669;-1:-1:-1;;;;;;;;;12671:669:0:o;80971:126::-;81053:36;;-1:-1:-1;;;81053:36:0;;-1:-1:-1;;;;;9351:32:1;;;81053:36:0;;;9333:51:1;81053:7:0;:15;;;;81076:6;;9306:18:1;;81053:36:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80971:126;;:::o;62453:315::-;62608:8;-1:-1:-1;;;;;62599:17:0;:5;-1:-1:-1;;;;;62599:17:0;;;62591:55;;;;-1:-1:-1;;;62591:55:0;;14283:2:1;62591:55:0;;;14265:21:1;14322:2;14302:18;;;14295:30;14361:27;14341:18;;;14334:55;14406:18;;62591:55:0;14255:175:1;62591:55:0;-1:-1:-1;;;;;62657:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;62657:46:0;;;;;;;;;;62719:41;;10826::1;;;62719::0;;10799:18:1;62719:41:0;;;;;;;62453:315;;;:::o;57363:::-;57520:28;57530:4;57536:2;57540:7;57520:9;:28::i;:::-;57567:48;57590:4;57596:2;57600:7;57609:5;57567:22;:48::i;:::-;57559:111;;;;-1:-1:-1;;;57559:111:0;;;;;;;:::i;49061:723::-;49117:13;49338:10;49334:53;;-1:-1:-1;;49365:10:0;;;;;;;;;;;;-1:-1:-1;;;49365:10:0;;;;;49061:723::o;49334:53::-;49412:5;49397:12;49453:78;49460:9;;49453:78;;49486:8;;;;:::i;:::-;;-1:-1:-1;49509:10:0;;-1:-1:-1;49517:2:0;49509:10;;:::i;:::-;;;49453:78;;;49541:19;49573:6;49563:17;;;;;;-1:-1:-1;;;49563:17:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;49563:17:0;;49541:39;;49591:154;49598:10;;49591:154;;49625:11;49635:1;49625:11;;:::i;:::-;;-1:-1:-1;49694:10:0;49702:2;49694:5;:10;:::i;:::-;49681:24;;:2;:24;:::i;:::-;49668:39;;49651:6;49658;49651:14;;;;;;-1:-1:-1;;;49651:14:0;;;;;;;;;;;;:56;-1:-1:-1;;;;;49651:56:0;;;;;;;;-1:-1:-1;49722:11:0;49731:2;49722:11;;:::i;:::-;;;49591:154;;52233:305;52335:4;-1:-1:-1;;;;;;52372:40:0;;-1:-1:-1;;;52372:40:0;;:105;;-1:-1:-1;;;;;;;52429:48:0;;-1:-1:-1;;;52429:48:0;52372:105;:158;;;-1:-1:-1;;;;;;;;;;31212:40:0;;;52494:36;31103:157;86965:155;87067:45;87094:4;87100:2;87104:7;87067:26;:45::i;59312:321::-;59442:18;59448:2;59452:7;59442:5;:18::i;:::-;59493:54;59524:1;59528:2;59532:7;59541:5;59493:22;:54::i;:::-;59471:154;;;;-1:-1:-1;;;59471:154:0;;;;;;;:::i;11687:98::-;11745:7;11772:5;11776:1;11772;:5;:::i;10550:98::-;10608:7;10635:5;10639:1;10635;:5;:::i;63333:799::-;63488:4;-1:-1:-1;;;;;63509:13:0;;22356:19;:23;63505:620;;63545:72;;-1:-1:-1;;;63545:72:0;;-1:-1:-1;;;;;63545:36:0;;;;;:72;;30098:10;;63596:4;;63602:7;;63611:5;;63545:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;63545:72:0;;;;;;;;-1:-1:-1;;63545:72:0;;;;;;;;;;;;:::i;:::-;;;63541:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;63787:13:0;;63783:272;;63830:60;;-1:-1:-1;;;63830:60:0;;;;;;;:::i;63783:272::-;64005:6;63999:13;63990:6;63986:2;63982:15;63975:38;63541:529;-1:-1:-1;;;;;;63668:51:0;-1:-1:-1;;;63668:51:0;;-1:-1:-1;63661:58:0;;63505:620;-1:-1:-1;64109:4:0;63333:799;;;;;;:::o;69126:589::-;-1:-1:-1;;;;;69332:18:0;;69328:187;;69367:40;69399:7;70542:10;:17;;70515:24;;;;:15;:24;;;;;:44;;;70570:24;;;;;;;;;;;;70438:164;69367:40;69328:187;;;69437:2;-1:-1:-1;;;;;69429:10:0;:4;-1:-1:-1;;;;;69429:10:0;;69425:90;;69456:47;69489:4;69495:7;69456:32;:47::i;:::-;-1:-1:-1;;;;;69529:16:0;;69525:183;;69562:45;69599:7;69562:36;:45::i;69525:183::-;69635:4;-1:-1:-1;;;;;69629:10:0;:2;-1:-1:-1;;;;;69629:10:0;;69625:83;;69656:40;69684:2;69688:7;69656:27;:40::i;59969:439::-;-1:-1:-1;;;;;60049:16:0;;60041:61;;;;-1:-1:-1;;;60041:61:0;;17426:2:1;60041:61:0;;;17408:21:1;;;17445:18;;;17438:30;17504:34;17484:18;;;17477:62;17556:18;;60041:61:0;17398:182:1;60041:61:0;58056:4;58080:16;;;:7;:16;;;;;;-1:-1:-1;;;;;58080:16:0;:30;60113:58;;;;-1:-1:-1;;;60113:58:0;;13521:2:1;60113:58:0;;;13503:21:1;13560:2;13540:18;;;13533:30;13599;13579:18;;;13572:58;13647:18;;60113:58:0;13493:178:1;60113:58:0;60184:45;60213:1;60217:2;60221:7;60184:20;:45::i;:::-;-1:-1:-1;;;;;60242:13:0;;;;;;:9;:13;;;;;:18;;60259:1;;60242:13;:18;;60259:1;;60242:18;:::i;:::-;;;;-1:-1:-1;;60271:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;60271:21:0;-1:-1:-1;;;;;60271:21:0;;;;;;;;60310:33;;60271:16;;;60310:33;;60271:16;;60310:33;91830:18:::1;91757:99:::0;:::o;71229:988::-;71495:22;71545:1;71520:22;71537:4;71520:16;:22::i;:::-;:26;;;;:::i;:::-;71557:18;71578:26;;;:17;:26;;;;;;71495:51;;-1:-1:-1;71711:28:0;;;71707:328;;-1:-1:-1;;;;;71778:18:0;;71756:19;71778:18;;;:12;:18;;;;;;;;:34;;;;;;;;;71829:30;;;;;;:44;;;71946:30;;:17;:30;;;;;:43;;;71707:328;-1:-1:-1;72131:26:0;;;;:17;:26;;;;;;;;72124:33;;;-1:-1:-1;;;;;72175:18:0;;;;;:12;:18;;;;;:34;;;;;;;72168:41;71229:988::o;72512:1079::-;72790:10;:17;72765:22;;72790:21;;72810:1;;72790:21;:::i;:::-;72822:18;72843:24;;;:15;:24;;;;;;73216:10;:26;;72765:46;;-1:-1:-1;72843:24:0;;72765:46;;73216:26;;;;-1:-1:-1;;;73216:26:0;;;;;;;;;;;;;;;;;73194:48;;73280:11;73255:10;73266;73255:22;;;;;;-1:-1:-1;;;73255:22:0;;;;;;;;;;;;;;;;;;;;:36;;;;73360:28;;;:15;:28;;;;;;;:41;;;73532:24;;;;;73525:31;73567:10;:16;;;;;-1:-1:-1;;;73567:16:0;;;;;;;;;;;;;;;;;;;;;;;;;;72512:1079;;;;:::o;70016:221::-;70101:14;70118:20;70135:2;70118:16;:20::i;:::-;-1:-1:-1;;;;;70149:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;70194:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;70016:221:0:o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:631:1;78:5;108:18;149:2;141:6;138:14;135:2;;;155:18;;:::i;:::-;230:2;224:9;198:2;284:15;;-1:-1:-1;;280:24:1;;;306:2;276:33;272:42;260:55;;;330:18;;;350:22;;;327:46;324:2;;;376:18;;:::i;:::-;416:10;412:2;405:22;445:6;436:15;;475:6;467;460:22;515:3;506:6;501:3;497:16;494:25;491:2;;;532:1;529;522:12;491:2;582:6;577:3;570:4;562:6;558:17;545:44;637:1;630:4;621:6;613;609:19;605:30;598:41;;;;88:557;;;;;:::o;650:395::-;713:8;723:6;777:3;770:4;762:6;758:17;754:27;744:2;;802:8;792;785:26;744:2;-1:-1:-1;832:20:1;;875:18;864:30;;861:2;;;914:8;904;897:26;861:2;958:4;950:6;946:17;934:29;;1018:3;1011:4;1001:6;998:1;994:14;986:6;982:27;978:38;975:47;972:2;;;1035:1;1032;1025:12;972:2;734:311;;;;;:::o;1050:257::-;1109:6;1162:2;1150:9;1141:7;1137:23;1133:32;1130:2;;;1183:6;1175;1168:22;1130:2;1227:9;1214:23;1246:31;1271:5;1246:31;:::i;1582:398::-;1650:6;1658;1711:2;1699:9;1690:7;1686:23;1682:32;1679:2;;;1732:6;1724;1717:22;1679:2;1776:9;1763:23;1795:31;1820:5;1795:31;:::i;:::-;1845:5;-1:-1:-1;1902:2:1;1887:18;;1874:32;1915:33;1874:32;1915:33;:::i;:::-;1967:7;1957:17;;;1669:311;;;;;:::o;1985:466::-;2062:6;2070;2078;2131:2;2119:9;2110:7;2106:23;2102:32;2099:2;;;2152:6;2144;2137:22;2099:2;2196:9;2183:23;2215:31;2240:5;2215:31;:::i;:::-;2265:5;-1:-1:-1;2322:2:1;2307:18;;2294:32;2335:33;2294:32;2335:33;:::i;:::-;2089:362;;2387:7;;-1:-1:-1;;;2441:2:1;2426:18;;;;2413:32;;2089:362::o;2456:824::-;2551:6;2559;2567;2575;2628:3;2616:9;2607:7;2603:23;2599:33;2596:2;;;2650:6;2642;2635:22;2596:2;2694:9;2681:23;2713:31;2738:5;2713:31;:::i;:::-;2763:5;-1:-1:-1;2820:2:1;2805:18;;2792:32;2833:33;2792:32;2833:33;:::i;:::-;2885:7;-1:-1:-1;2939:2:1;2924:18;;2911:32;;-1:-1:-1;2994:2:1;2979:18;;2966:32;3021:18;3010:30;;3007:2;;;3058:6;3050;3043:22;3007:2;3086:22;;3139:4;3131:13;;3127:27;-1:-1:-1;3117:2:1;;3173:6;3165;3158:22;3117:2;3201:73;3266:7;3261:2;3248:16;3243:2;3239;3235:11;3201:73;:::i;:::-;3191:83;;;2586:694;;;;;;;:::o;3285:436::-;3350:6;3358;3411:2;3399:9;3390:7;3386:23;3382:32;3379:2;;;3432:6;3424;3417:22;3379:2;3476:9;3463:23;3495:31;3520:5;3495:31;:::i;:::-;3545:5;-1:-1:-1;3602:2:1;3587:18;;3574:32;3644:15;;3637:23;3625:36;;3615:2;;3680:6;3672;3665:22;3726:325;3794:6;3802;3855:2;3843:9;3834:7;3830:23;3826:32;3823:2;;;3876:6;3868;3861:22;3823:2;3920:9;3907:23;3939:31;3964:5;3939:31;:::i;:::-;3989:5;4041:2;4026:18;;;;4013:32;;-1:-1:-1;;;3813:238:1:o;4056:457::-;4142:6;4150;4203:2;4191:9;4182:7;4178:23;4174:32;4171:2;;;4224:6;4216;4209:22;4171:2;4269:9;4256:23;4302:18;4294:6;4291:30;4288:2;;;4339:6;4331;4324:22;4288:2;4383:70;4445:7;4436:6;4425:9;4421:22;4383:70;:::i;:::-;4472:8;;4357:96;;-1:-1:-1;4161:352:1;-1:-1:-1;;;;4161:352:1:o;4518:255::-;4576:6;4629:2;4617:9;4608:7;4604:23;4600:32;4597:2;;;4650:6;4642;4635:22;4597:2;4694:9;4681:23;4713:30;4737:5;4713:30;:::i;4778:259::-;4847:6;4900:2;4888:9;4879:7;4875:23;4871:32;4868:2;;;4921:6;4913;4906:22;4868:2;4958:9;4952:16;4977:30;5001:5;4977:30;:::i;5042:480::-;5111:6;5164:2;5152:9;5143:7;5139:23;5135:32;5132:2;;;5185:6;5177;5170:22;5132:2;5230:9;5217:23;5263:18;5255:6;5252:30;5249:2;;;5300:6;5292;5285:22;5249:2;5328:22;;5381:4;5373:13;;5369:27;-1:-1:-1;5359:2:1;;5415:6;5407;5400:22;5359:2;5443:73;5508:7;5503:2;5490:16;5485:2;5481;5477:11;5443:73;:::i;5527:292::-;5585:6;5638:2;5626:9;5617:7;5613:23;5609:32;5606:2;;;5659:6;5651;5644:22;5606:2;5703:9;5690:23;5753:6;5746:5;5742:18;5735:5;5732:29;5722:2;;5780:6;5772;5765:22;5824:190;5883:6;5936:2;5924:9;5915:7;5911:23;5907:32;5904:2;;;5957:6;5949;5942:22;5904:2;-1:-1:-1;5985:23:1;;5894:120;-1:-1:-1;5894:120:1:o;6019:194::-;6089:6;6142:2;6130:9;6121:7;6117:23;6113:32;6110:2;;;6163:6;6155;6148:22;6110:2;-1:-1:-1;6191:16:1;;6100:113;-1:-1:-1;6100:113:1:o;6218:623::-;6310:6;6318;6326;6379:2;6367:9;6358:7;6354:23;6350:32;6347:2;;;6400:6;6392;6385:22;6347:2;6444:9;6431:23;6494:4;6487:5;6483:16;6476:5;6473:27;6463:2;;6519:6;6511;6504:22;6463:2;6547:5;-1:-1:-1;6603:2:1;6588:18;;6575:32;6630:18;6619:30;;6616:2;;;6667:6;6659;6652:22;6616:2;6711:70;6773:7;6764:6;6753:9;6749:22;6711:70;:::i;:::-;6337:504;;6800:8;;-1:-1:-1;6685:96:1;;-1:-1:-1;;;;6337:504:1:o;6846:257::-;6887:3;6925:5;6919:12;6952:6;6947:3;6940:19;6968:63;7024:6;7017:4;7012:3;7008:14;7001:4;6994:5;6990:16;6968:63;:::i;:::-;7085:2;7064:15;-1:-1:-1;;7060:29:1;7051:39;;;;7092:4;7047:50;;6895:208;-1:-1:-1;;6895:208:1:o;7108:185::-;7150:3;7188:5;7182:12;7203:52;7248:6;7243:3;7236:4;7229:5;7225:16;7203:52;:::i;:::-;7271:16;;;;;7158:135;-1:-1:-1;;7158:135:1:o;7535:1437::-;7913:3;7942;7977:6;7971:13;8007:3;8029:1;8057:9;8053:2;8049:18;8039:28;;8117:2;8106:9;8102:18;8139;8129:2;;8183:4;8175:6;8171:17;8161:27;;8129:2;8209;8257;8249:6;8246:14;8226:18;8223:38;8220:2;;;-1:-1:-1;;;8284:33:1;;8340:4;8337:1;8330:15;8370:4;8291:3;8358:17;8220:2;8401:18;8428:104;;;;8546:1;8541:322;;;;8394:469;;8428:104;-1:-1:-1;;8461:24:1;;8449:37;;8506:16;;;;-1:-1:-1;8428:104:1;;8541:322;22940:4;22959:17;;;23009:4;22993:21;;8636:3;8652:165;8666:6;8663:1;8660:13;8652:165;;;8744:14;;8731:11;;;8724:35;8787:16;;;;8681:10;;8652:165;;;8656:3;;8846:6;8841:3;8837:16;8830:23;;8394:469;;;;;;;8879:87;8904:61;8930:34;8960:3;-1:-1:-1;;;7481:16:1;;7522:1;7513:11;;7471:59;8930:34;8922:6;8904:61;:::i;:::-;-1:-1:-1;;;7358:20:1;;7403:1;7394:11;;7348:63;8879:87;8872:94;7921:1051;-1:-1:-1;;;;;7921:1051:1:o;9619:488::-;-1:-1:-1;;;;;9888:15:1;;;9870:34;;9940:15;;9935:2;9920:18;;9913:43;9987:2;9972:18;;9965:34;;;10035:3;10030:2;10015:18;;10008:31;;;9813:4;;10056:45;;10081:19;;10073:6;10056:45;:::i;:::-;10048:53;9822:285;-1:-1:-1;;;;;;9822:285:1:o;11102:219::-;11251:2;11240:9;11233:21;11214:4;11271:44;11311:2;11300:9;11296:18;11288:6;11271:44;:::i;12087:414::-;12289:2;12271:21;;;12328:2;12308:18;;;12301:30;12367:34;12362:2;12347:18;;12340:62;-1:-1:-1;;;12433:2:1;12418:18;;12411:48;12491:3;12476:19;;12261:240::o;18343:356::-;18545:2;18527:21;;;18564:18;;;18557:30;18623:34;18618:2;18603:18;;18596:62;18690:2;18675:18;;18517:182::o;19522:413::-;19724:2;19706:21;;;19763:2;19743:18;;;19736:30;19802:34;19797:2;19782:18;;19775:62;-1:-1:-1;;;19868:2:1;19853:18;;19846:47;19925:3;19910:19;;19696:239::o;23025:128::-;23065:3;23096:1;23092:6;23089:1;23086:13;23083:2;;;23102:18;;:::i;:::-;-1:-1:-1;23138:9:1;;23073:80::o;23158:204::-;23196:3;23232:4;23229:1;23225:12;23264:4;23261:1;23257:12;23299:3;23293:4;23289:14;23284:3;23281:23;23278:2;;;23307:18;;:::i;:::-;23343:13;;23204:158;-1:-1:-1;;;23204:158:1:o;23367:120::-;23407:1;23433;23423:2;;23438:18;;:::i;:::-;-1:-1:-1;23472:9:1;;23413:74::o;23492:168::-;23532:7;23598:1;23594;23590:6;23586:14;23583:1;23580:21;23575:1;23568:9;23561:17;23557:45;23554:2;;;23605:18;;:::i;:::-;-1:-1:-1;23645:9:1;;23544:116::o;23665:125::-;23705:4;23733:1;23730;23727:8;23724:2;;;23738:18;;:::i;:::-;-1:-1:-1;23775:9:1;;23714:76::o;23795:229::-;23834:4;23863:18;23931:10;;;;23901;;23953:12;;;23950:2;;;23968:18;;:::i;:::-;24005:13;;23843:181;-1:-1:-1;;;23843:181:1:o;24029:258::-;24101:1;24111:113;24125:6;24122:1;24119:13;24111:113;;;24201:11;;;24195:18;24182:11;;;24175:39;24147:2;24140:10;24111:113;;;24242:6;24239:1;24236:13;24233:2;;;-1:-1:-1;;24277:1:1;24259:16;;24252:27;24082:205::o;24292:380::-;24371:1;24367:12;;;;24414;;;24435:2;;24489:4;24481:6;24477:17;24467:27;;24435:2;24542;24534:6;24531:14;24511:18;24508:38;24505:2;;;24588:10;24583:3;24579:20;24576:1;24569:31;24623:4;24620:1;24613:15;24651:4;24648:1;24641:15;24505:2;;24347:325;;;:::o;24677:135::-;24716:3;-1:-1:-1;;24737:17:1;;24734:2;;;24757:18;;:::i;:::-;-1:-1:-1;24804:1:1;24793:13;;24724:88::o;24817:112::-;24849:1;24875;24865:2;;24880:18;;:::i;:::-;-1:-1:-1;24914:9:1;;24855:74::o;24934:127::-;24995:10;24990:3;24986:20;24983:1;24976:31;25026:4;25023:1;25016:15;25050:4;25047:1;25040:15;25066:127;25127:10;25122:3;25118:20;25115:1;25108:31;25158:4;25155:1;25148:15;25182:4;25179:1;25172:15;25198:127;25259:10;25254:3;25250:20;25247:1;25240:31;25290:4;25287:1;25280:15;25314:4;25311:1;25304:15;25330:131;-1:-1:-1;;;;;25405:31:1;;25395:42;;25385:2;;25451:1;25448;25441:12;25466:131;-1:-1:-1;;;;;;25540:32:1;;25530:43;;25520:2;;25587:1;25584;25577:12

Swarm Source

ipfs://97aaf8330e2b679c3d08b05923d025844a488ff53c65b2f148c20b20172688e8
Loading