ETH Price: $2,318.22 (+0.63%)

Contract

0xE40C6b5b2CeD59fe58750271425C31aD248e1236
 

Overview

ETH Balance

0 ETH

Eth Value

$0.00

Multichain Info

No addresses found
Transaction Hash
Method
Block
From
To
Set Approval For...139592352022-01-07 15:56:20975 days ago1641570980IN
ShapesArt: SHPS_ART Token
0 ETH0.00900745195.10602559
Withdraw All138800142021-12-26 9:32:29988 days ago1640511149IN
ShapesArt: SHPS_ART Token
0.26 ETH0.0013846645.7090326
Transfer Ownersh...138283632021-12-18 9:35:40996 days ago1639820140IN
ShapesArt: SHPS_ART Token
0 ETH0.0012717844.38433821
Mint137658342021-12-08 16:29:081005 days ago1638980948IN
ShapesArt: SHPS_ART Token
0.05 ETH0.0234767486.01022485
Mint137641032021-12-08 9:37:371006 days ago1638956257IN
ShapesArt: SHPS_ART Token
0.125 ETH0.0298705348.29542972
Mint137597672021-12-07 17:12:531006 days ago1638897173IN
ShapesArt: SHPS_ART Token
0.125 ETH0.0578319793.08280185
Mint137592352021-12-07 15:10:291006 days ago1638889829IN
ShapesArt: SHPS_ART Token
0.025 ETH0.01743516110.50862769
Toggle All Sales...137591692021-12-07 14:54:451006 days ago1638888885IN
ShapesArt: SHPS_ART Token
0 ETH0.0022523195.21915207
Toggle All Sales...137534572021-12-06 16:56:201007 days ago1638809780IN
ShapesArt: SHPS_ART Token
0 ETH0.00553845121.57989729
Mint137534532021-12-06 16:54:091007 days ago1638809649IN
ShapesArt: SHPS_ART Token
0.05 ETH0.02744082100.53316573
Toggle All Sales...137534332021-12-06 16:48:501007 days ago1638809330IN
ShapesArt: SHPS_ART Token
0 ETH0.0018662878.89929721
Toggle All Sales...137520662021-12-06 11:38:241007 days ago1638790704IN
ShapesArt: SHPS_ART Token
0 ETH0.0040323688.51845021
Toggle All Sales...137520322021-12-06 11:31:281007 days ago1638790288IN
ShapesArt: SHPS_ART Token
0 ETH0.0022831896.52445664
Set Approval For...137479992021-12-05 20:05:311008 days ago1638734731IN
ShapesArt: SHPS_ART Token
0 ETH0.00652979141.43851296
Toggle All Sales...137479992021-12-05 20:05:311008 days ago1638734731IN
ShapesArt: SHPS_ART Token
0 ETH0.00331769140.93851296
Toggle All Sales...137449632021-12-05 8:12:591009 days ago1638691979IN
ShapesArt: SHPS_ART Token
0 ETH0.0034619275.99604133
Mint137435182021-12-05 2:56:531009 days ago1638673013IN
ShapesArt: SHPS_ART Token
0.025 ETH0.0133709183.27050781
Mint137434742021-12-05 2:47:001009 days ago1638672420IN
ShapesArt: SHPS_ART Token
0.025 ETH0.01890532109.86866815
0x60806040137418672021-12-04 20:30:561009 days ago1638649856IN
 Create: ShapesArt
0 ETH0.2606267468.60241329

Latest 1 internal transaction

Advanced mode:
Parent Transaction Hash Block From To
138800142021-12-26 9:32:29988 days ago1640511149
ShapesArt: SHPS_ART Token
0.685 ETH
Loading...
Loading

Contract Source Code Verified (Exact Match)

Contract Name:
ShapesArt

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion
File 1 of 1 : ShapeArt.sol
// File: contracts/AutumnLeaf.sol

pragma solidity ^0.8.7;
//SPDX-License-Identifier: Unlicense


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






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

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

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

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

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

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

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

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

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

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

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

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




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

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

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

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

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




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

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









/**
 * @dev 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() {
        _setOwner(_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 {
        _setOwner(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");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}





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














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







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

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

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





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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

    function _verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) private pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

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









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


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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

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

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(from, to, tokenId);
    }

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

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

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







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

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

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

library ShapeArtGenerator{
    struct ShapeArt{
        uint256 bgcolor;
        uint256 numshapes;
        uint256 animation;
        uint256 monochrome;
        uint256 textured;
    }
    struct shapeStruct{
        uint256 x;
        uint256 y;
        uint256 height;
        uint256 width;
        uint256 shapeindex;
        uint256 yoffset;
        uint256 colortype;
    }
    function random(string memory input) internal pure returns (uint256) {
        return uint256(keccak256(abi.encodePacked(input)));
    }
    function pluckNum(uint256 tokenId, string memory keyPrefix, uint256 minNum, uint256 maxNum) internal pure returns (uint256) {
        uint256 rand = random(string(abi.encodePacked(keyPrefix, toString(tokenId), toString(minNum), toString(maxNum))));
        uint256 num = rand % (maxNum - minNum + 1) + minNum;
        return num;
    }

    function getNumShapes(uint256 tokenId) internal pure returns(uint256){
       uint256 rand = random(string(abi.encodePacked("NUM_SHAPES", toString(tokenId))));
       rand = rand % 201;
       uint256 ps=5;
       if(rand>110 && rand<=160){ps=6;}
       if(rand>160 && rand<=200){ps=4;}
       return ps;
   }

   function getAnimation(uint256 tokenId) internal pure returns(uint256){
       uint256 rand = random(string(abi.encodePacked("ANIMATION", toString(tokenId))));
       rand = rand % 201;
       uint256 ps;
       if(rand > 186 && rand <= 195){ps=1;}
       if(rand > 140 && rand <= 150){ps=2;}
       return ps;
   }

   function getMonochrome(uint256 tokenId) internal pure returns(uint256){
       uint256 rand = random(string(abi.encodePacked("MONOCHROME", toString(tokenId))));
       rand = rand % 201;
       uint256 ps;
       if(rand > 160){ps=1;}
       return ps;
   }

    function getTextured(uint256 tokenId) internal pure returns(uint256){
        uint256 rand = random(string(abi.encodePacked("TEXTURED", toString(tokenId))));
        rand = rand % 201;
        uint256 ps;
        if(rand > 170){ps=1;}
        return ps;
    }

   function getShape(uint256 tokenId,uint256 i) internal pure returns(uint256){
        uint256 rand = random(string(abi.encodePacked("Shape_Type", toString(tokenId),toString(i))));
       rand = rand % 201;
       uint256 ps;
       if(rand>22 && rand<=44){ps=1;}
       if(rand>44 && rand<=66){ps=2;}
       if(rand>66 && rand<=88){ps=3;}
       if(rand>88 && rand<=110){ps=4;}
       if(rand>110 && rand<=132){ps=5;}
       if(rand>132 && rand<=154){ps=6;}
       if(rand>154 && rand<=176){ps=7;}
       if(rand>176 && rand<=198){ps=8;}
       return ps;
   }
    function makeShapeFactory(uint256 tokenId) internal pure returns(ShapeArt memory,string memory){
        string[25] memory shapecolors=["#00E1DF", "#26F33A", "#06B2BB", "#BEB947", "#2A3166", "#F26419", "#B76CFD", "#0BF287", "#43ECE2", "#FBCC04", "#ED2995", "#E12B38", "#F71B2D", "#FA5456", "#E42C6A", "#DEE500", "#FFED00", "#BAF2D8","#FAF182", "#FFFFFF", "#0EA81F", "#000000", "#E53E34", "#0899D7","#1C6FFC"];
        string[9] memory paths=['<path d="M142.428 0L200 100H0L142.428 0Z" fill="',
                         '<rect width="200" height="89.2857" fill="',
                         '<circle cx="82" cy="82" r="82" fill="',
                         '<ellipse cx="100" cy="75.9162" rx="100" ry="75.9162" fill="',
                         '<path d="M0 0L200 0L127.684 82.4859L0 93.7853L0 0Z" fill="',
                         '<path d="M200 21.4L0 0L100.466 160.714L200 21.4Z" fill="',
                         '<path d="M43.7585 31.1205L200 0L142.467 111.788L0 144.643L43.7585 31.1205Z" fill="',
                         '<path d="M100 0L127.009 70.3841L200 96.4286L127.009 122.473L100 192.857L72.9909 122.473L0 96.4286L72.9909 70.3841L100 0Z" fill="',
                         '<path d="M159.489 7.83204C159.489 55.6026 123.786 94.3282 79.7447 94.3282C35.7029 94.3282 0 55.6026 0 7.83204C0 -39.9385 141.411 146.429 185.453 146.429C229.495 146.429 159.489 -39.9385 159.489 7.83204Z" fill="'];
        uint8[9] memory heights=[100,90,164,152,94,160,144,192,146];
        ShapeArt memory shape;
        shape.bgcolor = pluckNum(tokenId,"BG_COLOR",18,24);
        shape.numshapes = getNumShapes(tokenId);
        shape.animation = getAnimation(tokenId);
        shape.monochrome = getMonochrome(tokenId);
        shape.textured = getTextured(tokenId);
        shapeStruct memory attributes;
        attributes.yoffset=0;
        attributes.width=200;
        attributes.colortype = pluckNum(tokenId,toString(1391),0,9);
        string[7] memory parts;
        for(uint256 i=0;i<shape.numshapes;i++){
            attributes.shapeindex = getShape(tokenId,i);
            if(shape.monochrome==0){attributes.colortype = pluckNum(tokenId,toString(i*1800),0,17);}
            if(shape.numshapes==5){attributes.yoffset=53;}
            if(shape.numshapes==6){attributes.yoffset=45;}
            if(shape.numshapes==4){attributes.yoffset=62;}
            if(i>0){attributes.y += attributes.yoffset;}
            if(attributes.shapeindex==2){attributes.width = 164;}
            attributes.height = heights[attributes.shapeindex ]/2;
            attributes.x = pluckNum(tokenId,toString((i+1)*1111),0,63);
            parts[3] = string(abi.encodePacked(parts[3],'<g>',paths[attributes.shapeindex],shapecolors[attributes.colortype],'" fill-opacity="0.',
                        toString(pluckNum(tokenId,toString((i+1)*1784),68,78)),
                        '"  transform="translate(',
                        toString(68+attributes.x)));
            parts[3] = string(abi.encodePacked(parts[3],' ',
                                toString(100 + attributes.y),')  rotate(',
                                toString(pluckNum(tokenId,toString((i+1)*1666),0,180))));
            parts[3] = string(abi.encodePacked(parts[3],' ',toString(attributes.width/2),' ',toString(attributes.height),')"/></g>'));
        }
        if(shape.textured > 0){
            parts[4] = string(abi.encodePacked('<filter id="D" x="-50%" y="-50%" width="200%" height="200%">',
            '<feTurbulence type="fractalNoise" baseFrequency="0.9" numoctaves="1" seed="0"/>',
            '<feComposite operator="in" in2="SourceGraphic" result="monoNoise"/>',
            ' <feBlend in="SourceGraphic" in2="monoNoise" mode="multiply" /></filter>'));
        }
        if(shape.animation > 0){
            string memory anims='';
            if(shape.animation==1){anims = 'values="0;0;0.01;0.02;0.03;0.04;0.05;0.05;0.05;0.05;0.04;0.03;0.02;0.01;0;0"';}
            if(shape.animation==2){anims = 'values="0;0;0.01 0.4;0.02 0.4;0.03 0.4;0.04 0.4;0.04 0.4;0.04 0.4;0.04 0.4;0.03 0.4;0.02 0.4;0.01 0.4;0;0"';}
            parts[5] = string(abi.encodePacked('<filter xmlns="http://www.w3.org/2000/svg" id="C" x="-50%" y="-50%" width="200%" height="200%">',
            '<feTurbulence type="turbulence" baseFrequency="0.02" numOctaves="3" result="noise" seed="0">',
            '<animate attributeName="baseFrequency" dur="10s" ',
             anims,
            ' fill="freeze" repeatCount="indefinite"/></feTurbulence>',
            '<feDisplacementMap in2="noise" in="SourceGraphic" xChannelSelector="R" yChannelSelector="G" scale="80"></feDisplacementMap>',
            '</filter>'));
        }
        parts[0] = string(abi.encodePacked('<svg width="400" height="600" viewBox="0 0 400 600" fill="none" xmlns="http://www.w3.org/2000/svg"><rect width="400" height="600" fill="',shapecolors[shape.bgcolor]));
        parts[1] = string(abi.encodePacked((shape.textured > 0)?'" filter="url(#D)':'','"/>'));
        if(shape.animation > 0 && shape.textured > 0)
            parts[2] = '<g filter="url(#C) url(#D)">';
        else if(shape.animation > 0)
            parts[2] = '<g filter="url(#C)">';
        else if(shape.textured > 0)
            parts[2] = '<g filter="url(#D)">';
        else
            parts[2] = '<g>';
        parts[6] = '</g></svg>';
        return (shape,string(abi.encodePacked(parts[0],parts[1],parts[2],parts[3],parts[4],parts[5],parts[6])));
    }


    function toString(uint256 value) internal pure returns (string memory) {
    // Inspired by OraclizeAPI's implementation - MIT license
    // 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);
    }


}


contract ShapesArt is ERC721Enumerable, Ownable, ReentrancyGuard{
    uint256 public max_supply = 1000;
    uint256 public price = 0.025 ether;
    uint256 public minted;
    uint256 public maxMint = 10;
    
    bool public sales_paused = false;
    constructor() ERC721("ShapesArt", "SHPS_ART")  Ownable(){}
    

    function tokenURI(uint256 tokenId) override public view returns (string memory){
       require(tokenId > 0 && tokenId <= minted, "Invalid token ID");
       ShapeArtGenerator.ShapeArt memory shape;
       string memory svg;
       string[7] memory bgColorName=["Sweet Corn", "Cotton","Irish Green","Raven" ,"Grape Fruit" , "Rich Electric Blue", "Dodger Blue"];
       string[3] memory numshape = ["Four","Five","Six"];
       string[3] memory animation =["Normal","Splash Art","Slash Art"];
       (shape,svg) = ShapeArtGenerator.makeShapeFactory(tokenId);
        string memory attributes;
        attributes = string(abi.encodePacked('"attributes": [{"trait_type": "Background Color","value": "',
        bgColorName[shape.bgcolor-18],
        '"}, {"trait_type": "Number of Shapes","value": "',
        numshape[shape.numshapes-4],
        '"}, {"trait_type": "Effect Name","value": "',
        animation[shape.animation],
        '"}, {"trait_type": "Textured","value": "',
        (shape.textured > 0)?"True":"False",
        '"}], '));
       string memory output = Base64.encode(bytes(string(abi.encodePacked('{"name": "Shapes Art #', ShapeArtGenerator.toString(tokenId),'", "Description": "Abstract art painting on-chain for you to decorate your wall in the metaverse universe.",',
        attributes,
        '"image": "data:image/svg+xml;base64,', Base64.encode(bytes(svg)), '"}'))));
        output = string(abi.encodePacked('data:application/json;base64,', output));
        return output;
    }
    

    
    function mint(address add,uint256 numOftokens) public payable  {
        require(!sales_paused, "Sale is paused right now");
        require(totalSupply() < max_supply, "All tokens minted");
        require(totalSupply() + numOftokens <= max_supply, "Minting exceeds supply");
        require(numOftokens <= maxMint, "Cannot purchase so many in a transaction");
        require(numOftokens > 0, "Must mint at least one");
        require(price * numOftokens == msg.value, "ETH amount not correct");
        for(uint32 i=0;i < numOftokens; i++){
            uint256 tokenId = minted + 1;
            _safeMint(add, tokenId);
            minted += 1;
        }
    }

    function toggleAllSalesPaused() public onlyOwner {
        sales_paused = !sales_paused;
    }

    function withdrawAll() public payable onlyOwner {
        require(payable(_msgSender()).send(address(this).balance));
    }

    function setMaxSupply(uint256 new_max_supply) public onlyOwner{
         max_supply = new_max_supply;
    }

}

/// [MIT License]
/// @title Base64
/// @notice Provides a function for encoding some bytes in base64
/// @author Brecht Devos <[email protected]>
library Base64 {
    bytes internal constant TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    /// @notice Encodes some bytes to the base64 representation
    function encode(bytes memory data) internal pure returns (string memory) {
        uint256 len = data.length;
        if (len == 0) return "";

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

        // Add some extra buffer at the end
        bytes memory result = new bytes(encodedLen + 32);

        bytes memory table = TABLE;

        assembly {
            let tablePtr := add(table, 1)
            let resultPtr := add(result, 32)

            for {
                let i := 0
            } lt(i, len) {

            } {
                i := add(i, 3)
                let input := and(mload(add(data, i)), 0xffffff)

                let out := mload(add(tablePtr, and(shr(18, input), 0x3F)))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(input, 0x3F))), 0xFF))
                out := shl(224, out)

                mstore(resultPtr, out)

                resultPtr := add(resultPtr, 4)
            }

            switch mod(len, 3)
            case 1 {
                mstore(sub(resultPtr, 2), shl(240, 0x3d3d))
            }
            case 2 {
                mstore(sub(resultPtr, 1), shl(248, 0x3d))
            }

            mstore(result, encodedLen)
        }

        return string(result);
    }
}

Settings
{
  "optimizer": {
    "enabled": true,
    "runs": 200
  },
  "outputSelection": {
    "*": {
      "*": [
        "evm.bytecode",
        "evm.deployedBytecode",
        "devdoc",
        "userdoc",
        "metadata",
        "abi"
      ]
    }
  },
  "libraries": {}
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"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":[],"name":"maxMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"max_supply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"add","type":"address"},{"internalType":"uint256","name":"numOftokens","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"minted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"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":[],"name":"sales_paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"new_max_supply","type":"uint256"}],"name":"setMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleAllSalesPaused","outputs":[],"stateMutability":"nonpayable","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":"withdrawAll","outputs":[],"stateMutability":"payable","type":"function"}]

60806040526103e8600c556658d15e17628000600d55600a600f556010805460ff191690553480156200003157600080fd5b50604080518082018252600981526814da185c195cd05c9d60ba1b60208083019182528351808501909452600884526714d21414d7d0549560c21b908401528151919291620000839160009162000117565b5080516200009990600190602084019062000117565b505050620000b6620000b0620000c160201b60201c565b620000c5565b6001600b55620001fa565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b8280546200012590620001bd565b90600052602060002090601f01602090048101928262000149576000855562000194565b82601f106200016457805160ff191683800117855562000194565b8280016001018555821562000194579182015b828111156200019457825182559160200191906001019062000177565b50620001a2929150620001a6565b5090565b5b80821115620001a25760008155600101620001a7565b600181811c90821680620001d257607f821691505b60208210811415620001f457634e487b7160e01b600052602260045260246000fd5b50919050565b6140b8806200020a6000396000f3fe6080604052600436106101b75760003560e01c8063715018a6116100ec578063a035b1fe1161008a578063b88d4fde11610064578063b88d4fde14610476578063c87b56dd14610496578063e985e9c5146104b6578063f2fde38b146104ff57600080fd5b8063a035b1fe14610426578063a22cb4651461043c578063b1a9d7b51461045c57600080fd5b80638a333b50116100c65780638a333b50146103c85780638ad8f390146103de5780638da5cb5b146103f357806395d89b411461041157600080fd5b8063715018a6146103955780637501f741146103aa578063853828b6146103c057600080fd5b806340c10f19116101595780634f6ccce7116101335780634f6ccce7146103155780636352211e146103355780636f8b44b01461035557806370a082311461037557600080fd5b806340c10f19146102cc57806342842e0e146102df5780634f02c420146102ff57600080fd5b8063095ea7b311610195578063095ea7b31461024b57806318160ddd1461026d57806323b872dd1461028c5780632f745c59146102ac57600080fd5b806301ffc9a7146101bc57806306fdde03146101f1578063081812fc14610213575b600080fd5b3480156101c857600080fd5b506101dc6101d7366004612f84565b61051f565b60405190151581526020015b60405180910390f35b3480156101fd57600080fd5b5061020661054a565b6040516101e89190613a10565b34801561021f57600080fd5b5061023361022e366004612fbe565b6105dc565b6040516001600160a01b0390911681526020016101e8565b34801561025757600080fd5b5061026b610266366004612f5a565b610676565b005b34801561027957600080fd5b506008545b6040519081526020016101e8565b34801561029857600080fd5b5061026b6102a7366004612e06565b61078c565b3480156102b857600080fd5b5061027e6102c7366004612f5a565b6107bd565b61026b6102da366004612f5a565b610853565b3480156102eb57600080fd5b5061026b6102fa366004612e06565b610aa7565b34801561030b57600080fd5b5061027e600e5481565b34801561032157600080fd5b5061027e610330366004612fbe565b610ac2565b34801561034157600080fd5b50610233610350366004612fbe565b610b55565b34801561036157600080fd5b5061026b610370366004612fbe565b610bcc565b34801561038157600080fd5b5061027e610390366004612db8565b610bfb565b3480156103a157600080fd5b5061026b610c82565b3480156103b657600080fd5b5061027e600f5481565b61026b610cb8565b3480156103d457600080fd5b5061027e600c5481565b3480156103ea57600080fd5b5061026b610d06565b3480156103ff57600080fd5b50600a546001600160a01b0316610233565b34801561041d57600080fd5b50610206610d44565b34801561043257600080fd5b5061027e600d5481565b34801561044857600080fd5b5061026b610457366004612f1e565b610d53565b34801561046857600080fd5b506010546101dc9060ff1681565b34801561048257600080fd5b5061026b610491366004612e42565b610e18565b3480156104a257600080fd5b506102066104b1366004612fbe565b610e50565b3480156104c257600080fd5b506101dc6104d1366004612dd3565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561050b57600080fd5b5061026b61051a366004612db8565b6111f9565b60006001600160e01b0319821663780e9d6360e01b1480610544575061054482611294565b92915050565b60606000805461055990613bab565b80601f016020809104026020016040519081016040528092919081815260200182805461058590613bab565b80156105d25780601f106105a7576101008083540402835291602001916105d2565b820191906000526020600020905b8154815290600101906020018083116105b557829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b031661065a5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061068182610b55565b9050806001600160a01b0316836001600160a01b031614156106ef5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610651565b336001600160a01b038216148061070b575061070b81336104d1565b61077d5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610651565b61078783836112e4565b505050565b6107963382611352565b6107b25760405162461bcd60e51b815260040161065190613aaa565b610787838383611449565b60006107c883610bfb565b821061082a5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610651565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b60105460ff16156108a65760405162461bcd60e51b815260206004820152601860248201527f53616c6520697320706175736564207269676874206e6f7700000000000000006044820152606401610651565b600c54600854106108ed5760405162461bcd60e51b8152602060048201526011602482015270105b1b081d1bdad95b9cc81b5a5b9d1959607a1b6044820152606401610651565b600c54816108fa60085490565b6109049190613afb565b111561094b5760405162461bcd60e51b81526020600482015260166024820152754d696e74696e67206578636565647320737570706c7960501b6044820152606401610651565b600f548111156109ae5760405162461bcd60e51b815260206004820152602860248201527f43616e6e6f7420707572636861736520736f206d616e7920696e2061207472616044820152673739b0b1ba34b7b760c11b6064820152608401610651565b600081116109f75760405162461bcd60e51b81526020600482015260166024820152754d757374206d696e74206174206c65617374206f6e6560501b6044820152606401610651565b3481600d54610a069190613b49565b14610a4c5760405162461bcd60e51b815260206004820152601660248201527511551208185b5bdd5b9d081b9bdd0818dbdc9c9958dd60521b6044820152606401610651565b60005b818163ffffffff161015610787576000600e546001610a6e9190613afb565b9050610a7a84826115f4565b6001600e6000828254610a8d9190613afb565b90915550829150610a9f905081613c01565b915050610a4f565b61078783838360405180602001604052806000815250610e18565b6000610acd60085490565b8210610b305760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610651565b60088281548110610b4357610b43613c7b565b90600052602060002001549050919050565b6000818152600260205260408120546001600160a01b0316806105445760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610651565b600a546001600160a01b03163314610bf65760405162461bcd60e51b815260040161065190613a75565b600c55565b60006001600160a01b038216610c665760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610651565b506001600160a01b031660009081526003602052604090205490565b600a546001600160a01b03163314610cac5760405162461bcd60e51b815260040161065190613a75565b610cb66000611612565b565b600a546001600160a01b03163314610ce25760405162461bcd60e51b815260040161065190613a75565b60405133904780156108fc02916000818181858888f19350505050610cb657600080fd5b600a546001600160a01b03163314610d305760405162461bcd60e51b815260040161065190613a75565b6010805460ff19811660ff90911615179055565b60606001805461055990613bab565b6001600160a01b038216331415610dac5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610651565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b610e223383611352565b610e3e5760405162461bcd60e51b815260040161065190613aaa565b610e4a84848484611664565b50505050565b6060600082118015610e645750600e548211155b610ea35760405162461bcd60e51b815260206004820152601060248201526f125b9d985b1a59081d1bdad95b88125160821b6044820152606401610651565b610ed56040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b6040805161012081018252600a60e082018181526929bbb2b2ba1021b7b93760b11b61010084015282528251808401845260068082526521b7ba3a37b760d11b6020838101919091528085019290925284518086018652600b8082526a24b934b9b41023b932b2b760a91b82850152858701919091528551808701875260058152642930bb32b760d91b81850152606086810191909152865180880188528281526a11dc985c1948119c9d5a5d60aa1b818601526080808801919091528751808901895260128152715269636820456c65637472696320426c756560701b8187015260a0808901919091528851808a018a529384526a446f6467657220426c756560a81b8487015260c0880193909352875180840189526004818401818152632337bab960e11b8385015282528951808b018b52908152634669766560e01b81880152818701528851808a018a5260038152620a6d2f60eb1b81880152818a01528851938401895283830194855265139bdc9b585b60d21b91840191909152928252865180880188529485526914dc1b185cda08105c9d60b21b858501528184019490945285518087018752600981526814db185cda08105c9d60ba1b938101939093529485019190915290926110ab87611697565b8151919650945060609084906110c390601290613b68565b600781106110d3576110d3613c7b565b602002015183600488602001516110ea9190613b68565b600381106110fa576110fa613c7b565b60200201518388604001516003811061111557611115613c7b565b60200201516000896080015111611149576040518060400160405280600581526020016446616c736560d81b815250611167565b604051806040016040528060048152602001635472756560e01b8152505b60405160200161117a94939291906133e4565b604051602081830303815290604052905060006111c96111998a61231c565b836111a38961241a565b6040516020016111b593929190613577565b60405160208183030381529060405261241a565b9050806040516020016111dc9190613704565b60408051601f198184030181529190529998505050505050505050565b600a546001600160a01b031633146112235760405162461bcd60e51b815260040161065190613a75565b6001600160a01b0381166112885760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610651565b61129181611612565b50565b60006001600160e01b031982166380ac58cd60e01b14806112c557506001600160e01b03198216635b5e139f60e01b145b8061054457506301ffc9a760e01b6001600160e01b0319831614610544565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061131982610b55565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152600260205260408120546001600160a01b03166113cb5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610651565b60006113d683610b55565b9050806001600160a01b0316846001600160a01b031614806114115750836001600160a01b0316611406846105dc565b6001600160a01b0316145b8061144157506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b031661145c82610b55565b6001600160a01b0316146114c45760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610651565b6001600160a01b0382166115265760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610651565b611531838383612580565b61153c6000826112e4565b6001600160a01b0383166000908152600360205260408120805460019290611565908490613b68565b90915550506001600160a01b0382166000908152600360205260408120805460019290611593908490613afb565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b61160e828260405180602001604052806000815250612638565b5050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61166f848484611449565b61167b8484848461266b565b610e4a5760405162461bcd60e51b815260040161065190613a23565b6116c96040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b604080516103608101825260076103208201818152661198182298a22360c91b610340840152825282518084018452818152662332364633334160c81b60208281019190915280840191909152835180850185528281526611981b2119212160c91b818301528385015283518085018552828152662342454239343760c81b81830152606084810191909152845180860186528381526611992099989b1b60c91b81840152608085015284518086018652838152662346323634313960c81b8184015260a0850152845180860186528381526608d08dcd90d19160ca1b8184015260c085015284518086018652838152662330424632383760c81b8184015260e08501528451808601865283815266119a19a2a1a29960c91b81840152610100850152845180860186528381526608d19090d0cc0d60ca1b818401526101208086019190915285518087018752848152662345443239393560c81b818501526101408087019190915286518088018852858152660468a62648466760cb1b81860152610160870152865180880188528581526608d18dcc508c9160ca1b8186015261018080880191909152875180890189528681526611a3209a9a1a9b60c91b818701526101a088015287518089018952868152662345343243364160c81b818701526101c088015287518089018952868152660234445453530360cc1b818701526101e088015287518089018952868152660234646454430360cc1b81870152610200880152875180890189528681526604684828c6488760cb1b81870152610220880152875180890189528681526611a320a3189c1960c91b81870152610240880152875180890189528681526611a3232323232360c91b818701526102608801528751808901895286815266119822a09c18a360c91b8187015261028088015287518089018952868152660233030303030360cc1b818701526102a0880152875180890189528681526608d14d4cd14ccd60ca1b818701526102c088015287518089018952868152662330383939443760c81b818701526102e088015287518089018952958652662331433646464360c81b9486019490945261030086019490945285519283019095526030948201858152909460009383929190613ce7908401398152602001604051806060016040528060298152602001613cbe602991398152602001604051806060016040528060258152602001613d636025913981526020016040518060600160405280603b8152602001613f8e603b913981526020016040518060600160405280603a8152602001613fc9603a91398152602001604051806060016040528060388152602001613d88603891398152602001604051806080016040528060528152602001613dc06052913981526020016040518060a001604052806080815260200161400360809139815260200160405180610100016040528060d28152602001613ebc60d291399052604080516101208101825260648152605a60208083019190915260a4828401526098606080840191909152605e60808085019190915260a0808501819052609060c08087019190915260e08601526092610100860152855190810186526000808252938101849052948501839052908401829052830152919250611ba987604051806040016040528060088152602001672123afa1a7a627a960c11b81525060126018612778565b8152611bb4876127fa565b6020820152611bc287612865565b6040820152611bd0876128cf565b6060820152611bde87612912565b816080018181525050611c276040518060e00160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b600060a082015260c86060820152611c4d88611c4461056f61231c565b60006009612778565b60c0820152611c5a612d75565b60005b8360200151811015611ed757611c738a82612955565b60808401526060840151611ca857611ca28a611c99611c9484610708613b49565b61231c565b60006011612778565b60c08401525b836020015160051415611cbd57603560a08401525b836020015160061415611cd257602d60a08401525b836020015160041415611ce757603e60a08401525b8015611d07578260a0015183602001818151611d039190613afb565b9052505b826080015160021415611d1c5760a460608401525b600285846080015160098110611d3457611d34613c7b565b6020020151611d439190613b27565b60ff166040840152611d728a611d69611d5d846001613afb565b611c9490610457613b49565b6000603f612778565b835260608201516080840151879060098110611d9057611d90613c7b565b6020020151888560c0015160198110611dab57611dab613c7b565b6020020151611dda611c948e611dd1611dc5886001613afb565b611c94906106f8613b49565b6044604e612778565b8651611deb90611c94906044613afb565b604051602001611dff959493929190613124565b60408051808303601f19018152919052606083018190526020840151611e2a90611c94906064613afb565b611e54611c948d611e4b611e3f876001613afb565b611c9490610682613b49565b600060b4612778565b604051602001611e66939291906131ec565b60408051808303601f190181529190526060808401829052840151611e9190611c9490600290613b13565b611e9e856040015161231c565b604051602001611eb093929190613254565b60408051808303601f19018152919052606083015280611ecf81613be6565b915050611c5d565b5060808301511561206c57604051602001612056907f3c66696c7465722069643d22442220783d222d3530252220793d222d3530252281527f2077696474683d223230302522206865696768743d2232303025223e0000000060208201527f3c666554757262756c656e636520747970653d226672616374616c4e6f697365603c8201527f2220626173654672657175656e63793d22302e3922206e756d6f637461766573605c8201526e1e9118911039b2b2b21e911811179f60891b607c8201527f3c6665436f6d706f73697465206f70657261746f723d22696e2220696e323d22608b8201527f536f75726365477261706869632220726573756c743d226d6f6e6f4e6f69736560ab8201526211179f60e91b60cb8201527f203c6665426c656e6420696e3d22536f75726365477261706869632220696e3260ce8201527f3d226d6f6e6f4e6f69736522206d6f64653d226d756c7469706c7922202f3e3c60ee8201526717b334b63a32b91f60c11b61010e8201526101160190565b60408051808303601f1901815291905260808201525b6040830151156120fd57604080516020810182526000815290840151600114156120ac576040518060800160405280604c8152602001613d17604c913990505b8360400151600214156120d5576040518060a00160405280606a8152602001613e12606a913990505b806040516020016120e69190613791565b60408051808303601f1901815291905260a0830152505b825186906019811061211157612111613c7b565b602002015160405160200161212691906132ea565b60408051808303601f19018152919052815260808301516121565760405180602001604052806000815250612181565b60405180604001604052806011815260200170222066696c7465723d2275726c2823442960781b8152505b60405160200161219191906132c3565b60408051601f1981840301815291905281600160200201526040830151158015906121c0575060008360800151115b156122075760408051808201909152601c81527f3c672066696c7465723d2275726c282343292075726c28234429223e0000000060208201528160025b602002015261229f565b604083015115612244576040805180820190915260148152731e33903334b63a32b91e913ab9361411a194911f60611b60208201528160026121fd565b608083015115612281576040805180820190915260148152731e33903334b63a32b91e913ab9361411a214911f60611b60208201528160026121fd565b60408051808201825260038152621e339f60e91b6020820152908201525b604080518082018252600a8152691e17b39f1e17b9bb339f60b11b60208083019190915260c08401829052835184820151858501516060870151608088015160a089015197518b986122fe989697959694959394929390929101613092565b60405160208183030381529060405297509750505050505050915091565b6060816123405750506040805180820190915260018152600360fc1b602082015290565b8160005b811561236a578061235481613be6565b91506123639050600a83613b13565b9150612344565b60008167ffffffffffffffff81111561238557612385613c91565b6040519080825280601f01601f1916602001820160405280156123af576020820181803683370190505b5090505b8415611441576123c4600183613b68565b91506123d1600a86613c25565b6123dc906030613afb565b60f81b8183815181106123f1576123f1613c7b565b60200101906001600160f81b031916908160001a905350612413600a86613b13565b94506123b3565b80516060908061243a575050604080516020810190915260008152919050565b60006003612449836002613afb565b6124539190613b13565b61245e906004613b49565b9050600061246d826020613afb565b67ffffffffffffffff81111561248557612485613c91565b6040519080825280601f01601f1916602001820160405280156124af576020820181803683370190505b5090506000604051806060016040528060408152602001613e7c604091399050600181016020830160005b8681101561253b576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b8352600490920191016124da565b506003860660018114612555576002811461256657612572565b613d3d60f01b600119830152612572565b603d60f81b6000198301525b505050918152949350505050565b6001600160a01b0383166125db576125d681600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b6125fe565b816001600160a01b0316836001600160a01b0316146125fe576125fe8382612a66565b6001600160a01b0382166126155761078781612b03565b826001600160a01b0316826001600160a01b031614610787576107878282612bb2565b6126428383612bf6565b61264f600084848461266b565b6107875760405162461bcd60e51b815260040161065190613a23565b60006001600160a01b0384163b1561276d57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906126af9033908990889088906004016139d3565b602060405180830381600087803b1580156126c957600080fd5b505af19250505080156126f9575060408051601f3d908101601f191682019092526126f691810190612fa1565b60015b612753573d808015612727576040519150601f19603f3d011682016040523d82523d6000602084013e61272c565b606091505b50805161274b5760405162461bcd60e51b815260040161065190613a23565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611441565b506001949350505050565b6000806127c1856127888861231c565b6127918761231c565b61279a8761231c565b6040516020016127ad949392919061303b565b604051602081830303815290604052612d44565b90506000846127d08186613b68565b6127db906001613afb565b6127e59084613c25565b6127ef9190613afb565b979650505050505050565b6000806128196128098461231c565b6040516020016127ad91906136ae565b905061282660c982613c25565b90506005606e8211801561283b575060a08211155b15612844575060065b60a082118015612855575060c88211155b1561285e575060045b9392505050565b6000806128846128748461231c565b6040516020016127ad91906136d3565b905061289160c982613c25565b9050600060ba821180156128a6575060c38211155b156128af575060015b608c821180156128c0575060968211155b1561285e575060029392505050565b6000806128ee6128de8461231c565b6040516020016127ad91906133b2565b90506128fb60c982613c25565b9050600060a082111561285e575060019392505050565b6000806129316129218461231c565b6040516020016127ad9190613547565b905061293e60c982613c25565b9050600060aa82111561285e575060019392505050565b60008061297e6129648561231c565b61296d8561231c565b6040516020016127ad929190613749565b905061298b60c982613c25565b905060006016821180156129a05750602c8211155b156129a9575060015b602c821180156129ba575060428211155b156129c3575060025b6042821180156129d4575060588211155b156129dd575060035b6058821180156129ee5750606e8211155b156129f7575060045b606e82118015612a08575060848211155b15612a11575060055b608482118015612a225750609a8211155b15612a2b575060065b609a82118015612a3c575060b08211155b15612a45575060075b60b082118015612a56575060c68211155b1561144157506008949350505050565b60006001612a7384610bfb565b612a7d9190613b68565b600083815260076020526040902054909150808214612ad0576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090612b1590600190613b68565b60008381526009602052604081205460088054939450909284908110612b3d57612b3d613c7b565b906000526020600020015490508060088381548110612b5e57612b5e613c7b565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480612b9657612b96613c65565b6001900381819060005260206000200160009055905550505050565b6000612bbd83610bfb565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160a01b038216612c4c5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610651565b6000818152600260205260409020546001600160a01b031615612cb15760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610651565b612cbd60008383612580565b6001600160a01b0382166000908152600360205260408120805460019290612ce6908490613afb565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600081604051602001612d57919061301f565b60408051601f19818403018152919052805160209091012092915050565b6040518060e001604052806007905b6060815260200190600190039081612d845790505090565b80356001600160a01b0381168114612db357600080fd5b919050565b600060208284031215612dca57600080fd5b61285e82612d9c565b60008060408385031215612de657600080fd5b612def83612d9c565b9150612dfd60208401612d9c565b90509250929050565b600080600060608486031215612e1b57600080fd5b612e2484612d9c565b9250612e3260208501612d9c565b9150604084013590509250925092565b60008060008060808587031215612e5857600080fd5b612e6185612d9c565b9350612e6f60208601612d9c565b925060408501359150606085013567ffffffffffffffff80821115612e9357600080fd5b818701915087601f830112612ea757600080fd5b813581811115612eb957612eb9613c91565b604051601f8201601f19908116603f01168101908382118183101715612ee157612ee1613c91565b816040528281528a6020848701011115612efa57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060408385031215612f3157600080fd5b612f3a83612d9c565b915060208301358015158114612f4f57600080fd5b809150509250929050565b60008060408385031215612f6d57600080fd5b612f7683612d9c565b946020939093013593505050565b600060208284031215612f9657600080fd5b813561285e81613ca7565b600060208284031215612fb357600080fd5b815161285e81613ca7565b600060208284031215612fd057600080fd5b5035919050565b60008151808452612fef816020860160208601613b7f565b601f01601f19169290920160200192915050565b60008151613015818560208601613b7f565b9290920192915050565b60008251613031818460208701613b7f565b9190910192915050565b6000855161304d818460208a01613b7f565b855190830190613061818360208a01613b7f565b8551910190613074818360208901613b7f565b8451910190613087818360208801613b7f565b019695505050505050565b6000885160206130a58285838e01613b7f565b8951918401916130b88184848e01613b7f565b89519201916130ca8184848d01613b7f565b88519201916130dc8184848c01613b7f565b87519201916130ee8184848b01613b7f565b86519201916131008184848a01613b7f565b85519201916131128184848901613b7f565b919091019a9950505050505050505050565b60008651613136818460208b01613b7f565b621e339f60e91b9083019081528651613156816003840160208b01613b7f565b865191019061316c816003840160208a01613b7f565b7111103334b63616b7b830b1b4ba3c9e91181760711b60039290910191820152845161319f816015840160208901613b7f565b7f2220207472616e73666f726d3d227472616e736c6174652800000000000000006015929091019182015283516131dd81602d840160208801613b7f565b01602d01979650505050505050565b600084516131fe818460208901613b7f565b600160fd1b908301908152845161321c816001840160208901613b7f565b690524040e4dee8c2e8ca560b31b60019290910191820152835161324781600b840160208801613b7f565b01600b0195945050505050565b60008451613266818460208901613b7f565b8083019050600160fd1b8082528551613286816001850160208a01613b7f565b600192019182015283516132a1816002840160208801613b7f565b671491179f1e17b39f60c11b60029290910191820152600a0195945050505050565b600082516132d5818460208701613b7f565b6211179f60e91b920191825250600301919050565b7f3c7376672077696474683d2234303022206865696768743d223630302220766981527f6577426f783d223020302034303020363030222066696c6c3d226e6f6e65222060208201527f786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f737660408201527f67223e3c726563742077696474683d2234303022206865696768743d2236303060608201526711103334b6361e9160c11b6080820152600082516133a5816088850160208701613b7f565b9190910160880192915050565b694d4f4e4f4348524f4d4560b01b8152600082516133d781600a850160208701613b7f565b91909101600a0192915050565b7f2261747472696275746573223a205b7b2274726169745f74797065223a20224281527f61636b67726f756e6420436f6c6f72222c2276616c7565223a2022000000000060208201526000855161344281603b850160208a01613b7f565b7f227d2c207b2274726169745f74797065223a20224e756d626572206f66205368603b918401918201526f30b832b99116113b30b63ab2911d101160811b605b820152855161349881606b840160208a01613b7f565b7f227d2c207b2274726169745f74797065223a2022456666656374204e616d6522606b92909101918201526a16113b30b63ab2911d101160a91b608b82015284516134ea816096840160208901613b7f565b7f227d2c207b2274726169745f74797065223a20225465787475726564222c2276609692909101918201526730b63ab2911d101160c11b60b68201526127ef61353660be830186613003565b640113eae96160dd1b815260050190565b67151156151554915160c21b81526000825161356a816008850160208701613b7f565b9190910160080192915050565b757b226e616d65223a202253686170657320417274202360501b815283516000906135a9816016850160208901613b7f565b7f222c20224465736372697074696f6e223a2022416273747261637420617274206016918401918201527f7061696e74696e67206f6e2d636861696e20666f7220796f7520746f2064656360368201527f6f7261746520796f75722077616c6c20696e20746865206d657461766572736560568201526b081d5b9a5d995c9cd94b888b60a21b60768201528451613647816082840160208901613b7f565b7f22696d616765223a2022646174613a696d6167652f7376672b786d6c3b6261736082929091019182015263194d8d0b60e21b60a282015283516136928160a6840160208801613b7f565b61227d60f01b60a6929091019182015260a80195945050505050565b694e554d5f53484150455360b01b8152600082516133d781600a850160208701613b7f565b6820a724a6a0aa24a7a760b91b8152600082516136f7816009850160208701613b7f565b9190910160090192915050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161373c81601d850160208701613b7f565b91909101601d0192915050565b6953686170655f5479706560b01b81526000835161376e81600a850160208801613b7f565b83519083019061378581600a840160208801613b7f565b01600a01949350505050565b7f3c66696c74657220786d6c6e733d22687474703a2f2f7777772e77332e6f726781527f2f323030302f737667222069643d22432220783d222d3530252220793d222d3560208201527f3025222077696474683d223230302522206865696768743d2232303025223e0060408201527f3c666554757262756c656e636520747970653d2274757262756c656e63652220605f8201527f626173654672657175656e63793d22302e303222206e756d4f6374617665733d607f8201527f22332220726573756c743d226e6f6973652220736565643d2230223e00000000609f8201527f3c616e696d617465206174747269627574654e616d653d22626173654672657160bb8201527003ab2b731bc9110323ab91e91189839911607d1b60db820152600082516138c78160ec850160208701613b7f565b7f2066696c6c3d22667265657a652220726570656174436f756e743d22696e646560ec918401918201527f66696e697465222f3e3c2f666554757262756c656e63653e000000000000000061010c8201526114416139be61012483017f3c6665446973706c6163656d656e744d617020696e323d226e6f69736522206981527f6e3d22536f75726365477261706869632220784368616e6e656c53656c65637460208201527f6f723d22522220794368616e6e656c53656c6563746f723d224722207363616c60408201527f653d223830223e3c2f6665446973706c6163656d656e744d61703e00000000006060820152607b0190565b681e17b334b63a32b91f60b91b815260090190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090613a0690830184612fd7565b9695505050505050565b60208152600061285e6020830184612fd7565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b60008219821115613b0e57613b0e613c39565b500190565b600082613b2257613b22613c4f565b500490565b600060ff831680613b3a57613b3a613c4f565b8060ff84160491505092915050565b6000816000190483118215151615613b6357613b63613c39565b500290565b600082821015613b7a57613b7a613c39565b500390565b60005b83811015613b9a578181015183820152602001613b82565b83811115610e4a5750506000910152565b600181811c90821680613bbf57607f821691505b60208210811415613be057634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415613bfa57613bfa613c39565b5060010190565b600063ffffffff80831681811415613c1b57613c1b613c39565b6001019392505050565b600082613c3457613c34613c4f565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b03198116811461129157600080fdfe3c726563742077696474683d2232303022206865696768743d2238392e32383537222066696c6c3d223c7061746820643d224d3134322e34323820304c3230302031303048304c3134322e34323820305a222066696c6c3d2276616c7565733d22303b303b302e30313b302e30323b302e30333b302e30343b302e30353b302e30353b302e30353b302e30353b302e30343b302e30333b302e30323b302e30313b303b30223c636972636c652063783d223832222063793d2238322220723d223832222066696c6c3d223c7061746820643d224d3230302032312e344c3020304c3130302e343636203136302e3731344c3230302032312e345a222066696c6c3d223c7061746820643d224d34332e373538352033312e313230354c32303020304c3134322e343637203131312e3738384c30203134342e3634334c34332e373538352033312e313230355a222066696c6c3d2276616c7565733d22303b303b302e303120302e343b302e303220302e343b302e303320302e343b302e303420302e343b302e303420302e343b302e303420302e343b302e303420302e343b302e303320302e343b302e303220302e343b302e303120302e343b303b30224142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f3c7061746820643d224d3135392e34383920372e3833323034433135392e3438392035352e36303236203132332e3738362039342e333238322037392e373434372039342e333238324333352e373032392039342e3332383220302035352e36303236203020372e38333230344330202d33392e39333835203134312e343131203134362e343239203138352e343533203134362e343239433232392e343935203134362e343239203135392e343839202d33392e39333835203135392e34383920372e38333230345a222066696c6c3d223c656c6c697073652063783d22313030222063793d2237352e39313632222072783d22313030222072793d2237352e39313632222066696c6c3d223c7061746820643d224d3020304c32303020304c3132372e3638342038322e343835394c302039332e373835334c3020305a222066696c6c3d223c7061746820643d224d31303020304c3132372e3030392037302e333834314c3230302039362e343238364c3132372e303039203132322e3437334c313030203139322e3835374c37322e39393039203132322e3437334c302039362e343238364c37322e393930392037302e333834314c31303020305a222066696c6c3d22a26469706673582212200677bbc1d3e3aeaf8a699d8ed5e3509c3cb23c4e6fd318a8b6001129c861717c64736f6c63430008070033

Deployed Bytecode

0x6080604052600436106101b75760003560e01c8063715018a6116100ec578063a035b1fe1161008a578063b88d4fde11610064578063b88d4fde14610476578063c87b56dd14610496578063e985e9c5146104b6578063f2fde38b146104ff57600080fd5b8063a035b1fe14610426578063a22cb4651461043c578063b1a9d7b51461045c57600080fd5b80638a333b50116100c65780638a333b50146103c85780638ad8f390146103de5780638da5cb5b146103f357806395d89b411461041157600080fd5b8063715018a6146103955780637501f741146103aa578063853828b6146103c057600080fd5b806340c10f19116101595780634f6ccce7116101335780634f6ccce7146103155780636352211e146103355780636f8b44b01461035557806370a082311461037557600080fd5b806340c10f19146102cc57806342842e0e146102df5780634f02c420146102ff57600080fd5b8063095ea7b311610195578063095ea7b31461024b57806318160ddd1461026d57806323b872dd1461028c5780632f745c59146102ac57600080fd5b806301ffc9a7146101bc57806306fdde03146101f1578063081812fc14610213575b600080fd5b3480156101c857600080fd5b506101dc6101d7366004612f84565b61051f565b60405190151581526020015b60405180910390f35b3480156101fd57600080fd5b5061020661054a565b6040516101e89190613a10565b34801561021f57600080fd5b5061023361022e366004612fbe565b6105dc565b6040516001600160a01b0390911681526020016101e8565b34801561025757600080fd5b5061026b610266366004612f5a565b610676565b005b34801561027957600080fd5b506008545b6040519081526020016101e8565b34801561029857600080fd5b5061026b6102a7366004612e06565b61078c565b3480156102b857600080fd5b5061027e6102c7366004612f5a565b6107bd565b61026b6102da366004612f5a565b610853565b3480156102eb57600080fd5b5061026b6102fa366004612e06565b610aa7565b34801561030b57600080fd5b5061027e600e5481565b34801561032157600080fd5b5061027e610330366004612fbe565b610ac2565b34801561034157600080fd5b50610233610350366004612fbe565b610b55565b34801561036157600080fd5b5061026b610370366004612fbe565b610bcc565b34801561038157600080fd5b5061027e610390366004612db8565b610bfb565b3480156103a157600080fd5b5061026b610c82565b3480156103b657600080fd5b5061027e600f5481565b61026b610cb8565b3480156103d457600080fd5b5061027e600c5481565b3480156103ea57600080fd5b5061026b610d06565b3480156103ff57600080fd5b50600a546001600160a01b0316610233565b34801561041d57600080fd5b50610206610d44565b34801561043257600080fd5b5061027e600d5481565b34801561044857600080fd5b5061026b610457366004612f1e565b610d53565b34801561046857600080fd5b506010546101dc9060ff1681565b34801561048257600080fd5b5061026b610491366004612e42565b610e18565b3480156104a257600080fd5b506102066104b1366004612fbe565b610e50565b3480156104c257600080fd5b506101dc6104d1366004612dd3565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561050b57600080fd5b5061026b61051a366004612db8565b6111f9565b60006001600160e01b0319821663780e9d6360e01b1480610544575061054482611294565b92915050565b60606000805461055990613bab565b80601f016020809104026020016040519081016040528092919081815260200182805461058590613bab565b80156105d25780601f106105a7576101008083540402835291602001916105d2565b820191906000526020600020905b8154815290600101906020018083116105b557829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b031661065a5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061068182610b55565b9050806001600160a01b0316836001600160a01b031614156106ef5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610651565b336001600160a01b038216148061070b575061070b81336104d1565b61077d5760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610651565b61078783836112e4565b505050565b6107963382611352565b6107b25760405162461bcd60e51b815260040161065190613aaa565b610787838383611449565b60006107c883610bfb565b821061082a5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610651565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b60105460ff16156108a65760405162461bcd60e51b815260206004820152601860248201527f53616c6520697320706175736564207269676874206e6f7700000000000000006044820152606401610651565b600c54600854106108ed5760405162461bcd60e51b8152602060048201526011602482015270105b1b081d1bdad95b9cc81b5a5b9d1959607a1b6044820152606401610651565b600c54816108fa60085490565b6109049190613afb565b111561094b5760405162461bcd60e51b81526020600482015260166024820152754d696e74696e67206578636565647320737570706c7960501b6044820152606401610651565b600f548111156109ae5760405162461bcd60e51b815260206004820152602860248201527f43616e6e6f7420707572636861736520736f206d616e7920696e2061207472616044820152673739b0b1ba34b7b760c11b6064820152608401610651565b600081116109f75760405162461bcd60e51b81526020600482015260166024820152754d757374206d696e74206174206c65617374206f6e6560501b6044820152606401610651565b3481600d54610a069190613b49565b14610a4c5760405162461bcd60e51b815260206004820152601660248201527511551208185b5bdd5b9d081b9bdd0818dbdc9c9958dd60521b6044820152606401610651565b60005b818163ffffffff161015610787576000600e546001610a6e9190613afb565b9050610a7a84826115f4565b6001600e6000828254610a8d9190613afb565b90915550829150610a9f905081613c01565b915050610a4f565b61078783838360405180602001604052806000815250610e18565b6000610acd60085490565b8210610b305760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610651565b60088281548110610b4357610b43613c7b565b90600052602060002001549050919050565b6000818152600260205260408120546001600160a01b0316806105445760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610651565b600a546001600160a01b03163314610bf65760405162461bcd60e51b815260040161065190613a75565b600c55565b60006001600160a01b038216610c665760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610651565b506001600160a01b031660009081526003602052604090205490565b600a546001600160a01b03163314610cac5760405162461bcd60e51b815260040161065190613a75565b610cb66000611612565b565b600a546001600160a01b03163314610ce25760405162461bcd60e51b815260040161065190613a75565b60405133904780156108fc02916000818181858888f19350505050610cb657600080fd5b600a546001600160a01b03163314610d305760405162461bcd60e51b815260040161065190613a75565b6010805460ff19811660ff90911615179055565b60606001805461055990613bab565b6001600160a01b038216331415610dac5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610651565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b610e223383611352565b610e3e5760405162461bcd60e51b815260040161065190613aaa565b610e4a84848484611664565b50505050565b6060600082118015610e645750600e548211155b610ea35760405162461bcd60e51b815260206004820152601060248201526f125b9d985b1a59081d1bdad95b88125160821b6044820152606401610651565b610ed56040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b6040805161012081018252600a60e082018181526929bbb2b2ba1021b7b93760b11b61010084015282528251808401845260068082526521b7ba3a37b760d11b6020838101919091528085019290925284518086018652600b8082526a24b934b9b41023b932b2b760a91b82850152858701919091528551808701875260058152642930bb32b760d91b81850152606086810191909152865180880188528281526a11dc985c1948119c9d5a5d60aa1b818601526080808801919091528751808901895260128152715269636820456c65637472696320426c756560701b8187015260a0808901919091528851808a018a529384526a446f6467657220426c756560a81b8487015260c0880193909352875180840189526004818401818152632337bab960e11b8385015282528951808b018b52908152634669766560e01b81880152818701528851808a018a5260038152620a6d2f60eb1b81880152818a01528851938401895283830194855265139bdc9b585b60d21b91840191909152928252865180880188529485526914dc1b185cda08105c9d60b21b858501528184019490945285518087018752600981526814db185cda08105c9d60ba1b938101939093529485019190915290926110ab87611697565b8151919650945060609084906110c390601290613b68565b600781106110d3576110d3613c7b565b602002015183600488602001516110ea9190613b68565b600381106110fa576110fa613c7b565b60200201518388604001516003811061111557611115613c7b565b60200201516000896080015111611149576040518060400160405280600581526020016446616c736560d81b815250611167565b604051806040016040528060048152602001635472756560e01b8152505b60405160200161117a94939291906133e4565b604051602081830303815290604052905060006111c96111998a61231c565b836111a38961241a565b6040516020016111b593929190613577565b60405160208183030381529060405261241a565b9050806040516020016111dc9190613704565b60408051601f198184030181529190529998505050505050505050565b600a546001600160a01b031633146112235760405162461bcd60e51b815260040161065190613a75565b6001600160a01b0381166112885760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610651565b61129181611612565b50565b60006001600160e01b031982166380ac58cd60e01b14806112c557506001600160e01b03198216635b5e139f60e01b145b8061054457506301ffc9a760e01b6001600160e01b0319831614610544565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061131982610b55565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000818152600260205260408120546001600160a01b03166113cb5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610651565b60006113d683610b55565b9050806001600160a01b0316846001600160a01b031614806114115750836001600160a01b0316611406846105dc565b6001600160a01b0316145b8061144157506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b031661145c82610b55565b6001600160a01b0316146114c45760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610651565b6001600160a01b0382166115265760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610651565b611531838383612580565b61153c6000826112e4565b6001600160a01b0383166000908152600360205260408120805460019290611565908490613b68565b90915550506001600160a01b0382166000908152600360205260408120805460019290611593908490613afb565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b61160e828260405180602001604052806000815250612638565b5050565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b61166f848484611449565b61167b8484848461266b565b610e4a5760405162461bcd60e51b815260040161065190613a23565b6116c96040518060a0016040528060008152602001600081526020016000815260200160008152602001600081525090565b604080516103608101825260076103208201818152661198182298a22360c91b610340840152825282518084018452818152662332364633334160c81b60208281019190915280840191909152835180850185528281526611981b2119212160c91b818301528385015283518085018552828152662342454239343760c81b81830152606084810191909152845180860186528381526611992099989b1b60c91b81840152608085015284518086018652838152662346323634313960c81b8184015260a0850152845180860186528381526608d08dcd90d19160ca1b8184015260c085015284518086018652838152662330424632383760c81b8184015260e08501528451808601865283815266119a19a2a1a29960c91b81840152610100850152845180860186528381526608d19090d0cc0d60ca1b818401526101208086019190915285518087018752848152662345443239393560c81b818501526101408087019190915286518088018852858152660468a62648466760cb1b81860152610160870152865180880188528581526608d18dcc508c9160ca1b8186015261018080880191909152875180890189528681526611a3209a9a1a9b60c91b818701526101a088015287518089018952868152662345343243364160c81b818701526101c088015287518089018952868152660234445453530360cc1b818701526101e088015287518089018952868152660234646454430360cc1b81870152610200880152875180890189528681526604684828c6488760cb1b81870152610220880152875180890189528681526611a320a3189c1960c91b81870152610240880152875180890189528681526611a3232323232360c91b818701526102608801528751808901895286815266119822a09c18a360c91b8187015261028088015287518089018952868152660233030303030360cc1b818701526102a0880152875180890189528681526608d14d4cd14ccd60ca1b818701526102c088015287518089018952868152662330383939443760c81b818701526102e088015287518089018952958652662331433646464360c81b9486019490945261030086019490945285519283019095526030948201858152909460009383929190613ce7908401398152602001604051806060016040528060298152602001613cbe602991398152602001604051806060016040528060258152602001613d636025913981526020016040518060600160405280603b8152602001613f8e603b913981526020016040518060600160405280603a8152602001613fc9603a91398152602001604051806060016040528060388152602001613d88603891398152602001604051806080016040528060528152602001613dc06052913981526020016040518060a001604052806080815260200161400360809139815260200160405180610100016040528060d28152602001613ebc60d291399052604080516101208101825260648152605a60208083019190915260a4828401526098606080840191909152605e60808085019190915260a0808501819052609060c08087019190915260e08601526092610100860152855190810186526000808252938101849052948501839052908401829052830152919250611ba987604051806040016040528060088152602001672123afa1a7a627a960c11b81525060126018612778565b8152611bb4876127fa565b6020820152611bc287612865565b6040820152611bd0876128cf565b6060820152611bde87612912565b816080018181525050611c276040518060e00160405280600081526020016000815260200160008152602001600081526020016000815260200160008152602001600081525090565b600060a082015260c86060820152611c4d88611c4461056f61231c565b60006009612778565b60c0820152611c5a612d75565b60005b8360200151811015611ed757611c738a82612955565b60808401526060840151611ca857611ca28a611c99611c9484610708613b49565b61231c565b60006011612778565b60c08401525b836020015160051415611cbd57603560a08401525b836020015160061415611cd257602d60a08401525b836020015160041415611ce757603e60a08401525b8015611d07578260a0015183602001818151611d039190613afb565b9052505b826080015160021415611d1c5760a460608401525b600285846080015160098110611d3457611d34613c7b565b6020020151611d439190613b27565b60ff166040840152611d728a611d69611d5d846001613afb565b611c9490610457613b49565b6000603f612778565b835260608201516080840151879060098110611d9057611d90613c7b565b6020020151888560c0015160198110611dab57611dab613c7b565b6020020151611dda611c948e611dd1611dc5886001613afb565b611c94906106f8613b49565b6044604e612778565b8651611deb90611c94906044613afb565b604051602001611dff959493929190613124565b60408051808303601f19018152919052606083018190526020840151611e2a90611c94906064613afb565b611e54611c948d611e4b611e3f876001613afb565b611c9490610682613b49565b600060b4612778565b604051602001611e66939291906131ec565b60408051808303601f190181529190526060808401829052840151611e9190611c9490600290613b13565b611e9e856040015161231c565b604051602001611eb093929190613254565b60408051808303601f19018152919052606083015280611ecf81613be6565b915050611c5d565b5060808301511561206c57604051602001612056907f3c66696c7465722069643d22442220783d222d3530252220793d222d3530252281527f2077696474683d223230302522206865696768743d2232303025223e0000000060208201527f3c666554757262756c656e636520747970653d226672616374616c4e6f697365603c8201527f2220626173654672657175656e63793d22302e3922206e756d6f637461766573605c8201526e1e9118911039b2b2b21e911811179f60891b607c8201527f3c6665436f6d706f73697465206f70657261746f723d22696e2220696e323d22608b8201527f536f75726365477261706869632220726573756c743d226d6f6e6f4e6f69736560ab8201526211179f60e91b60cb8201527f203c6665426c656e6420696e3d22536f75726365477261706869632220696e3260ce8201527f3d226d6f6e6f4e6f69736522206d6f64653d226d756c7469706c7922202f3e3c60ee8201526717b334b63a32b91f60c11b61010e8201526101160190565b60408051808303601f1901815291905260808201525b6040830151156120fd57604080516020810182526000815290840151600114156120ac576040518060800160405280604c8152602001613d17604c913990505b8360400151600214156120d5576040518060a00160405280606a8152602001613e12606a913990505b806040516020016120e69190613791565b60408051808303601f1901815291905260a0830152505b825186906019811061211157612111613c7b565b602002015160405160200161212691906132ea565b60408051808303601f19018152919052815260808301516121565760405180602001604052806000815250612181565b60405180604001604052806011815260200170222066696c7465723d2275726c2823442960781b8152505b60405160200161219191906132c3565b60408051601f1981840301815291905281600160200201526040830151158015906121c0575060008360800151115b156122075760408051808201909152601c81527f3c672066696c7465723d2275726c282343292075726c28234429223e0000000060208201528160025b602002015261229f565b604083015115612244576040805180820190915260148152731e33903334b63a32b91e913ab9361411a194911f60611b60208201528160026121fd565b608083015115612281576040805180820190915260148152731e33903334b63a32b91e913ab9361411a214911f60611b60208201528160026121fd565b60408051808201825260038152621e339f60e91b6020820152908201525b604080518082018252600a8152691e17b39f1e17b9bb339f60b11b60208083019190915260c08401829052835184820151858501516060870151608088015160a089015197518b986122fe989697959694959394929390929101613092565b60405160208183030381529060405297509750505050505050915091565b6060816123405750506040805180820190915260018152600360fc1b602082015290565b8160005b811561236a578061235481613be6565b91506123639050600a83613b13565b9150612344565b60008167ffffffffffffffff81111561238557612385613c91565b6040519080825280601f01601f1916602001820160405280156123af576020820181803683370190505b5090505b8415611441576123c4600183613b68565b91506123d1600a86613c25565b6123dc906030613afb565b60f81b8183815181106123f1576123f1613c7b565b60200101906001600160f81b031916908160001a905350612413600a86613b13565b94506123b3565b80516060908061243a575050604080516020810190915260008152919050565b60006003612449836002613afb565b6124539190613b13565b61245e906004613b49565b9050600061246d826020613afb565b67ffffffffffffffff81111561248557612485613c91565b6040519080825280601f01601f1916602001820160405280156124af576020820181803683370190505b5090506000604051806060016040528060408152602001613e7c604091399050600181016020830160005b8681101561253b576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b8352600490920191016124da565b506003860660018114612555576002811461256657612572565b613d3d60f01b600119830152612572565b603d60f81b6000198301525b505050918152949350505050565b6001600160a01b0383166125db576125d681600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b6125fe565b816001600160a01b0316836001600160a01b0316146125fe576125fe8382612a66565b6001600160a01b0382166126155761078781612b03565b826001600160a01b0316826001600160a01b031614610787576107878282612bb2565b6126428383612bf6565b61264f600084848461266b565b6107875760405162461bcd60e51b815260040161065190613a23565b60006001600160a01b0384163b1561276d57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906126af9033908990889088906004016139d3565b602060405180830381600087803b1580156126c957600080fd5b505af19250505080156126f9575060408051601f3d908101601f191682019092526126f691810190612fa1565b60015b612753573d808015612727576040519150601f19603f3d011682016040523d82523d6000602084013e61272c565b606091505b50805161274b5760405162461bcd60e51b815260040161065190613a23565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611441565b506001949350505050565b6000806127c1856127888861231c565b6127918761231c565b61279a8761231c565b6040516020016127ad949392919061303b565b604051602081830303815290604052612d44565b90506000846127d08186613b68565b6127db906001613afb565b6127e59084613c25565b6127ef9190613afb565b979650505050505050565b6000806128196128098461231c565b6040516020016127ad91906136ae565b905061282660c982613c25565b90506005606e8211801561283b575060a08211155b15612844575060065b60a082118015612855575060c88211155b1561285e575060045b9392505050565b6000806128846128748461231c565b6040516020016127ad91906136d3565b905061289160c982613c25565b9050600060ba821180156128a6575060c38211155b156128af575060015b608c821180156128c0575060968211155b1561285e575060029392505050565b6000806128ee6128de8461231c565b6040516020016127ad91906133b2565b90506128fb60c982613c25565b9050600060a082111561285e575060019392505050565b6000806129316129218461231c565b6040516020016127ad9190613547565b905061293e60c982613c25565b9050600060aa82111561285e575060019392505050565b60008061297e6129648561231c565b61296d8561231c565b6040516020016127ad929190613749565b905061298b60c982613c25565b905060006016821180156129a05750602c8211155b156129a9575060015b602c821180156129ba575060428211155b156129c3575060025b6042821180156129d4575060588211155b156129dd575060035b6058821180156129ee5750606e8211155b156129f7575060045b606e82118015612a08575060848211155b15612a11575060055b608482118015612a225750609a8211155b15612a2b575060065b609a82118015612a3c575060b08211155b15612a45575060075b60b082118015612a56575060c68211155b1561144157506008949350505050565b60006001612a7384610bfb565b612a7d9190613b68565b600083815260076020526040902054909150808214612ad0576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b600854600090612b1590600190613b68565b60008381526009602052604081205460088054939450909284908110612b3d57612b3d613c7b565b906000526020600020015490508060088381548110612b5e57612b5e613c7b565b6000918252602080832090910192909255828152600990915260408082208490558582528120556008805480612b9657612b96613c65565b6001900381819060005260206000200160009055905550505050565b6000612bbd83610bfb565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160a01b038216612c4c5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610651565b6000818152600260205260409020546001600160a01b031615612cb15760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610651565b612cbd60008383612580565b6001600160a01b0382166000908152600360205260408120805460019290612ce6908490613afb565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600081604051602001612d57919061301f565b60408051601f19818403018152919052805160209091012092915050565b6040518060e001604052806007905b6060815260200190600190039081612d845790505090565b80356001600160a01b0381168114612db357600080fd5b919050565b600060208284031215612dca57600080fd5b61285e82612d9c565b60008060408385031215612de657600080fd5b612def83612d9c565b9150612dfd60208401612d9c565b90509250929050565b600080600060608486031215612e1b57600080fd5b612e2484612d9c565b9250612e3260208501612d9c565b9150604084013590509250925092565b60008060008060808587031215612e5857600080fd5b612e6185612d9c565b9350612e6f60208601612d9c565b925060408501359150606085013567ffffffffffffffff80821115612e9357600080fd5b818701915087601f830112612ea757600080fd5b813581811115612eb957612eb9613c91565b604051601f8201601f19908116603f01168101908382118183101715612ee157612ee1613c91565b816040528281528a6020848701011115612efa57600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b60008060408385031215612f3157600080fd5b612f3a83612d9c565b915060208301358015158114612f4f57600080fd5b809150509250929050565b60008060408385031215612f6d57600080fd5b612f7683612d9c565b946020939093013593505050565b600060208284031215612f9657600080fd5b813561285e81613ca7565b600060208284031215612fb357600080fd5b815161285e81613ca7565b600060208284031215612fd057600080fd5b5035919050565b60008151808452612fef816020860160208601613b7f565b601f01601f19169290920160200192915050565b60008151613015818560208601613b7f565b9290920192915050565b60008251613031818460208701613b7f565b9190910192915050565b6000855161304d818460208a01613b7f565b855190830190613061818360208a01613b7f565b8551910190613074818360208901613b7f565b8451910190613087818360208801613b7f565b019695505050505050565b6000885160206130a58285838e01613b7f565b8951918401916130b88184848e01613b7f565b89519201916130ca8184848d01613b7f565b88519201916130dc8184848c01613b7f565b87519201916130ee8184848b01613b7f565b86519201916131008184848a01613b7f565b85519201916131128184848901613b7f565b919091019a9950505050505050505050565b60008651613136818460208b01613b7f565b621e339f60e91b9083019081528651613156816003840160208b01613b7f565b865191019061316c816003840160208a01613b7f565b7111103334b63616b7b830b1b4ba3c9e91181760711b60039290910191820152845161319f816015840160208901613b7f565b7f2220207472616e73666f726d3d227472616e736c6174652800000000000000006015929091019182015283516131dd81602d840160208801613b7f565b01602d01979650505050505050565b600084516131fe818460208901613b7f565b600160fd1b908301908152845161321c816001840160208901613b7f565b690524040e4dee8c2e8ca560b31b60019290910191820152835161324781600b840160208801613b7f565b01600b0195945050505050565b60008451613266818460208901613b7f565b8083019050600160fd1b8082528551613286816001850160208a01613b7f565b600192019182015283516132a1816002840160208801613b7f565b671491179f1e17b39f60c11b60029290910191820152600a0195945050505050565b600082516132d5818460208701613b7f565b6211179f60e91b920191825250600301919050565b7f3c7376672077696474683d2234303022206865696768743d223630302220766981527f6577426f783d223020302034303020363030222066696c6c3d226e6f6e65222060208201527f786d6c6e733d22687474703a2f2f7777772e77332e6f72672f323030302f737660408201527f67223e3c726563742077696474683d2234303022206865696768743d2236303060608201526711103334b6361e9160c11b6080820152600082516133a5816088850160208701613b7f565b9190910160880192915050565b694d4f4e4f4348524f4d4560b01b8152600082516133d781600a850160208701613b7f565b91909101600a0192915050565b7f2261747472696275746573223a205b7b2274726169745f74797065223a20224281527f61636b67726f756e6420436f6c6f72222c2276616c7565223a2022000000000060208201526000855161344281603b850160208a01613b7f565b7f227d2c207b2274726169745f74797065223a20224e756d626572206f66205368603b918401918201526f30b832b99116113b30b63ab2911d101160811b605b820152855161349881606b840160208a01613b7f565b7f227d2c207b2274726169745f74797065223a2022456666656374204e616d6522606b92909101918201526a16113b30b63ab2911d101160a91b608b82015284516134ea816096840160208901613b7f565b7f227d2c207b2274726169745f74797065223a20225465787475726564222c2276609692909101918201526730b63ab2911d101160c11b60b68201526127ef61353660be830186613003565b640113eae96160dd1b815260050190565b67151156151554915160c21b81526000825161356a816008850160208701613b7f565b9190910160080192915050565b757b226e616d65223a202253686170657320417274202360501b815283516000906135a9816016850160208901613b7f565b7f222c20224465736372697074696f6e223a2022416273747261637420617274206016918401918201527f7061696e74696e67206f6e2d636861696e20666f7220796f7520746f2064656360368201527f6f7261746520796f75722077616c6c20696e20746865206d657461766572736560568201526b081d5b9a5d995c9cd94b888b60a21b60768201528451613647816082840160208901613b7f565b7f22696d616765223a2022646174613a696d6167652f7376672b786d6c3b6261736082929091019182015263194d8d0b60e21b60a282015283516136928160a6840160208801613b7f565b61227d60f01b60a6929091019182015260a80195945050505050565b694e554d5f53484150455360b01b8152600082516133d781600a850160208701613b7f565b6820a724a6a0aa24a7a760b91b8152600082516136f7816009850160208701613b7f565b9190910160090192915050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c00000081526000825161373c81601d850160208701613b7f565b91909101601d0192915050565b6953686170655f5479706560b01b81526000835161376e81600a850160208801613b7f565b83519083019061378581600a840160208801613b7f565b01600a01949350505050565b7f3c66696c74657220786d6c6e733d22687474703a2f2f7777772e77332e6f726781527f2f323030302f737667222069643d22432220783d222d3530252220793d222d3560208201527f3025222077696474683d223230302522206865696768743d2232303025223e0060408201527f3c666554757262756c656e636520747970653d2274757262756c656e63652220605f8201527f626173654672657175656e63793d22302e303222206e756d4f6374617665733d607f8201527f22332220726573756c743d226e6f6973652220736565643d2230223e00000000609f8201527f3c616e696d617465206174747269627574654e616d653d22626173654672657160bb8201527003ab2b731bc9110323ab91e91189839911607d1b60db820152600082516138c78160ec850160208701613b7f565b7f2066696c6c3d22667265657a652220726570656174436f756e743d22696e646560ec918401918201527f66696e697465222f3e3c2f666554757262756c656e63653e000000000000000061010c8201526114416139be61012483017f3c6665446973706c6163656d656e744d617020696e323d226e6f69736522206981527f6e3d22536f75726365477261706869632220784368616e6e656c53656c65637460208201527f6f723d22522220794368616e6e656c53656c6563746f723d224722207363616c60408201527f653d223830223e3c2f6665446973706c6163656d656e744d61703e00000000006060820152607b0190565b681e17b334b63a32b91f60b91b815260090190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090613a0690830184612fd7565b9695505050505050565b60208152600061285e6020830184612fd7565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b60008219821115613b0e57613b0e613c39565b500190565b600082613b2257613b22613c4f565b500490565b600060ff831680613b3a57613b3a613c4f565b8060ff84160491505092915050565b6000816000190483118215151615613b6357613b63613c39565b500290565b600082821015613b7a57613b7a613c39565b500390565b60005b83811015613b9a578181015183820152602001613b82565b83811115610e4a5750506000910152565b600181811c90821680613bbf57607f821691505b60208210811415613be057634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415613bfa57613bfa613c39565b5060010190565b600063ffffffff80831681811415613c1b57613c1b613c39565b6001019392505050565b600082613c3457613c34613c4f565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b03198116811461129157600080fdfe3c726563742077696474683d2232303022206865696768743d2238392e32383537222066696c6c3d223c7061746820643d224d3134322e34323820304c3230302031303048304c3134322e34323820305a222066696c6c3d2276616c7565733d22303b303b302e30313b302e30323b302e30333b302e30343b302e30353b302e30353b302e30353b302e30353b302e30343b302e30333b302e30323b302e30313b303b30223c636972636c652063783d223832222063793d2238322220723d223832222066696c6c3d223c7061746820643d224d3230302032312e344c3020304c3130302e343636203136302e3731344c3230302032312e345a222066696c6c3d223c7061746820643d224d34332e373538352033312e313230354c32303020304c3134322e343637203131312e3738384c30203134342e3634334c34332e373538352033312e313230355a222066696c6c3d2276616c7565733d22303b303b302e303120302e343b302e303220302e343b302e303320302e343b302e303420302e343b302e303420302e343b302e303420302e343b302e303420302e343b302e303320302e343b302e303220302e343b302e303120302e343b303b30224142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f3c7061746820643d224d3135392e34383920372e3833323034433135392e3438392035352e36303236203132332e3738362039342e333238322037392e373434372039342e333238324333352e373032392039342e3332383220302035352e36303236203020372e38333230344330202d33392e39333835203134312e343131203134362e343239203138352e343533203134362e343239433232392e343935203134362e343239203135392e343839202d33392e39333835203135392e34383920372e38333230345a222066696c6c3d223c656c6c697073652063783d22313030222063793d2237352e39313632222072783d22313030222072793d2237352e39313632222066696c6c3d223c7061746820643d224d3020304c32303020304c3132372e3638342038322e343835394c302039332e373835334c3020305a222066696c6c3d223c7061746820643d224d31303020304c3132372e3030392037302e333834314c3230302039362e343238364c3132372e303039203132322e3437334c313030203139322e3835374c37322e39393039203132322e3437334c302039362e343238364c37322e393930392037302e333834314c31303020305a222066696c6c3d22a26469706673582212200677bbc1d3e3aeaf8a699d8ed5e3509c3cb23c4e6fd318a8b6001129c861717c64736f6c63430008070033

Block Transaction Difficulty Gas Used Reward
View All Blocks Produced

Block Uncle Number Difficulty Gas Used Reward
View All Uncles
Loading...
Loading
Loading...
Loading

OVERVIEW

ShapesArt is 100% on chain generated geometric shapes coming together in a beautiful symphony of colors and arrangement.

Validator Index Block Amount
View All Withdrawals

Transaction Hash Block Value Eth2 PubKey Valid
View All Deposits
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A contract address hosts a smart contract, which is a set of code stored on the blockchain that runs when predetermined conditions are met. Learn more about addresses in our Knowledge Base.