ETH Price: $2,421.19 (-2.02%)
 

Overview

Max Total Supply

0 YECHEFREEMINT

Holders

12

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Balance
1 YECHEFREEMINT
0x96eead4cf15be74b20f02c32bc2dbeb6494b5c17
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
YecheFreeMint

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-04-27
*/

// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&B##&###&####@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&BP~:!~~^^7~~^.:~!5PGB#&@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@5~.  :!??J557!?77!!77~^!?&@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@P.:~?J5PGB55555PGGGGPPYJJG@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#~75GGGBBBGPPGGBBBG5YYP5?P@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@B5P#@@BG!?PGGGGBGP555Y5557!:  .7~P@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&BY~^~~::?PBBGGGBG5YY?J?JY!:    ~ !&@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&#GPY7:..:~7PBBBGGGG55YJ!!7Y5G!   .::B@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@#G57:.^!77YGBBGGGG555J?7!?JJ?~.  .:B@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&##BBGGGGP5PG!:^^^~7PGBBGGGPY5Y?7!7??!^:... 5@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@&B5?!~!~~~^:::^^:::^::^~75GGGPP55YYYJ??JJ7~^... :&@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@P????Y555YJJ7!!~~^~^:^^~!?YGGP55YYJJYY?7!77~^. . !@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@#J?JJJYPP5YYJ?7!7!!!~^!!~~!?J5YYJJJJJJJJ?77~7?^... Y@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@GJJYJ?JY55YYJ?7!77??7~~!!!!77777777??7?JJ???!^!~:.: 5@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@#PYJ!75YJJJJY5YYJ77!7????7!!!!!!!!!~!!!77!!7?J??J!~757~~^G@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@#?!!!7?Y5Y?7JYJYYJ77!77??77???!!~~~~!!!!~~!7777??7?!!~~JPP#@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@G!7JYJJ555J?77JJJYJ?7777???????!^^^^!!~~!~!!!?7~~77!!7^.!@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@#G5!?JJ?J5P55Y?7!7JYJJ??7!????777!!!~^^~~~!!777??77~~!!??7^7@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@&#&@&&BY!~:7J??JY5PP5Y?!~!7JYJJ?77??77!!~~~!!::^^~777????7!~~~^~!!~B@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@&J~!!!^:.:~JY?YY5YJY55J!^!77JJ?77!!!!!!!~^^~~^~~~^~?????7!~~~~~~^ Y@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@#7~^~~^^~!J5YY5P5JJYYJ!~~!7J5J?!77!~~!!!~^!~~!7!!~~~!77!~^^^^~^:  P@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@&Y777!!!7!J555PPPPJJ557~^^~!JYJ?7777!!!!!~!!~!!!7!~^::~~~^^^^^::^:^&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@G7!7777??J5PPGGPP55PBG7^^^~!7??7!!!!!7!!~!!77777~~~^::^YP?~::::^~^~B@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@&5!77?JJYYYPGPPP5PPPG&B?^^^~^7!~~^^7B&######&&&#P7^::...7#&GY!:^^~:.?#@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@G?7?JJY55PGGPPPPGG#&@&?~~^.~~^^^?&@@@@@@@@@@@@@@&5!:.. ^@@@&BY!:...:&@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@&GYJJYY5PGG555B&@@@@@&7~~::~^^J@@@@@@@@BJ??YPB#B5!~:::!@@@@@@5^^:.:#@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@#PYJJYYY5P#@@@@@@@G?!!^.^!P@@@@@@@@&J..::....:^^^^J&@@@@@@J.^^:.#@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@&G5YP#@@@@@@@&Y!!!!~: ?@@@@@@@@@@P7!~~~~^::^~?B@@@@@@@&! .^: G@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@#7~~~~~^..!&@@@@@@@@#57~~~^^^^^?@@@@@@@@@@7 .:: !@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@P~~~~~^:. J@@@@@@@@@@#G55JJJJY&@@@@@@@@@G^^^:.  P@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@&7~^:!Y!^..B@@@@@@@@@@@@@@@@@@@@@@@@@@@#!^~~^^^.~@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@G~~::#BJ~::Y@@@@@@@@@@@@@@@@@@@@@@@@@@J:~~~~!:^B@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@?~~:!@@P7^:~5BBB&@@@@@@@@@@@@@@@@@@@@P?7~!!!.Y@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@#!!~~.J@@#?~:..: :!P@@@@@@@@@@@@@@@@@@@B5J??75@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@B!7~~^.7GBP7!~^:.  ~&@@@@@@@@@@@@@@@@@@@#GGP#@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@G^~!~~^::..^7???!^.:G@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@&Y?7?J??JJJ?YPPP55?~P@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@&&&@@@@@@@&&####B&@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
// @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@

// GALERIE YECHE LANGE 

// SPDX-License-Identifier: MIT

// File: @openzeppelin/contracts/utils/Counters.sol


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

pragma solidity ^0.8.0;

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

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

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

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

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

// File: @openzeppelin/contracts/utils/cryptography/MerkleProof.sol


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

pragma solidity ^0.8.0;

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

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

    function _efficientHash(bytes32 a, bytes32 b) private pure returns (bytes32 value) {
        assembly {
            mstore(0x00, a)
            mstore(0x20, b)
            value := keccak256(0x00, 0x40)
        }
    }
}

// File: @openzeppelin/contracts/access/IAccessControl.sol


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

pragma solidity ^0.8.0;

/**
 * @dev External interface of AccessControl declared to support ERC165 detection.
 */
interface IAccessControl {
    /**
     * @dev Emitted when `newAdminRole` is set as ``role``'s admin role, replacing `previousAdminRole`
     *
     * `DEFAULT_ADMIN_ROLE` is the starting admin for all roles, despite
     * {RoleAdminChanged} not being emitted signaling this.
     *
     * _Available since v3.1._
     */
    event RoleAdminChanged(bytes32 indexed role, bytes32 indexed previousAdminRole, bytes32 indexed newAdminRole);

    /**
     * @dev Emitted when `account` is granted `role`.
     *
     * `sender` is the account that originated the contract call, an admin role
     * bearer except when using {AccessControl-_setupRole}.
     */
    event RoleGranted(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Emitted when `account` is revoked `role`.
     *
     * `sender` is the account that originated the contract call:
     *   - if using `revokeRole`, it is the admin role bearer
     *   - if using `renounceRole`, it is the role bearer (i.e. `account`)
     */
    event RoleRevoked(bytes32 indexed role, address indexed account, address indexed sender);

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) external view returns (bool);

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {AccessControl-_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) external view returns (bytes32);

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) external;

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been granted `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) external;
}

// File: @openzeppelin/contracts/utils/Strings.sol


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

pragma solidity ^0.8.0;

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

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

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

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

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

// File: @openzeppelin/contracts/utils/Context.sol


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

pragma solidity ^0.8.0;

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

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

// File: @openzeppelin/contracts/utils/Address.sol


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

pragma solidity ^0.8.1;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     *
     * [IMPORTANT]
     * ====
     * You shouldn't rely on `isContract` to protect against flash loan attacks!
     *
     * Preventing calls from contracts is highly discouraged. It breaks composability, breaks support for smart wallets
     * like Gnosis Safe, and does not provide security since it can be circumvented by calling from a contract
     * constructor.
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize/address.code.length, which returns 0
        // for contracts in construction, since the code is only stored at the end
        // of the constructor execution.

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol


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

pragma solidity ^0.8.0;

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

// File: @openzeppelin/contracts/utils/introspection/IERC165.sol


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

pragma solidity ^0.8.0;

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

// File: @openzeppelin/contracts/utils/introspection/ERC165.sol


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

pragma solidity ^0.8.0;


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

// File: @openzeppelin/contracts/access/AccessControl.sol


// OpenZeppelin Contracts (last updated v4.5.0) (access/AccessControl.sol)

pragma solidity ^0.8.0;


/**
 * @dev Contract module that allows children to implement role-based access
 * control mechanisms. This is a lightweight version that doesn't allow enumerating role
 * members except through off-chain means by accessing the contract event logs. Some
 * applications may benefit from on-chain enumerability, for those cases see
 * {AccessControlEnumerable}.
 *
 * Roles are referred to by their `bytes32` identifier. These should be exposed
 * in the external API and be unique. The best way to achieve this is by
 * using `public constant` hash digests:
 *
 * ```
 * bytes32 public constant MY_ROLE = keccak256("MY_ROLE");
 * ```
 *
 * Roles can be used to represent a set of permissions. To restrict access to a
 * function call, use {hasRole}:
 *
 * ```
 * function foo() public {
 *     require(hasRole(MY_ROLE, msg.sender));
 *     ...
 * }
 * ```
 *
 * Roles can be granted and revoked dynamically via the {grantRole} and
 * {revokeRole} functions. Each role has an associated admin role, and only
 * accounts that have a role's admin role can call {grantRole} and {revokeRole}.
 *
 * By default, the admin role for all roles is `DEFAULT_ADMIN_ROLE`, which means
 * that only accounts with this role will be able to grant or revoke other
 * roles. More complex role relationships can be created by using
 * {_setRoleAdmin}.
 *
 * WARNING: The `DEFAULT_ADMIN_ROLE` is also its own admin: it has permission to
 * grant and revoke this role. Extra precautions should be taken to secure
 * accounts that have been granted it.
 */
abstract contract AccessControl is Context, IAccessControl, ERC165 {
    struct RoleData {
        mapping(address => bool) members;
        bytes32 adminRole;
    }

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

    /**
     * @dev Modifier that checks that an account has a specific role. Reverts
     * with a standardized message including the required role.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     *
     * _Available since v4.1._
     */
    modifier onlyRole(bytes32 role) {
        _checkRole(role, _msgSender());
        _;
    }

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

    /**
     * @dev Returns `true` if `account` has been granted `role`.
     */
    function hasRole(bytes32 role, address account) public view virtual override returns (bool) {
        return _roles[role].members[account];
    }

    /**
     * @dev Revert with a standard message if `account` is missing `role`.
     *
     * The format of the revert reason is given by the following regular expression:
     *
     *  /^AccessControl: account (0x[0-9a-f]{40}) is missing role (0x[0-9a-f]{64})$/
     */
    function _checkRole(bytes32 role, address account) internal view virtual {
        if (!hasRole(role, account)) {
            revert(
                string(
                    abi.encodePacked(
                        "AccessControl: account ",
                        Strings.toHexString(uint160(account), 20),
                        " is missing role ",
                        Strings.toHexString(uint256(role), 32)
                    )
                )
            );
        }
    }

    /**
     * @dev Returns the admin role that controls `role`. See {grantRole} and
     * {revokeRole}.
     *
     * To change a role's admin, use {_setRoleAdmin}.
     */
    function getRoleAdmin(bytes32 role) public view virtual override returns (bytes32) {
        return _roles[role].adminRole;
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * If `account` had been granted `role`, emits a {RoleRevoked} event.
     *
     * Requirements:
     *
     * - the caller must have ``role``'s admin role.
     */
    function revokeRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _revokeRole(role, account);
    }

    /**
     * @dev Revokes `role` from the calling account.
     *
     * Roles are often managed via {grantRole} and {revokeRole}: this function's
     * purpose is to provide a mechanism for accounts to lose their privileges
     * if they are compromised (such as when a trusted device is misplaced).
     *
     * If the calling account had been revoked `role`, emits a {RoleRevoked}
     * event.
     *
     * Requirements:
     *
     * - the caller must be `account`.
     */
    function renounceRole(bytes32 role, address account) public virtual override {
        require(account == _msgSender(), "AccessControl: can only renounce roles for self");

        _revokeRole(role, account);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * If `account` had not been already granted `role`, emits a {RoleGranted}
     * event. Note that unlike {grantRole}, this function doesn't perform any
     * checks on the calling account.
     *
     * [WARNING]
     * ====
     * This function should only be called from the constructor when setting
     * up the initial roles for the system.
     *
     * Using this function in any other way is effectively circumventing the admin
     * system imposed by {AccessControl}.
     * ====
     *
     * NOTE: This function is deprecated in favor of {_grantRole}.
     */
    function _setupRole(bytes32 role, address account) internal virtual {
        _grantRole(role, account);
    }

    /**
     * @dev Sets `adminRole` as ``role``'s admin role.
     *
     * Emits a {RoleAdminChanged} event.
     */
    function _setRoleAdmin(bytes32 role, bytes32 adminRole) internal virtual {
        bytes32 previousAdminRole = getRoleAdmin(role);
        _roles[role].adminRole = adminRole;
        emit RoleAdminChanged(role, previousAdminRole, adminRole);
    }

    /**
     * @dev Grants `role` to `account`.
     *
     * Internal function without access restriction.
     */
    function _grantRole(bytes32 role, address account) internal virtual {
        if (!hasRole(role, account)) {
            _roles[role].members[account] = true;
            emit RoleGranted(role, account, _msgSender());
        }
    }

    /**
     * @dev Revokes `role` from `account`.
     *
     * Internal function without access restriction.
     */
    function _revokeRole(bytes32 role, address account) internal virtual {
        if (hasRole(role, account)) {
            _roles[role].members[account] = false;
            emit RoleRevoked(role, account, _msgSender());
        }
    }
}

// File: @openzeppelin/contracts/token/ERC721/IERC721.sol


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

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

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

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

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

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

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol


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

pragma solidity ^0.8.0;


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

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

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

// File: @openzeppelin/contracts/token/ERC721/ERC721.sol


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

pragma solidity ^0.8.0;


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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId);
    }

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

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

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

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

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

// File: @openzeppelin/contracts/token/ERC721/extensions/ERC721Burnable.sol


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

pragma solidity ^0.8.0;


/**
 * @title ERC721 Burnable Token
 * @dev ERC721 Token that can be irreversibly burned (destroyed).
 */
abstract contract ERC721Burnable is Context, ERC721 {
    /**
     * @dev Burns `tokenId`. See {ERC721-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId) public virtual {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721Burnable: caller is not owner nor approved");
        _burn(tokenId);
    }
}

// File: contracts/YecheFreeMint.sol


pragma solidity ^0.8.4;


contract YecheFreeMint is ERC721, ERC721Burnable, AccessControl {

    using Counters for Counters.Counter;

    struct Artwork {
        uint256 maxSupply;
        bytes32 merkleRoot;
        string baseURI;
        Counters.Counter editionIDCounter;
    }

    bytes32 public constant GIFTER_ROLE = keccak256("GIFTER_ROLE");

    mapping(address => mapping(uint256 => bool)) public whitelistClaimed;

    mapping(uint256 => bool) public artworkInitialized;
    mapping(uint256 => uint256) public tokenIDToArtworkID;
    mapping(uint256 => uint256) public tokenIDToEditionID;

    mapping(uint256 => Artwork) public artworks;

    Counters.Counter public tokenIDCounter;
    Counters.Counter public artworkIDCounter;

    constructor(address[] memory gifters) ERC721("YecheFreeMint", "YECHEFREEMINT") {
        _setupRole(DEFAULT_ADMIN_ROLE, msg.sender);
        _setupRole(GIFTER_ROLE, msg.sender);

        for (uint256 i = 0; i < gifters.length; i++) {
            _setupRole(GIFTER_ROLE, gifters[i]);
        }
    }
    
    function checkWhitelist(uint256 artworkID, address addr, bytes32[] calldata merkleProof) public view returns (bool) {
        require(artworkInitialized[artworkID] == true, "artwork hasn't been initialized");

        bytes32 leaf = keccak256(abi.encodePacked(addr));
        bytes32 merkleRoot = artworks[artworkID].merkleRoot;
        bool isWhitelisted = MerkleProof.verify(merkleProof, merkleRoot, leaf);

        return isWhitelisted;
    }

    function getNumMinted(uint256 artworkID) public view returns (uint256) {
        require(artworkInitialized[artworkID] == true, "artwork hasn't been initialized");
        return artworks[artworkID].editionIDCounter.current();
    }

    function getMaxSupply(uint256 artworkID) public view returns (uint256) {
        require(artworkInitialized[artworkID] == true, "artwork hasn't been initialized");
        return artworks[artworkID].maxSupply;
    }

    function getMintedOut(uint256 artworkID) public view returns (bool) {
        require(artworkInitialized[artworkID] == true, "artwork hasn't been initialized");
        return artworks[artworkID].maxSupply == artworks[artworkID].editionIDCounter.current();
    }

    function tokenURI(uint256 tokenID) public view override returns (string memory) {
        require(_exists(tokenID), "ERC721Metadata: URI query for nonexistent token");

        uint256 artworkID = tokenIDToArtworkID[tokenID];

        uint256 editionID = tokenIDToEditionID[tokenID];

        string memory baseURI = artworks[artworkID].baseURI;

        return string(abi.encodePacked(baseURI, Strings.toString(editionID)));
    }

    function artworkBaseURI(uint256 artworkID) public view returns (string memory) {
        require(artworkInitialized[artworkID], "artwork not initialized");
        return artworks[artworkID].baseURI;
    }

    function mint(uint256 artworkID, bytes32[] calldata merkleProof) public {
        require(artworkInitialized[artworkID] == true, "artwork hasn't been initialized");

        uint256 editionID = artworks[artworkID].editionIDCounter.current(); 
        require(editionID < artworks[artworkID].maxSupply, "artwork already minted out");

        require(!whitelistClaimed[msg.sender][artworkID], "address already minted this work");

        bytes32 leaf = keccak256(abi.encodePacked(msg.sender));
        bytes32 merkleRoot = artworks[artworkID].merkleRoot;
        require(MerkleProof.verify(merkleProof, merkleRoot, leaf), "invalid proof");

        whitelistClaimed[msg.sender][artworkID] = true;

        uint256 tokenID = tokenIDCounter.current();
        tokenIDCounter.increment();

        artworks[artworkID].editionIDCounter.increment();

        tokenIDToArtworkID[tokenID] = artworkID;
        tokenIDToEditionID[tokenID] = editionID;

        _safeMint(msg.sender, tokenID);
    }

    function gift(uint256 artworkID, address to) public onlyRole(GIFTER_ROLE) {
        require(artworkInitialized[artworkID] == true, "artwork hasn't been initialized");

        uint256 editionID = artworks[artworkID].editionIDCounter.current(); 
        require(editionID < artworks[artworkID].maxSupply, "artwork already minted out");

        uint256 tokenID = tokenIDCounter.current();
        tokenIDCounter.increment();

        artworks[artworkID].editionIDCounter.increment();

        tokenIDToArtworkID[tokenID] = artworkID;
        tokenIDToEditionID[tokenID] = editionID;

        _safeMint(to, tokenID);
    }

    function updateArtworkBaseURI(uint256 artworkID, string calldata newBaseURI) public onlyRole(DEFAULT_ADMIN_ROLE) {
        require(artworkInitialized[artworkID] == true, "artwork hasn't been initialized");
        artworks[artworkID].baseURI = newBaseURI;
    }

    function updateArtworkMerkleRoot(uint256 artworkID, bytes32 newMerkleRoot) public onlyRole(DEFAULT_ADMIN_ROLE) {
        require(artworkInitialized[artworkID] == true, "artwork hasn't been initialized");
        artworks[artworkID].merkleRoot = newMerkleRoot;
    }

    function setupArtwork(uint256 maxSupply, bytes32 merkleRoot, string calldata baseURI) public onlyRole(DEFAULT_ADMIN_ROLE) {
        uint256 artworkID = artworkIDCounter.current();

        require(artworkInitialized[artworkID] == false, "artwork has already been initialized");
        require(maxSupply > 0, "max supply must be greater than 0");

        artworks[artworkID] = Artwork({
            maxSupply: maxSupply,
            merkleRoot: merkleRoot,
            baseURI: baseURI,
            editionIDCounter: Counters.Counter(0)
        });

        artworkInitialized[artworkID] = true;

        artworkIDCounter.increment();
    }

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address[]","name":"gifters","type":"address[]"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"GIFTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"artworkID","type":"uint256"}],"name":"artworkBaseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"artworkIDCounter","outputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"artworkInitialized","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"artworks","outputs":[{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"string","name":"baseURI","type":"string"},{"components":[{"internalType":"uint256","name":"_value","type":"uint256"}],"internalType":"struct Counters.Counter","name":"editionIDCounter","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"artworkID","type":"uint256"},{"internalType":"address","name":"addr","type":"address"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"checkWhitelist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"uint256","name":"artworkID","type":"uint256"}],"name":"getMaxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"artworkID","type":"uint256"}],"name":"getMintedOut","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"artworkID","type":"uint256"}],"name":"getNumMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"artworkID","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"gift","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"artworkID","type":"uint256"},{"internalType":"bytes32[]","name":"merkleProof","type":"bytes32[]"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","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":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxSupply","type":"uint256"},{"internalType":"bytes32","name":"merkleRoot","type":"bytes32"},{"internalType":"string","name":"baseURI","type":"string"}],"name":"setupArtwork","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":"tokenIDCounter","outputs":[{"internalType":"uint256","name":"_value","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenIDToArtworkID","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenIDToEditionID","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":[{"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":"uint256","name":"artworkID","type":"uint256"},{"internalType":"string","name":"newBaseURI","type":"string"}],"name":"updateArtworkBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"artworkID","type":"uint256"},{"internalType":"bytes32","name":"newMerkleRoot","type":"bytes32"}],"name":"updateArtworkMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"name":"whitelistClaimed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]

60806040523480156200001157600080fd5b5060405162002f5638038062002f568339810160408190526200003491620002b9565b6040518060400160405280600d81526020016c165958da19519c9959535a5b9d609a1b8152506040518060400160405280600d81526020016c165150d2115194915153525395609a1b815250816000908051906020019062000098929190620001f6565b508051620000ae906001906020840190620001f6565b50620000c09150600090503362000142565b620000db60008051602062002f368339815191523362000142565b60005b81518110156200013a576200012560008051602062002f36833981519152838381518110620001115762000111620003f9565b60200260200101516200014260201b60201c565b806200013181620003cf565b915050620000de565b505062000425565b6200014e828262000152565b5050565b60008281526006602090815260408083206001600160a01b038516845290915290205460ff166200014e5760008281526006602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620001b23390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b828054620002049062000392565b90600052602060002090601f01602090048101928262000228576000855562000273565b82601f106200024357805160ff191683800117855562000273565b8280016001018555821562000273579182015b828111156200027357825182559160200191906001019062000256565b506200028192915062000285565b5090565b5b8082111562000281576000815560010162000286565b80516001600160a01b0381168114620002b457600080fd5b919050565b60006020808385031215620002cd57600080fd5b82516001600160401b0380821115620002e557600080fd5b818501915085601f830112620002fa57600080fd5b8151818111156200030f576200030f6200040f565b8060051b604051601f19603f830116810181811085821117156200033757620003376200040f565b604052828152858101935084860182860187018a10156200035757600080fd5b600095505b83861015620003855762000370816200029c565b8552600195909501949386019386016200035c565b5098975050505050505050565b600181811c90821680620003a757607f821691505b60208210811415620003c957634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415620003f257634e487b7160e01b600052601160045260246000fd5b5060010190565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b612b0180620004356000396000f3fe608060405234801561001057600080fd5b50600436106102325760003560e01c806376e9dd1811610130578063b88d4fde116100b8578063df6ec4711161007c578063df6ec4711461052a578063e985e9c51461054d578063f43f63c514610589578063f71359091461059c578063fa4ed5a3146105af57600080fd5b8063b88d4fde146104be578063ba41b0c6146104d1578063c87b56dd146104e4578063cd952ff7146104f7578063d547741f1461051757600080fd5b806391d14854116100ff57806391d148541461046157806395d89b4114610474578063a217fddf1461047c578063a22cb46514610484578063a3dfa0441461049757600080fd5b806376e9dd181461041e5780637d3fb2e61461043157806383a076be1461043b578063859ca71d1461044e57600080fd5b806336568abe116101be5780635e1066e1116101825780635e1066e1146103bb5780635e495d74146103db5780636352211e146103ee5780636deb47301461040157806370a082311461040b57600080fd5b806336568abe1461034c57806342842e0e1461035f57806342966c68146103725780634b6026731461038557806351afaeab146103a857600080fd5b8063095ea7b311610205578063095ea7b3146102cd5780631d5b9f7d146102e257806323b872dd146102f5578063248a9ca3146103085780632f2ff15d1461033957600080fd5b806301ffc9a714610237578063064f110c1461025f57806306fdde031461028d578063081812fc146102a2575b600080fd5b61024a61024536600461259b565b6105c2565b60405190151581526020015b60405180910390f35b61024a61026d366004612535565b600760209081526000928352604080842090915290825290205460ff1681565b6102956105d3565b6040516102569190612830565b6102b56102b036600461255f565b610665565b6040516001600160a01b039091168152602001610256565b6102e06102db366004612535565b6106ff565b005b61024a6102f03660046125d5565b610815565b6102e06103033660046123e1565b6108df565b61032b61031636600461255f565b60009081526006602052604090206001015490565b604051908152602001610256565b6102e0610347366004612578565b610911565b6102e061035a366004612578565b610937565b6102e061036d3660046123e1565b6109b5565b6102e061038036600461255f565b6109d0565b61039861039336600461255f565b610a4a565b604051610256949392919061291d565b6102956103b636600461255f565b610b0a565b61032b6103c936600461255f565b60096020526000908152604090205481565b61032b6103e936600461255f565b610c0c565b6102b56103fc36600461255f565b610c52565b600c5461032b9081565b61032b610419366004612393565b610cc9565b6102e061042c36600461267b565b610d50565b600d5461032b9081565b6102e0610449366004612578565b610da5565b61032b61045c36600461255f565b610ec4565b61024a61046f366004612578565b610f0e565b610295610f39565b61032b600081565b6102e06104923660046124f9565b610f48565b61032b7fca050c94470b1f4a8903d38474de29772235c710d8a46176cf55c80ffc51ac6281565b6102e06104cc36600461241d565b610f53565b6102e06104df36600461262f565b610f8b565b6102956104f236600461255f565b6111d2565b61032b61050536600461255f565b600a6020526000908152604090205481565b6102e0610525366004612578565b61133b565b61024a61053836600461255f565b60086020526000908152604090205460ff1681565b61024a61055b3660046123ae565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b61024a61059736600461255f565b611361565b6102e06105aa3660046126e4565b6113ae565b6102e06105bd36600461269d565b611409565b60006105cd826115b8565b92915050565b6060600080546105e2906129f3565b80601f016020809104026020016040519081016040528092919081815260200182805461060e906129f3565b801561065b5780601f106106305761010080835404028352916020019161065b565b820191906000526020600020905b81548152906001019060200180831161063e57829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b03166106e35760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061070a82610c52565b9050806001600160a01b0316836001600160a01b031614156107785760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084016106da565b336001600160a01b03821614806107945750610794813361055b565b6108065760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016106da565b61081083836115dd565b505050565b60008481526008602052604081205460ff1615156001146108485760405162461bcd60e51b81526004016106da906128e6565b6040516bffffffffffffffffffffffff19606086901b16602082015260009060340160408051601f19818403018152828252805160209182012060008a8152600b8352838120600101548884028087018501909552888652919550909390926108d1928991899182919085019084908082843760009201919091525086925087915061164b9050565b93505050505b949350505050565b6108ea335b82611661565b6109065760405162461bcd60e51b81526004016106da90612895565b610810838383611754565b60008281526006602052604090206001015461092d81336118f0565b6108108383611954565b6001600160a01b03811633146109a75760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016106da565b6109b182826119da565b5050565b61081083838360405180602001604052806000815250610f53565b6109d9336108e4565b610a3e5760405162461bcd60e51b815260206004820152603060248201527f4552433732314275726e61626c653a2063616c6c6572206973206e6f74206f7760448201526f1b995c881b9bdc88185c1c1c9bdd995960821b60648201526084016106da565b610a4781611a41565b50565b600b6020526000908152604090208054600182015460028301805492939192610a72906129f3565b80601f0160208091040260200160405190810160405280929190818152602001828054610a9e906129f3565b8015610aeb5780601f10610ac057610100808354040283529160200191610aeb565b820191906000526020600020905b815481529060010190602001808311610ace57829003601f168201915b5050604080516020810190915260039095015485525091929150859050565b60008181526008602052604090205460609060ff16610b6b5760405162461bcd60e51b815260206004820152601760248201527f617274776f726b206e6f7420696e697469616c697a656400000000000000000060448201526064016106da565b6000828152600b602052604090206002018054610b87906129f3565b80601f0160208091040260200160405190810160405280929190818152602001828054610bb3906129f3565b8015610c005780601f10610bd557610100808354040283529160200191610c00565b820191906000526020600020905b815481529060010190602001808311610be357829003601f168201915b50505050509050919050565b60008181526008602052604081205460ff161515600114610c3f5760405162461bcd60e51b81526004016106da906128e6565b506000908152600b602052604090205490565b6000818152600260205260408120546001600160a01b0316806105cd5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b60648201526084016106da565b60006001600160a01b038216610d345760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b60648201526084016106da565b506001600160a01b031660009081526003602052604090205490565b6000610d5c81336118f0565b60008381526008602052604090205460ff161515600114610d8f5760405162461bcd60e51b81526004016106da906128e6565b506000918252600b602052604090912060010155565b7fca050c94470b1f4a8903d38474de29772235c710d8a46176cf55c80ffc51ac62610dd081336118f0565b60008381526008602052604090205460ff161515600114610e035760405162461bcd60e51b81526004016106da906128e6565b6000838152600b60205260409020600381015490548110610e665760405162461bcd60e51b815260206004820152601a60248201527f617274776f726b20616c7265616479206d696e746564206f757400000000000060448201526064016106da565b6000610e71600c5490565b9050610e81600c80546001019055565b6000858152600b602090815260408083206003018054600101905583835260098252808320889055600a9091529020829055610ebd8482611adc565b5050505050565b60008181526008602052604081205460ff161515600114610ef75760405162461bcd60e51b81526004016106da906128e6565b6000828152600b60205260409020600301546105cd565b60009182526006602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6060600180546105e2906129f3565b6109b1338383611af6565b610f5d3383611661565b610f795760405162461bcd60e51b81526004016106da90612895565b610f8584848484611bc5565b50505050565b60008381526008602052604090205460ff161515600114610fbe5760405162461bcd60e51b81526004016106da906128e6565b6000838152600b602052604090206003810154905481106110215760405162461bcd60e51b815260206004820152601a60248201527f617274776f726b20616c7265616479206d696e746564206f757400000000000060448201526064016106da565b33600090815260076020908152604080832087845290915290205460ff161561108c5760405162461bcd60e51b815260206004820181905260248201527f6164647265737320616c7265616479206d696e746564207468697320776f726b60448201526064016106da565b6040516bffffffffffffffffffffffff193360601b16602082015260009060340160408051601f1981840301815282825280516020918201206000898152600b8352839020600101548783028086018401909452878552909450926111139290918891889182919085019084908082843760009201919091525085925086915061164b9050565b61114f5760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b60448201526064016106da565b3360009081526007602090815260408083208984529091528120805460ff1916600117905561117d600c5490565b905061118d600c80546001019055565b6000878152600b6020908152604080832060030180546001019055838352600982528083208a9055600a90915290208490556111c93382611adc565b50505050505050565b6000818152600260205260409020546060906001600160a01b03166112515760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b60648201526084016106da565b600082815260096020908152604080832054600a835281842054818552600b9093529083206002018054919391611287906129f3565b80601f01602080910402602001604051908101604052809291908181526020018280546112b3906129f3565b80156113005780601f106112d557610100808354040283529160200191611300565b820191906000526020600020905b8154815290600101906020018083116112e357829003601f168201915b505050505090508061131183611bf8565b60405160200161132292919061274f565b6040516020818303038152906040529350505050919050565b60008281526006602052604090206001015461135781336118f0565b61081083836119da565b60008181526008602052604081205460ff1615156001146113945760405162461bcd60e51b81526004016106da906128e6565b506000908152600b60205260409020600381015490541490565b60006113ba81336118f0565b60008481526008602052604090205460ff1615156001146113ed5760405162461bcd60e51b81526004016106da906128e6565b6000848152600b60205260409020610ebd9060020184846121dc565b600061141581336118f0565b6000611420600d5490565b60008181526008602052604090205490915060ff161561148e5760405162461bcd60e51b8152602060048201526024808201527f617274776f726b2068617320616c7265616479206265656e20696e697469616c6044820152631a5e995960e21b60648201526084016106da565b600086116114e85760405162461bcd60e51b815260206004820152602160248201527f6d617820737570706c79206d7573742062652067726561746572207468616e206044820152600360fc1b60648201526084016106da565b604051806080016040528087815260200186815260200185858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509385525050604080516020818101835284825294850152858352600b84529182902084518155848401516001820155918401518051929361157a93600286019350910190612260565b5060609190910151516003909101556000818152600860205260409020805460ff191660011790556115b0600d80546001019055565b505050505050565b60006001600160e01b03198216637965db0b60e01b14806105cd57506105cd82611cf6565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061161282610c52565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000826116588584611d46565b14949350505050565b6000818152600260205260408120546001600160a01b03166116da5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016106da565b60006116e583610c52565b9050806001600160a01b0316846001600160a01b031614806117205750836001600160a01b031661171584610665565b6001600160a01b0316145b806108d757506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff166108d7565b826001600160a01b031661176782610c52565b6001600160a01b0316146117cb5760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b60648201526084016106da565b6001600160a01b03821661182d5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016106da565b6118386000826115dd565b6001600160a01b0383166000908152600360205260408120805460019290611861908490612999565b90915550506001600160a01b038216600090815260036020526040812080546001929061188f90849061294e565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6118fa8282610f0e565b6109b157611912816001600160a01b03166014611dba565b61191d836020611dba565b60405160200161192e92919061277e565b60408051601f198184030181529082905262461bcd60e51b82526106da91600401612830565b61195e8282610f0e565b6109b15760008281526006602090815260408083206001600160a01b03851684529091529020805460ff191660011790556119963390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6119e48282610f0e565b156109b15760008281526006602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000611a4c82610c52565b9050611a596000836115dd565b6001600160a01b0381166000908152600360205260408120805460019290611a82908490612999565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6109b1828260405180602001604052806000815250611f5d565b816001600160a01b0316836001600160a01b03161415611b585760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016106da565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611bd0848484611754565b611bdc84848484611f90565b610f855760405162461bcd60e51b81526004016106da90612843565b606081611c1c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611c465780611c3081612a2e565b9150611c3f9050600a83612966565b9150611c20565b60008167ffffffffffffffff811115611c6157611c61612a9f565b6040519080825280601f01601f191660200182016040528015611c8b576020820181803683370190505b5090505b84156108d757611ca0600183612999565b9150611cad600a86612a49565b611cb890603061294e565b60f81b818381518110611ccd57611ccd612a89565b60200101906001600160f81b031916908160001a905350611cef600a86612966565b9450611c8f565b60006001600160e01b031982166380ac58cd60e01b1480611d2757506001600160e01b03198216635b5e139f60e01b145b806105cd57506301ffc9a760e01b6001600160e01b03198316146105cd565b600081815b8451811015611db2576000858281518110611d6857611d68612a89565b60200260200101519050808311611d8e5760008381526020829052604090209250611d9f565b600081815260208490526040902092505b5080611daa81612a2e565b915050611d4b565b509392505050565b60606000611dc983600261297a565b611dd490600261294e565b67ffffffffffffffff811115611dec57611dec612a9f565b6040519080825280601f01601f191660200182016040528015611e16576020820181803683370190505b509050600360fc1b81600081518110611e3157611e31612a89565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110611e6057611e60612a89565b60200101906001600160f81b031916908160001a9053506000611e8484600261297a565b611e8f90600161294e565b90505b6001811115611f07576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110611ec357611ec3612a89565b1a60f81b828281518110611ed957611ed9612a89565b60200101906001600160f81b031916908160001a90535060049490941c93611f00816129dc565b9050611e92565b508315611f565760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016106da565b9392505050565b611f67838361209a565b611f746000848484611f90565b6108105760405162461bcd60e51b81526004016106da90612843565b60006001600160a01b0384163b1561209257604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611fd49033908990889088906004016127f3565b602060405180830381600087803b158015611fee57600080fd5b505af192505050801561201e575060408051601f3d908101601f1916820190925261201b918101906125b8565b60015b612078573d80801561204c576040519150601f19603f3d011682016040523d82523d6000602084013e612051565b606091505b5080516120705760405162461bcd60e51b81526004016106da90612843565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506108d7565b5060016108d7565b6001600160a01b0382166120f05760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016106da565b6000818152600260205260409020546001600160a01b0316156121555760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016106da565b6001600160a01b038216600090815260036020526040812080546001929061217e90849061294e565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b8280546121e8906129f3565b90600052602060002090601f01602090048101928261220a5760008555612250565b82601f106122235782800160ff19823516178555612250565b82800160010185558215612250579182015b82811115612250578235825591602001919060010190612235565b5061225c9291506122d4565b5090565b82805461226c906129f3565b90600052602060002090601f01602090048101928261228e5760008555612250565b82601f106122a757805160ff1916838001178555612250565b82800160010185558215612250579182015b828111156122505782518255916020019190600101906122b9565b5b8082111561225c57600081556001016122d5565b80356001600160a01b038116811461230057600080fd5b919050565b60008083601f84011261231757600080fd5b50813567ffffffffffffffff81111561232f57600080fd5b6020830191508360208260051b850101111561234a57600080fd5b9250929050565b60008083601f84011261236357600080fd5b50813567ffffffffffffffff81111561237b57600080fd5b60208301915083602082850101111561234a57600080fd5b6000602082840312156123a557600080fd5b611f56826122e9565b600080604083850312156123c157600080fd5b6123ca836122e9565b91506123d8602084016122e9565b90509250929050565b6000806000606084860312156123f657600080fd5b6123ff846122e9565b925061240d602085016122e9565b9150604084013590509250925092565b6000806000806080858703121561243357600080fd5b61243c856122e9565b935061244a602086016122e9565b925060408501359150606085013567ffffffffffffffff8082111561246e57600080fd5b818701915087601f83011261248257600080fd5b81358181111561249457612494612a9f565b604051601f8201601f19908116603f011681019083821181831017156124bc576124bc612a9f565b816040528281528a60208487010111156124d557600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6000806040838503121561250c57600080fd5b612515836122e9565b91506020830135801515811461252a57600080fd5b809150509250929050565b6000806040838503121561254857600080fd5b612551836122e9565b946020939093013593505050565b60006020828403121561257157600080fd5b5035919050565b6000806040838503121561258b57600080fd5b823591506123d8602084016122e9565b6000602082840312156125ad57600080fd5b8135611f5681612ab5565b6000602082840312156125ca57600080fd5b8151611f5681612ab5565b600080600080606085870312156125eb57600080fd5b843593506125fb602086016122e9565b9250604085013567ffffffffffffffff81111561261757600080fd5b61262387828801612305565b95989497509550505050565b60008060006040848603121561264457600080fd5b83359250602084013567ffffffffffffffff81111561266257600080fd5b61266e86828701612305565b9497909650939450505050565b6000806040838503121561268e57600080fd5b50508035926020909101359150565b600080600080606085870312156126b357600080fd5b8435935060208501359250604085013567ffffffffffffffff8111156126d857600080fd5b61262387828801612351565b6000806000604084860312156126f957600080fd5b83359250602084013567ffffffffffffffff81111561271757600080fd5b61266e86828701612351565b6000815180845261273b8160208601602086016129b0565b601f01601f19169290920160200192915050565b600083516127618184602088016129b0565b8351908301906127758183602088016129b0565b01949350505050565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516127b68160178501602088016129b0565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516127e78160288401602088016129b0565b01602801949350505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061282690830184612723565b9695505050505050565b602081526000611f566020830184612723565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601f908201527f617274776f726b206861736e2774206265656e20696e697469616c697a656400604082015260600190565b84815283602082015260806040820152600061293c6080830185612723565b90508251606083015295945050505050565b6000821982111561296157612961612a5d565b500190565b60008261297557612975612a73565b500490565b600081600019048311821515161561299457612994612a5d565b500290565b6000828210156129ab576129ab612a5d565b500390565b60005b838110156129cb5781810151838201526020016129b3565b83811115610f855750506000910152565b6000816129eb576129eb612a5d565b506000190190565b600181811c90821680612a0757607f821691505b60208210811415612a2857634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415612a4257612a42612a5d565b5060010190565b600082612a5857612a58612a73565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114610a4757600080fdfea26469706673582212207cd3bd63cc976f070ddbf081dc15584cfa7bfae281c930b245095d9b1899519364736f6c63430008070033ca050c94470b1f4a8903d38474de29772235c710d8a46176cf55c80ffc51ac6200000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000730ca048cab18d4f09f2a295936325addfee7bcf000000000000000000000000520c221e86429f274381ca057e6114210c07e2fd

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102325760003560e01c806376e9dd1811610130578063b88d4fde116100b8578063df6ec4711161007c578063df6ec4711461052a578063e985e9c51461054d578063f43f63c514610589578063f71359091461059c578063fa4ed5a3146105af57600080fd5b8063b88d4fde146104be578063ba41b0c6146104d1578063c87b56dd146104e4578063cd952ff7146104f7578063d547741f1461051757600080fd5b806391d14854116100ff57806391d148541461046157806395d89b4114610474578063a217fddf1461047c578063a22cb46514610484578063a3dfa0441461049757600080fd5b806376e9dd181461041e5780637d3fb2e61461043157806383a076be1461043b578063859ca71d1461044e57600080fd5b806336568abe116101be5780635e1066e1116101825780635e1066e1146103bb5780635e495d74146103db5780636352211e146103ee5780636deb47301461040157806370a082311461040b57600080fd5b806336568abe1461034c57806342842e0e1461035f57806342966c68146103725780634b6026731461038557806351afaeab146103a857600080fd5b8063095ea7b311610205578063095ea7b3146102cd5780631d5b9f7d146102e257806323b872dd146102f5578063248a9ca3146103085780632f2ff15d1461033957600080fd5b806301ffc9a714610237578063064f110c1461025f57806306fdde031461028d578063081812fc146102a2575b600080fd5b61024a61024536600461259b565b6105c2565b60405190151581526020015b60405180910390f35b61024a61026d366004612535565b600760209081526000928352604080842090915290825290205460ff1681565b6102956105d3565b6040516102569190612830565b6102b56102b036600461255f565b610665565b6040516001600160a01b039091168152602001610256565b6102e06102db366004612535565b6106ff565b005b61024a6102f03660046125d5565b610815565b6102e06103033660046123e1565b6108df565b61032b61031636600461255f565b60009081526006602052604090206001015490565b604051908152602001610256565b6102e0610347366004612578565b610911565b6102e061035a366004612578565b610937565b6102e061036d3660046123e1565b6109b5565b6102e061038036600461255f565b6109d0565b61039861039336600461255f565b610a4a565b604051610256949392919061291d565b6102956103b636600461255f565b610b0a565b61032b6103c936600461255f565b60096020526000908152604090205481565b61032b6103e936600461255f565b610c0c565b6102b56103fc36600461255f565b610c52565b600c5461032b9081565b61032b610419366004612393565b610cc9565b6102e061042c36600461267b565b610d50565b600d5461032b9081565b6102e0610449366004612578565b610da5565b61032b61045c36600461255f565b610ec4565b61024a61046f366004612578565b610f0e565b610295610f39565b61032b600081565b6102e06104923660046124f9565b610f48565b61032b7fca050c94470b1f4a8903d38474de29772235c710d8a46176cf55c80ffc51ac6281565b6102e06104cc36600461241d565b610f53565b6102e06104df36600461262f565b610f8b565b6102956104f236600461255f565b6111d2565b61032b61050536600461255f565b600a6020526000908152604090205481565b6102e0610525366004612578565b61133b565b61024a61053836600461255f565b60086020526000908152604090205460ff1681565b61024a61055b3660046123ae565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b61024a61059736600461255f565b611361565b6102e06105aa3660046126e4565b6113ae565b6102e06105bd36600461269d565b611409565b60006105cd826115b8565b92915050565b6060600080546105e2906129f3565b80601f016020809104026020016040519081016040528092919081815260200182805461060e906129f3565b801561065b5780601f106106305761010080835404028352916020019161065b565b820191906000526020600020905b81548152906001019060200180831161063e57829003601f168201915b5050505050905090565b6000818152600260205260408120546001600160a01b03166106e35760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061070a82610c52565b9050806001600160a01b0316836001600160a01b031614156107785760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084016106da565b336001600160a01b03821614806107945750610794813361055b565b6108065760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016106da565b61081083836115dd565b505050565b60008481526008602052604081205460ff1615156001146108485760405162461bcd60e51b81526004016106da906128e6565b6040516bffffffffffffffffffffffff19606086901b16602082015260009060340160408051601f19818403018152828252805160209182012060008a8152600b8352838120600101548884028087018501909552888652919550909390926108d1928991899182919085019084908082843760009201919091525086925087915061164b9050565b93505050505b949350505050565b6108ea335b82611661565b6109065760405162461bcd60e51b81526004016106da90612895565b610810838383611754565b60008281526006602052604090206001015461092d81336118f0565b6108108383611954565b6001600160a01b03811633146109a75760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b60648201526084016106da565b6109b182826119da565b5050565b61081083838360405180602001604052806000815250610f53565b6109d9336108e4565b610a3e5760405162461bcd60e51b815260206004820152603060248201527f4552433732314275726e61626c653a2063616c6c6572206973206e6f74206f7760448201526f1b995c881b9bdc88185c1c1c9bdd995960821b60648201526084016106da565b610a4781611a41565b50565b600b6020526000908152604090208054600182015460028301805492939192610a72906129f3565b80601f0160208091040260200160405190810160405280929190818152602001828054610a9e906129f3565b8015610aeb5780601f10610ac057610100808354040283529160200191610aeb565b820191906000526020600020905b815481529060010190602001808311610ace57829003601f168201915b5050604080516020810190915260039095015485525091929150859050565b60008181526008602052604090205460609060ff16610b6b5760405162461bcd60e51b815260206004820152601760248201527f617274776f726b206e6f7420696e697469616c697a656400000000000000000060448201526064016106da565b6000828152600b602052604090206002018054610b87906129f3565b80601f0160208091040260200160405190810160405280929190818152602001828054610bb3906129f3565b8015610c005780601f10610bd557610100808354040283529160200191610c00565b820191906000526020600020905b815481529060010190602001808311610be357829003601f168201915b50505050509050919050565b60008181526008602052604081205460ff161515600114610c3f5760405162461bcd60e51b81526004016106da906128e6565b506000908152600b602052604090205490565b6000818152600260205260408120546001600160a01b0316806105cd5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b60648201526084016106da565b60006001600160a01b038216610d345760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b60648201526084016106da565b506001600160a01b031660009081526003602052604090205490565b6000610d5c81336118f0565b60008381526008602052604090205460ff161515600114610d8f5760405162461bcd60e51b81526004016106da906128e6565b506000918252600b602052604090912060010155565b7fca050c94470b1f4a8903d38474de29772235c710d8a46176cf55c80ffc51ac62610dd081336118f0565b60008381526008602052604090205460ff161515600114610e035760405162461bcd60e51b81526004016106da906128e6565b6000838152600b60205260409020600381015490548110610e665760405162461bcd60e51b815260206004820152601a60248201527f617274776f726b20616c7265616479206d696e746564206f757400000000000060448201526064016106da565b6000610e71600c5490565b9050610e81600c80546001019055565b6000858152600b602090815260408083206003018054600101905583835260098252808320889055600a9091529020829055610ebd8482611adc565b5050505050565b60008181526008602052604081205460ff161515600114610ef75760405162461bcd60e51b81526004016106da906128e6565b6000828152600b60205260409020600301546105cd565b60009182526006602090815260408084206001600160a01b0393909316845291905290205460ff1690565b6060600180546105e2906129f3565b6109b1338383611af6565b610f5d3383611661565b610f795760405162461bcd60e51b81526004016106da90612895565b610f8584848484611bc5565b50505050565b60008381526008602052604090205460ff161515600114610fbe5760405162461bcd60e51b81526004016106da906128e6565b6000838152600b602052604090206003810154905481106110215760405162461bcd60e51b815260206004820152601a60248201527f617274776f726b20616c7265616479206d696e746564206f757400000000000060448201526064016106da565b33600090815260076020908152604080832087845290915290205460ff161561108c5760405162461bcd60e51b815260206004820181905260248201527f6164647265737320616c7265616479206d696e746564207468697320776f726b60448201526064016106da565b6040516bffffffffffffffffffffffff193360601b16602082015260009060340160408051601f1981840301815282825280516020918201206000898152600b8352839020600101548783028086018401909452878552909450926111139290918891889182919085019084908082843760009201919091525085925086915061164b9050565b61114f5760405162461bcd60e51b815260206004820152600d60248201526c34b73b30b634b210383937b7b360991b60448201526064016106da565b3360009081526007602090815260408083208984529091528120805460ff1916600117905561117d600c5490565b905061118d600c80546001019055565b6000878152600b6020908152604080832060030180546001019055838352600982528083208a9055600a90915290208490556111c93382611adc565b50505050505050565b6000818152600260205260409020546060906001600160a01b03166112515760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b60648201526084016106da565b600082815260096020908152604080832054600a835281842054818552600b9093529083206002018054919391611287906129f3565b80601f01602080910402602001604051908101604052809291908181526020018280546112b3906129f3565b80156113005780601f106112d557610100808354040283529160200191611300565b820191906000526020600020905b8154815290600101906020018083116112e357829003601f168201915b505050505090508061131183611bf8565b60405160200161132292919061274f565b6040516020818303038152906040529350505050919050565b60008281526006602052604090206001015461135781336118f0565b61081083836119da565b60008181526008602052604081205460ff1615156001146113945760405162461bcd60e51b81526004016106da906128e6565b506000908152600b60205260409020600381015490541490565b60006113ba81336118f0565b60008481526008602052604090205460ff1615156001146113ed5760405162461bcd60e51b81526004016106da906128e6565b6000848152600b60205260409020610ebd9060020184846121dc565b600061141581336118f0565b6000611420600d5490565b60008181526008602052604090205490915060ff161561148e5760405162461bcd60e51b8152602060048201526024808201527f617274776f726b2068617320616c7265616479206265656e20696e697469616c6044820152631a5e995960e21b60648201526084016106da565b600086116114e85760405162461bcd60e51b815260206004820152602160248201527f6d617820737570706c79206d7573742062652067726561746572207468616e206044820152600360fc1b60648201526084016106da565b604051806080016040528087815260200186815260200185858080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201829052509385525050604080516020818101835284825294850152858352600b84529182902084518155848401516001820155918401518051929361157a93600286019350910190612260565b5060609190910151516003909101556000818152600860205260409020805460ff191660011790556115b0600d80546001019055565b505050505050565b60006001600160e01b03198216637965db0b60e01b14806105cd57506105cd82611cf6565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061161282610c52565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000826116588584611d46565b14949350505050565b6000818152600260205260408120546001600160a01b03166116da5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016106da565b60006116e583610c52565b9050806001600160a01b0316846001600160a01b031614806117205750836001600160a01b031661171584610665565b6001600160a01b0316145b806108d757506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff166108d7565b826001600160a01b031661176782610c52565b6001600160a01b0316146117cb5760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b60648201526084016106da565b6001600160a01b03821661182d5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016106da565b6118386000826115dd565b6001600160a01b0383166000908152600360205260408120805460019290611861908490612999565b90915550506001600160a01b038216600090815260036020526040812080546001929061188f90849061294e565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b6118fa8282610f0e565b6109b157611912816001600160a01b03166014611dba565b61191d836020611dba565b60405160200161192e92919061277e565b60408051601f198184030181529082905262461bcd60e51b82526106da91600401612830565b61195e8282610f0e565b6109b15760008281526006602090815260408083206001600160a01b03851684529091529020805460ff191660011790556119963390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6119e48282610f0e565b156109b15760008281526006602090815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b6000611a4c82610c52565b9050611a596000836115dd565b6001600160a01b0381166000908152600360205260408120805460019290611a82908490612999565b909155505060008281526002602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6109b1828260405180602001604052806000815250611f5d565b816001600160a01b0316836001600160a01b03161415611b585760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016106da565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611bd0848484611754565b611bdc84848484611f90565b610f855760405162461bcd60e51b81526004016106da90612843565b606081611c1c5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611c465780611c3081612a2e565b9150611c3f9050600a83612966565b9150611c20565b60008167ffffffffffffffff811115611c6157611c61612a9f565b6040519080825280601f01601f191660200182016040528015611c8b576020820181803683370190505b5090505b84156108d757611ca0600183612999565b9150611cad600a86612a49565b611cb890603061294e565b60f81b818381518110611ccd57611ccd612a89565b60200101906001600160f81b031916908160001a905350611cef600a86612966565b9450611c8f565b60006001600160e01b031982166380ac58cd60e01b1480611d2757506001600160e01b03198216635b5e139f60e01b145b806105cd57506301ffc9a760e01b6001600160e01b03198316146105cd565b600081815b8451811015611db2576000858281518110611d6857611d68612a89565b60200260200101519050808311611d8e5760008381526020829052604090209250611d9f565b600081815260208490526040902092505b5080611daa81612a2e565b915050611d4b565b509392505050565b60606000611dc983600261297a565b611dd490600261294e565b67ffffffffffffffff811115611dec57611dec612a9f565b6040519080825280601f01601f191660200182016040528015611e16576020820181803683370190505b509050600360fc1b81600081518110611e3157611e31612a89565b60200101906001600160f81b031916908160001a905350600f60fb1b81600181518110611e6057611e60612a89565b60200101906001600160f81b031916908160001a9053506000611e8484600261297a565b611e8f90600161294e565b90505b6001811115611f07576f181899199a1a9b1b9c1cb0b131b232b360811b85600f1660108110611ec357611ec3612a89565b1a60f81b828281518110611ed957611ed9612a89565b60200101906001600160f81b031916908160001a90535060049490941c93611f00816129dc565b9050611e92565b508315611f565760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e7460448201526064016106da565b9392505050565b611f67838361209a565b611f746000848484611f90565b6108105760405162461bcd60e51b81526004016106da90612843565b60006001600160a01b0384163b1561209257604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611fd49033908990889088906004016127f3565b602060405180830381600087803b158015611fee57600080fd5b505af192505050801561201e575060408051601f3d908101601f1916820190925261201b918101906125b8565b60015b612078573d80801561204c576040519150601f19603f3d011682016040523d82523d6000602084013e612051565b606091505b5080516120705760405162461bcd60e51b81526004016106da90612843565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506108d7565b5060016108d7565b6001600160a01b0382166120f05760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016106da565b6000818152600260205260409020546001600160a01b0316156121555760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016106da565b6001600160a01b038216600090815260036020526040812080546001929061217e90849061294e565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b8280546121e8906129f3565b90600052602060002090601f01602090048101928261220a5760008555612250565b82601f106122235782800160ff19823516178555612250565b82800160010185558215612250579182015b82811115612250578235825591602001919060010190612235565b5061225c9291506122d4565b5090565b82805461226c906129f3565b90600052602060002090601f01602090048101928261228e5760008555612250565b82601f106122a757805160ff1916838001178555612250565b82800160010185558215612250579182015b828111156122505782518255916020019190600101906122b9565b5b8082111561225c57600081556001016122d5565b80356001600160a01b038116811461230057600080fd5b919050565b60008083601f84011261231757600080fd5b50813567ffffffffffffffff81111561232f57600080fd5b6020830191508360208260051b850101111561234a57600080fd5b9250929050565b60008083601f84011261236357600080fd5b50813567ffffffffffffffff81111561237b57600080fd5b60208301915083602082850101111561234a57600080fd5b6000602082840312156123a557600080fd5b611f56826122e9565b600080604083850312156123c157600080fd5b6123ca836122e9565b91506123d8602084016122e9565b90509250929050565b6000806000606084860312156123f657600080fd5b6123ff846122e9565b925061240d602085016122e9565b9150604084013590509250925092565b6000806000806080858703121561243357600080fd5b61243c856122e9565b935061244a602086016122e9565b925060408501359150606085013567ffffffffffffffff8082111561246e57600080fd5b818701915087601f83011261248257600080fd5b81358181111561249457612494612a9f565b604051601f8201601f19908116603f011681019083821181831017156124bc576124bc612a9f565b816040528281528a60208487010111156124d557600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6000806040838503121561250c57600080fd5b612515836122e9565b91506020830135801515811461252a57600080fd5b809150509250929050565b6000806040838503121561254857600080fd5b612551836122e9565b946020939093013593505050565b60006020828403121561257157600080fd5b5035919050565b6000806040838503121561258b57600080fd5b823591506123d8602084016122e9565b6000602082840312156125ad57600080fd5b8135611f5681612ab5565b6000602082840312156125ca57600080fd5b8151611f5681612ab5565b600080600080606085870312156125eb57600080fd5b843593506125fb602086016122e9565b9250604085013567ffffffffffffffff81111561261757600080fd5b61262387828801612305565b95989497509550505050565b60008060006040848603121561264457600080fd5b83359250602084013567ffffffffffffffff81111561266257600080fd5b61266e86828701612305565b9497909650939450505050565b6000806040838503121561268e57600080fd5b50508035926020909101359150565b600080600080606085870312156126b357600080fd5b8435935060208501359250604085013567ffffffffffffffff8111156126d857600080fd5b61262387828801612351565b6000806000604084860312156126f957600080fd5b83359250602084013567ffffffffffffffff81111561271757600080fd5b61266e86828701612351565b6000815180845261273b8160208601602086016129b0565b601f01601f19169290920160200192915050565b600083516127618184602088016129b0565b8351908301906127758183602088016129b0565b01949350505050565b7f416363657373436f6e74726f6c3a206163636f756e74200000000000000000008152600083516127b68160178501602088016129b0565b7001034b99036b4b9b9b4b733903937b6329607d1b60179184019182015283516127e78160288401602088016129b0565b01602801949350505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061282690830184612723565b9695505050505050565b602081526000611f566020830184612723565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601f908201527f617274776f726b206861736e2774206265656e20696e697469616c697a656400604082015260600190565b84815283602082015260806040820152600061293c6080830185612723565b90508251606083015295945050505050565b6000821982111561296157612961612a5d565b500190565b60008261297557612975612a73565b500490565b600081600019048311821515161561299457612994612a5d565b500290565b6000828210156129ab576129ab612a5d565b500390565b60005b838110156129cb5781810151838201526020016129b3565b83811115610f855750506000910152565b6000816129eb576129eb612a5d565b506000190190565b600181811c90821680612a0757607f821691505b60208210811415612a2857634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415612a4257612a42612a5d565b5060010190565b600082612a5857612a58612a73565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160e01b031981168114610a4757600080fdfea26469706673582212207cd3bd63cc976f070ddbf081dc15584cfa7bfae281c930b245095d9b1899519364736f6c63430008070033

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

00000000000000000000000000000000000000000000000000000000000000200000000000000000000000000000000000000000000000000000000000000002000000000000000000000000730ca048cab18d4f09f2a295936325addfee7bcf000000000000000000000000520c221e86429f274381ca057e6114210c07e2fd

-----Decoded View---------------
Arg [0] : gifters (address[]): 0x730Ca048cab18D4F09F2A295936325adDfeE7BcF,0x520C221E86429F274381ca057e6114210C07e2FD

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000020
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000002
Arg [2] : 000000000000000000000000730ca048cab18d4f09f2a295936325addfee7bcf
Arg [3] : 000000000000000000000000520c221e86429f274381ca057e6114210c07e2fd


Deployed Bytecode Sourcemap

54372:5990:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60181:168;;;;;;:::i;:::-;;:::i;:::-;;;9863:14:1;;9856:22;9838:41;;9826:2;9811:18;60181:168:0;;;;;;;;54717:68;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;41346:100;;;:::i;:::-;;;;;;;:::i;42905:221::-;;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;9161:32:1;;;9143:51;;9131:2;9116:18;42905:221:0;8997:203:1;42428:411:0;;;;;;:::i;:::-;;:::i;:::-;;55436:453;;;;;;:::i;:::-;;:::i;43655:339::-;;;;;;:::i;:::-;;:::i;29773:131::-;;;;;;:::i;:::-;29847:7;29874:12;;;:6;:12;;;;;:22;;;;29773:131;;;;10036:25:1;;;10024:2;10009:18;29773:131:0;9890:177:1;30166:147:0;;;;;;:::i;:::-;;:::i;31214:218::-;;;;;;:::i;:::-;;:::i;44065:185::-;;;;;;:::i;:::-;;:::i;54049:245::-;;;;;;:::i;:::-;;:::i;54973:43::-;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;:::i;57088:208::-;;;;;;:::i;:::-;;:::i;54851:53::-;;;;;;:::i;:::-;;;;;;;;;;;;;;56140:218;;;;;;:::i;:::-;;:::i;41040:239::-;;;;;;:::i;:::-;;:::i;55025:38::-;;;;;;;40770:208;;;;;;:::i;:::-;;:::i;59240:268::-;;;;;;:::i;:::-;;:::i;55070:40::-;;;;;;;58325:635;;;;;;:::i;:::-;;:::i;55897:235::-;;;;;;:::i;:::-;;:::i;28642:147::-;;;;;;:::i;:::-;;:::i;41515:104::-;;;:::i;27733:49::-;;27778:4;27733:49;;43198:155;;;;;;:::i;:::-;;:::i;54646:62::-;;54684:24;54646:62;;44321:328;;;;;;:::i;:::-;;:::i;57304:1013::-;;;;;;:::i;:::-;;:::i;56639:441::-;;;;;;:::i;:::-;;:::i;54911:53::-;;;;;;:::i;:::-;;;;;;;;;;;;;;30558:149;;;;;;:::i;:::-;;:::i;54794:50::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;43424:164;;;;;;:::i;:::-;-1:-1:-1;;;;;43545:25:0;;;43521:4;43545:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;43424:164;56366:265;;;;;;:::i;:::-;;:::i;58968:264::-;;;;;;:::i;:::-;;:::i;59516:657::-;;;;;;:::i;:::-;;:::i;60181:168::-;60281:4;60305:36;60329:11;60305:23;:36::i;:::-;60298:43;60181:168;-1:-1:-1;;60181:168:0:o;41346:100::-;41400:13;41433:5;41426:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41346:100;:::o;42905:221::-;42981:7;46248:16;;;:7;:16;;;;;;-1:-1:-1;;;;;46248:16:0;43001:73;;;;-1:-1:-1;;;43001:73:0;;16290:2:1;43001:73:0;;;16272:21:1;16329:2;16309:18;;;16302:30;16368:34;16348:18;;;16341:62;-1:-1:-1;;;16419:18:1;;;16412:42;16471:19;;43001:73:0;;;;;;;;;-1:-1:-1;43094:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;43094:24:0;;42905:221::o;42428:411::-;42509:13;42525:23;42540:7;42525:14;:23::i;:::-;42509:39;;42573:5;-1:-1:-1;;;;;42567:11:0;:2;-1:-1:-1;;;;;42567:11:0;;;42559:57;;;;-1:-1:-1;;;42559:57:0;;17119:2:1;42559:57:0;;;17101:21:1;17158:2;17138:18;;;17131:30;17197:34;17177:18;;;17170:62;-1:-1:-1;;;17248:18:1;;;17241:31;17289:19;;42559:57:0;16917:397:1;42559:57:0;14147:10;-1:-1:-1;;;;;42651:21:0;;;;:62;;-1:-1:-1;42676:37:0;42693:5;14147:10;43424:164;:::i;42676:37::-;42629:168;;;;-1:-1:-1;;;42629:168:0;;14683:2:1;42629:168:0;;;14665:21:1;14722:2;14702:18;;;14695:30;14761:34;14741:18;;;14734:62;14832:26;14812:18;;;14805:54;14876:19;;42629:168:0;14481:420:1;42629:168:0;42810:21;42819:2;42823:7;42810:8;:21::i;:::-;42498:341;42428:411;;:::o;55436:453::-;55546:4;55571:29;;;:18;:29;;;;;;;;:37;;:29;:37;55563:81;;;;-1:-1:-1;;;55563:81:0;;;;;;;:::i;:::-;55682:22;;-1:-1:-1;;7646:2:1;7642:15;;;7638:53;55682:22:0;;;7626:66:1;55657:12:0;;7708::1;;55682:22:0;;;-1:-1:-1;;55682:22:0;;;;;;;;;55672:33;;55682:22;55672:33;;;;55716:18;55737:19;;;:8;:19;;;;;:30;;;55799:49;;;;;;;;;;;;;;55672:33;;-1:-1:-1;55737:30:0;;55716:18;;55799:49;;55818:11;;;;;;55799:49;;;;55818:11;;55799:49;55818:11;55799:49;;;;;;;;;-1:-1:-1;55831:10:0;;-1:-1:-1;55843:4:0;;-1:-1:-1;55799:18:0;;-1:-1:-1;55799:49:0:i;:::-;55778:70;-1:-1:-1;;;;55436:453:0;;;;;;;:::o;43655:339::-;43850:41;14147:10;43869:12;43883:7;43850:18;:41::i;:::-;43842:103;;;;-1:-1:-1;;;43842:103:0;;;;;;;:::i;:::-;43958:28;43968:4;43974:2;43978:7;43958:9;:28::i;30166:147::-;29847:7;29874:12;;;:6;:12;;;;;:22;;;28224:30;28235:4;14147:10;28224;:30::i;:::-;30280:25:::1;30291:4;30297:7;30280:10;:25::i;31214:218::-:0;-1:-1:-1;;;;;31310:23:0;;14147:10;31310:23;31302:83;;;;-1:-1:-1;;;31302:83:0;;19463:2:1;31302:83:0;;;19445:21:1;19502:2;19482:18;;;19475:30;19541:34;19521:18;;;19514:62;-1:-1:-1;;;19592:18:1;;;19585:45;19647:19;;31302:83:0;19261:411:1;31302:83:0;31398:26;31410:4;31416:7;31398:11;:26::i;:::-;31214:218;;:::o;44065:185::-;44203:39;44220:4;44226:2;44230:7;44203:39;;;;;;;;;;;;:16;:39::i;54049:245::-;54167:41;14147:10;54186:12;14067:98;54167:41;54159:102;;;;-1:-1:-1;;;54159:102:0;;19046:2:1;54159:102:0;;;19028:21:1;19085:2;19065:18;;;19058:30;19124:34;19104:18;;;19097:62;-1:-1:-1;;;19175:18:1;;;19168:46;19231:19;;54159:102:0;18844:412:1;54159:102:0;54272:14;54278:7;54272:5;:14::i;:::-;54049:245;:::o;54973:43::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;54973:43:0;;;;;;;;;;;;;;;;-1:-1:-1;54973:43:0;;;-1:-1:-1;54973:43:0;;-1:-1:-1;54973:43:0:o;57088:208::-;57186:29;;;;:18;:29;;;;;;57152:13;;57186:29;;57178:65;;;;-1:-1:-1;;;57178:65:0;;13516:2:1;57178:65:0;;;13498:21:1;13555:2;13535:18;;;13528:30;13594:25;13574:18;;;13567:53;13637:18;;57178:65:0;13314:347:1;57178:65:0;57261:19;;;;:8;:19;;;;;:27;;57254:34;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57088:208;;;:::o;56140:218::-;56202:7;56230:29;;;:18;:29;;;;;;;;:37;;:29;:37;56222:81;;;;-1:-1:-1;;;56222:81:0;;;;;;;:::i;:::-;-1:-1:-1;56321:19:0;;;;:8;:19;;;;;:29;;56140:218::o;41040:239::-;41112:7;41148:16;;;:7;:16;;;;;;-1:-1:-1;;;;;41148:16:0;41183:19;41175:73;;;;-1:-1:-1;;;41175:73:0;;15519:2:1;41175:73:0;;;15501:21:1;15558:2;15538:18;;;15531:30;15597:34;15577:18;;;15570:62;-1:-1:-1;;;15648:18:1;;;15641:39;15697:19;;41175:73:0;15317:405:1;40770:208:0;40842:7;-1:-1:-1;;;;;40870:19:0;;40862:74;;;;-1:-1:-1;;;40862:74:0;;15108:2:1;40862:74:0;;;15090:21:1;15147:2;15127:18;;;15120:30;15186:34;15166:18;;;15159:62;-1:-1:-1;;;15237:18:1;;;15230:40;15287:19;;40862:74:0;14906:406:1;40862:74:0;-1:-1:-1;;;;;;40954:16:0;;;;;:9;:16;;;;;;;40770:208::o;59240:268::-;27778:4;28224:30;27778:4;14147:10;28224;:30::i;:::-;59370:29:::1;::::0;;;:18:::1;:29;::::0;;;;;::::1;;:37;;:29:::0;:37:::1;59362:81;;;;-1:-1:-1::0;;;59362:81:0::1;;;;;;;:::i;:::-;-1:-1:-1::0;59454:19:0::1;::::0;;;:8:::1;:19;::::0;;;;;:30:::1;;:46:::0;59240:268::o;58325:635::-;54684:24;28224:30;54684:24;14147:10;28224;:30::i;:::-;58418:29:::1;::::0;;;:18:::1;:29;::::0;;;;;::::1;;:37;;:29:::0;:37:::1;58410:81;;;;-1:-1:-1::0;;;58410:81:0::1;;;;;;;:::i;:::-;58504:17;58524:19:::0;;;:8:::1;:19;::::0;;;;:36:::1;::::0;::::1;5333:14:::0;58602:29;;58590:41;::::1;58582:80;;;::::0;-1:-1:-1;;;58582:80:0;;12041:2:1;58582:80:0::1;::::0;::::1;12023:21:1::0;12080:2;12060:18;;;12053:30;12119:28;12099:18;;;12092:56;12165:18;;58582:80:0::1;11839:350:1::0;58582:80:0::1;58675:15;58693:24;:14;5333::::0;;5241:114;58693:24:::1;58675:42;;58728:26;:14;5452:19:::0;;5470:1;5452:19;;;5363:127;58728:26:::1;58767:19;::::0;;;:8:::1;:19;::::0;;;;;;;:36:::1;;5452:19:::0;;5470:1;5452:19;;;58828:27;;;:18:::1;:27:::0;;;;;:39;;;58878:18:::1;:27:::0;;;;;:39;;;58930:22:::1;58940:2:::0;58828:27;58930:9:::1;:22::i;:::-;58399:561;;58325:635:::0;;;:::o;55897:235::-;55959:7;55987:29;;;:18;:29;;;;;;;;:37;;:29;:37;55979:81;;;;-1:-1:-1;;;55979:81:0;;;;;;;:::i;:::-;56078:19;;;;:8;:19;;;;;:36;;5333:14;56078:46;5241:114;28642:147;28728:4;28752:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;28752:29:0;;;;;;;;;;;;;;;28642:147::o;41515:104::-;41571:13;41604:7;41597:14;;;;;:::i;43198:155::-;43293:52;14147:10;43326:8;43336;43293:18;:52::i;44321:328::-;44496:41;14147:10;44529:7;44496:18;:41::i;:::-;44488:103;;;;-1:-1:-1;;;44488:103:0;;;;;;;:::i;:::-;44602:39;44616:4;44622:2;44626:7;44635:5;44602:13;:39::i;:::-;44321:328;;;;:::o;57304:1013::-;57395:29;;;;:18;:29;;;;;;;;:37;;:29;:37;57387:81;;;;-1:-1:-1;;;57387:81:0;;;;;;;:::i;:::-;57481:17;57501:19;;;:8;:19;;;;;:36;;;5333:14;57579:29;;57567:41;;57559:80;;;;-1:-1:-1;;;57559:80:0;;12041:2:1;57559:80:0;;;12023:21:1;12080:2;12060:18;;;12053:30;12119:28;12099:18;;;12092:56;12165:18;;57559:80:0;11839:350:1;57559:80:0;57678:10;57661:28;;;;:16;:28;;;;;;;;:39;;;;;;;;;;;57660:40;57652:85;;;;-1:-1:-1;;;57652:85:0;;13155:2:1;57652:85:0;;;13137:21:1;;;13174:18;;;13167:30;13233:34;13213:18;;;13206:62;13285:18;;57652:85:0;12953:356:1;57652:85:0;57775:28;;-1:-1:-1;;57792:10:0;7646:2:1;7642:15;7638:53;57775:28:0;;;7626:66:1;57750:12:0;;7708::1;;57775:28:0;;;-1:-1:-1;;57775:28:0;;;;;;;;;57765:39;;57775:28;57765:39;;;;57815:18;57836:19;;;:8;:19;;;;;:30;;;57885:49;;;;;;;;;;;;;;57765:39;;-1:-1:-1;57836:30:0;57885:49;;57775:28;;57904:11;;;;;;57885:49;;;;57904:11;;57885:49;57904:11;57885:49;;;;;;;;;-1:-1:-1;57917:10:0;;-1:-1:-1;57929:4:0;;-1:-1:-1;57885:18:0;;-1:-1:-1;57885:49:0:i;:::-;57877:75;;;;-1:-1:-1;;;57877:75:0;;18344:2:1;57877:75:0;;;18326:21:1;18383:2;18363:18;;;18356:30;-1:-1:-1;;;18402:18:1;;;18395:43;18455:18;;57877:75:0;18142:337:1;57877:75:0;57982:10;57965:28;;;;:16;:28;;;;;;;;:39;;;;;;;;:46;;-1:-1:-1;;57965:46:0;58007:4;57965:46;;;58042:24;:14;5333;;5241:114;58042:24;58024:42;;58077:26;:14;5452:19;;5470:1;5452:19;;;5363:127;58077:26;58116:19;;;;:8;:19;;;;;;;;:36;;5452:19;;5470:1;5452:19;;;58177:27;;;:18;:27;;;;;:39;;;58227:18;:27;;;;;:39;;;58279:30;58289:10;58177:27;58279:9;:30::i;:::-;57376:941;;;;57304:1013;;;:::o;56639:441::-;46224:4;46248:16;;;:7;:16;;;;;;56704:13;;-1:-1:-1;;;;;46248:16:0;56730:76;;;;-1:-1:-1;;;56730:76:0;;16703:2:1;56730:76:0;;;16685:21:1;16742:2;16722:18;;;16715:30;16781:34;16761:18;;;16754:62;-1:-1:-1;;;16832:18:1;;;16825:45;16887:19;;56730:76:0;16501:411:1;56730:76:0;56819:17;56839:27;;;:18;:27;;;;;;;;;56899:18;:27;;;;;;56963:19;;;:8;:19;;;;;;:27;;56939:51;;56839:27;;56819:17;56939:51;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57034:7;57043:27;57060:9;57043:16;:27::i;:::-;57017:54;;;;;;;;;:::i;:::-;;;;;;;;;;;;;57003:69;;;;;56639:441;;;:::o;30558:149::-;29847:7;29874:12;;;:6;:12;;;;;:22;;;28224:30;28235:4;14147:10;28224;:30::i;:::-;30673:26:::1;30685:4;30691:7;30673:11;:26::i;56366:265::-:0;56428:4;56453:29;;;:18;:29;;;;;;;;:37;;:29;:37;56445:81;;;;-1:-1:-1;;;56445:81:0;;;;;;;:::i;:::-;-1:-1:-1;56577:19:0;;;;:8;:19;;;;;:36;;;5333:14;56544:29;;:79;;56366:265::o;58968:264::-;27778:4;28224:30;27778:4;14147:10;28224;:30::i;:::-;59100:29:::1;::::0;;;:18:::1;:29;::::0;;;;;::::1;;:37;;:29:::0;:37:::1;59092:81;;;;-1:-1:-1::0;;;59092:81:0::1;;;;;;;:::i;:::-;59184:19;::::0;;;:8:::1;:19;::::0;;;;:40:::1;::::0;:27:::1;;59214:10:::0;;59184:40:::1;:::i;59516:657::-:0;27778:4;28224:30;27778:4;14147:10;28224;:30::i;:::-;59649:17:::1;59669:26;:16;5333:14:::0;;5241:114;59669:26:::1;59716:29;::::0;;;:18:::1;:29;::::0;;;;;59649:46;;-1:-1:-1;59716:29:0::1;;:38;59708:87;;;::::0;-1:-1:-1;;;59708:87:0;;17521:2:1;59708:87:0::1;::::0;::::1;17503:21:1::0;17560:2;17540:18;;;17533:30;17599:34;17579:18;;;17572:62;-1:-1:-1;;;17650:18:1;;;17643:34;17694:19;;59708:87:0::1;17319:400:1::0;59708:87:0::1;59826:1;59814:9;:13;59806:59;;;::::0;-1:-1:-1;;;59806:59:0;;13868:2:1;59806:59:0::1;::::0;::::1;13850:21:1::0;13907:2;13887:18;;;13880:30;13946:34;13926:18;;;13919:62;-1:-1:-1;;;13997:18:1;;;13990:31;14038:19;;59806:59:0::1;13666:397:1::0;59806:59:0::1;59900:175;;;;;;;;59934:9;59900:175;;;;59970:10;59900:175;;;;60004:7;;59900:175;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;::::0;;;-1:-1:-1;59900:175:0;;;-1:-1:-1;;60044:19:0::1;::::0;;59900:175:::1;60044:19:::0;;::::1;::::0;;;;;59900:175;;::::1;::::0;59878:19;;;:8:::1;:19:::0;;;;;;:197;;;;;;::::1;::::0;::::1;::::0;::::1;::::0;;;::::1;::::0;;;:19;;:197:::1;::::0;::::1;::::0;::::1;::::0;-1:-1:-1;59878:197:0;::::1;::::0;::::1;:::i;:::-;-1:-1:-1::0;59878:197:0::1;::::0;;;::::1;::::0;;::::1;::::0;;::::1;::::0;::::1;60088:29:::0;;;:18:::1;:29;::::0;;;;:36;;-1:-1:-1;;60088:36:0::1;60120:4;60088:36;::::0;;60137:28:::1;:16;5452:19:::0;;5470:1;5452:19;;;5363:127;60137:28:::1;59638:535;59516:657:::0;;;;;:::o;28346:204::-;28431:4;-1:-1:-1;;;;;;28455:47:0;;-1:-1:-1;;;28455:47:0;;:87;;;28506:36;28530:11;28506:23;:36::i;50305:174::-;50380:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;50380:29:0;-1:-1:-1;;;;;50380:29:0;;;;;;;;:24;;50434:23;50380:24;50434:14;:23::i;:::-;-1:-1:-1;;;;;50425:46:0;;;;;;;;;;;50305:174;;:::o;6757:190::-;6882:4;6935;6906:25;6919:5;6926:4;6906:12;:25::i;:::-;:33;;6757:190;-1:-1:-1;;;;6757:190:0:o;46453:348::-;46546:4;46248:16;;;:7;:16;;;;;;-1:-1:-1;;;;;46248:16:0;46563:73;;;;-1:-1:-1;;;46563:73:0;;14270:2:1;46563:73:0;;;14252:21:1;14309:2;14289:18;;;14282:30;14348:34;14328:18;;;14321:62;-1:-1:-1;;;14399:18:1;;;14392:42;14451:19;;46563:73:0;14068:408:1;46563:73:0;46647:13;46663:23;46678:7;46663:14;:23::i;:::-;46647:39;;46716:5;-1:-1:-1;;;;;46705:16:0;:7;-1:-1:-1;;;;;46705:16:0;;:51;;;;46749:7;-1:-1:-1;;;;;46725:31:0;:20;46737:7;46725:11;:20::i;:::-;-1:-1:-1;;;;;46725:31:0;;46705:51;:87;;;-1:-1:-1;;;;;;43545:25:0;;;43521:4;43545:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;46760:32;43424:164;49562:625;49721:4;-1:-1:-1;;;;;49694:31:0;:23;49709:7;49694:14;:23::i;:::-;-1:-1:-1;;;;;49694:31:0;;49686:81;;;;-1:-1:-1;;;49686:81:0;;11278:2:1;49686:81:0;;;11260:21:1;11317:2;11297:18;;;11290:30;11356:34;11336:18;;;11329:62;-1:-1:-1;;;11407:18:1;;;11400:35;11452:19;;49686:81:0;11076:401:1;49686:81:0;-1:-1:-1;;;;;49786:16:0;;49778:65;;;;-1:-1:-1;;;49778:65:0;;12396:2:1;49778:65:0;;;12378:21:1;12435:2;12415:18;;;12408:30;12474:34;12454:18;;;12447:62;-1:-1:-1;;;12525:18:1;;;12518:34;12569:19;;49778:65:0;12194:400:1;49778:65:0;49960:29;49977:1;49981:7;49960:8;:29::i;:::-;-1:-1:-1;;;;;50002:15:0;;;;;;:9;:15;;;;;:20;;50021:1;;50002:15;:20;;50021:1;;50002:20;:::i;:::-;;;;-1:-1:-1;;;;;;;50033:13:0;;;;;;:9;:13;;;;;:18;;50050:1;;50033:13;:18;;50050:1;;50033:18;:::i;:::-;;;;-1:-1:-1;;50062:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;50062:21:0;-1:-1:-1;;;;;50062:21:0;;;;;;;;;50101:27;;50062:16;;50101:27;;;;;;;42498:341;42428:411;;:::o;29079:505::-;29168:22;29176:4;29182:7;29168;:22::i;:::-;29163:414;;29356:41;29384:7;-1:-1:-1;;;;;29356:41:0;29394:2;29356:19;:41::i;:::-;29470:38;29498:4;29505:2;29470:19;:38::i;:::-;29261:270;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;29261:270:0;;;;;;;;;;-1:-1:-1;;;29207:358:0;;;;;;;:::i;32715:238::-;32799:22;32807:4;32813:7;32799;:22::i;:::-;32794:152;;32838:12;;;;:6;:12;;;;;;;;-1:-1:-1;;;;;32838:29:0;;;;;;;;;:36;;-1:-1:-1;;32838:36:0;32870:4;32838:36;;;32921:12;14147:10;;14067:98;32921:12;-1:-1:-1;;;;;32894:40:0;32912:7;-1:-1:-1;;;;;32894:40:0;32906:4;32894:40;;;;;;;;;;32715:238;;:::o;33085:239::-;33169:22;33177:4;33183:7;33169;:22::i;:::-;33165:152;;;33240:5;33208:12;;;:6;:12;;;;;;;;-1:-1:-1;;;;;33208:29:0;;;;;;;;;;:37;;-1:-1:-1;;33208:37:0;;;33265:40;14147:10;;33208:12;;33265:40;;33240:5;33265:40;33085:239;;:::o;48805:420::-;48865:13;48881:23;48896:7;48881:14;:23::i;:::-;48865:39;;49006:29;49023:1;49027:7;49006:8;:29::i;:::-;-1:-1:-1;;;;;49048:16:0;;;;;;:9;:16;;;;;:21;;49068:1;;49048:16;:21;;49068:1;;49048:21;:::i;:::-;;;;-1:-1:-1;;49087:16:0;;;;:7;:16;;;;;;49080:23;;-1:-1:-1;;;;;;49080:23:0;;;49121:36;49095:7;;49087:16;-1:-1:-1;;;;;49121:36:0;;;;;49087:16;;49121:36;31214:218;;:::o;47143:110::-;47219:26;47229:2;47233:7;47219:26;;;;;;;;;;;;:9;:26::i;50621:315::-;50776:8;-1:-1:-1;;;;;50767:17:0;:5;-1:-1:-1;;;;;50767:17:0;;;50759:55;;;;-1:-1:-1;;;50759:55:0;;12801:2:1;50759:55:0;;;12783:21:1;12840:2;12820:18;;;12813:30;12879:27;12859:18;;;12852:55;12924:18;;50759:55:0;12599:349:1;50759:55:0;-1:-1:-1;;;;;50825:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;50825:46:0;;;;;;;;;;50887:41;;9838::1;;;50887::0;;9811:18:1;50887:41:0;;;;;;;50621:315;;;:::o;45531:::-;45688:28;45698:4;45704:2;45708:7;45688:9;:28::i;:::-;45735:48;45758:4;45764:2;45768:7;45777:5;45735:22;:48::i;:::-;45727:111;;;;-1:-1:-1;;;45727:111:0;;;;;;;:::i;11629:723::-;11685:13;11906:10;11902:53;;-1:-1:-1;;11933:10:0;;;;;;;;;;;;-1:-1:-1;;;11933:10:0;;;;;11629:723::o;11902:53::-;11980:5;11965:12;12021:78;12028:9;;12021:78;;12054:8;;;;:::i;:::-;;-1:-1:-1;12077:10:0;;-1:-1:-1;12085:2:0;12077:10;;:::i;:::-;;;12021:78;;;12109:19;12141:6;12131:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;12131:17:0;;12109:39;;12159:154;12166:10;;12159:154;;12193:11;12203:1;12193:11;;:::i;:::-;;-1:-1:-1;12262:10:0;12270:2;12262:5;:10;:::i;:::-;12249:24;;:2;:24;:::i;:::-;12236:39;;12219:6;12226;12219:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;12219:56:0;;;;;;;;-1:-1:-1;12290:11:0;12299:2;12290:11;;:::i;:::-;;;12159:154;;40401:305;40503:4;-1:-1:-1;;;;;;40540:40:0;;-1:-1:-1;;;40540:40:0;;:105;;-1:-1:-1;;;;;;;40597:48:0;;-1:-1:-1;;;40597:48:0;40540:105;:158;;;-1:-1:-1;;;;;;;;;;25706:40:0;;;40662:36;25597:157;7309:675;7392:7;7435:4;7392:7;7450:497;7474:5;:12;7470:1;:16;7450:497;;;7508:20;7531:5;7537:1;7531:8;;;;;;;;:::i;:::-;;;;;;;7508:31;;7574:12;7558;:28;7554:382;;8060:13;8110:15;;;8146:4;8139:15;;;8193:4;8177:21;;7686:57;;7554:382;;;8060:13;8110:15;;;8146:4;8139:15;;;8193:4;8177:21;;7863:57;;7554:382;-1:-1:-1;7488:3:0;;;;:::i;:::-;;;;7450:497;;;-1:-1:-1;7964:12:0;7309:675;-1:-1:-1;;;7309:675:0:o;12930:451::-;13005:13;13031:19;13063:10;13067:6;13063:1;:10;:::i;:::-;:14;;13076:1;13063:14;:::i;:::-;13053:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;13053:25:0;;13031:47;;-1:-1:-1;;;13089:6:0;13096:1;13089:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;13089:15:0;;;;;;;;;-1:-1:-1;;;13115:6:0;13122:1;13115:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;13115:15:0;;;;;;;;-1:-1:-1;13146:9:0;13158:10;13162:6;13158:1;:10;:::i;:::-;:14;;13171:1;13158:14;:::i;:::-;13146:26;;13141:135;13178:1;13174;:5;13141:135;;;-1:-1:-1;;;13226:5:0;13234:3;13226:11;13213:25;;;;;;;:::i;:::-;;;;13201:6;13208:1;13201:9;;;;;;;;:::i;:::-;;;;:37;-1:-1:-1;;;;;13201:37:0;;;;;;;;-1:-1:-1;13263:1:0;13253:11;;;;;13181:3;;;:::i;:::-;;;13141:135;;;-1:-1:-1;13294:10:0;;13286:55;;;;-1:-1:-1;;;13286:55:0;;10498:2:1;13286:55:0;;;10480:21:1;;;10517:18;;;10510:30;10576:34;10556:18;;;10549:62;10628:18;;13286:55:0;10296:356:1;13286:55:0;13366:6;12930:451;-1:-1:-1;;;12930:451:0:o;47480:321::-;47610:18;47616:2;47620:7;47610:5;:18::i;:::-;47661:54;47692:1;47696:2;47700:7;47709:5;47661:22;:54::i;:::-;47639:154;;;;-1:-1:-1;;;47639:154:0;;;;;;;:::i;51501:799::-;51656:4;-1:-1:-1;;;;;51677:13:0;;15809:19;:23;51673:620;;51713:72;;-1:-1:-1;;;51713:72:0;;-1:-1:-1;;;;;51713:36:0;;;;;:72;;14147:10;;51764:4;;51770:7;;51779:5;;51713:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;51713:72:0;;;;;;;;-1:-1:-1;;51713:72:0;;;;;;;;;;;;:::i;:::-;;;51709:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;51955:13:0;;51951:272;;51998:60;;-1:-1:-1;;;51998:60:0;;;;;;;:::i;51951:272::-;52173:6;52167:13;52158:6;52154:2;52150:15;52143:38;51709:529;-1:-1:-1;;;;;;51836:51:0;-1:-1:-1;;;51836:51:0;;-1:-1:-1;51829:58:0;;51673:620;-1:-1:-1;52277:4:0;52270:11;;48137:439;-1:-1:-1;;;;;48217:16:0;;48209:61;;;;-1:-1:-1;;;48209:61:0;;15929:2:1;48209:61:0;;;15911:21:1;;;15948:18;;;15941:30;16007:34;15987:18;;;15980:62;16059:18;;48209:61:0;15727:356:1;48209:61:0;46224:4;46248:16;;;:7;:16;;;;;;-1:-1:-1;;;;;46248:16:0;:30;48281:58;;;;-1:-1:-1;;;48281:58:0;;11684:2:1;48281:58:0;;;11666:21:1;11723:2;11703:18;;;11696:30;11762;11742:18;;;11735:58;11810:18;;48281:58:0;11482:352:1;48281:58:0;-1:-1:-1;;;;;48410:13:0;;;;;;:9;:13;;;;;:18;;48427:1;;48410:13;:18;;48427:1;;48410:18;:::i;:::-;;;;-1:-1:-1;;48439:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;48439:21:0;-1:-1:-1;;;;;48439:21:0;;;;;;;;48478:33;;48439:16;;;48478:33;;48439:16;;48478:33;31214:218;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:173:1;82:20;;-1:-1:-1;;;;;131:31:1;;121:42;;111:70;;177:1;174;167:12;111:70;14:173;;;:::o;192:367::-;255:8;265:6;319:3;312:4;304:6;300:17;296:27;286:55;;337:1;334;327:12;286:55;-1:-1:-1;360:20:1;;403:18;392:30;;389:50;;;435:1;432;425:12;389:50;472:4;464:6;460:17;448:29;;532:3;525:4;515:6;512:1;508:14;500:6;496:27;492:38;489:47;486:67;;;549:1;546;539:12;486:67;192:367;;;;;:::o;564:348::-;616:8;626:6;680:3;673:4;665:6;661:17;657:27;647:55;;698:1;695;688:12;647:55;-1:-1:-1;721:20:1;;764:18;753:30;;750:50;;;796:1;793;786:12;750:50;833:4;825:6;821:17;809:29;;885:3;878:4;869:6;861;857:19;853:30;850:39;847:59;;;902:1;899;892:12;917:186;976:6;1029:2;1017:9;1008:7;1004:23;1000:32;997:52;;;1045:1;1042;1035:12;997:52;1068:29;1087:9;1068:29;:::i;1108:260::-;1176:6;1184;1237:2;1225:9;1216:7;1212:23;1208:32;1205:52;;;1253:1;1250;1243:12;1205:52;1276:29;1295:9;1276:29;:::i;:::-;1266:39;;1324:38;1358:2;1347:9;1343:18;1324:38;:::i;:::-;1314:48;;1108:260;;;;;:::o;1373:328::-;1450:6;1458;1466;1519:2;1507:9;1498:7;1494:23;1490:32;1487:52;;;1535:1;1532;1525:12;1487:52;1558:29;1577:9;1558:29;:::i;:::-;1548:39;;1606:38;1640:2;1629:9;1625:18;1606:38;:::i;:::-;1596:48;;1691:2;1680:9;1676:18;1663:32;1653:42;;1373:328;;;;;:::o;1706:1138::-;1801:6;1809;1817;1825;1878:3;1866:9;1857:7;1853:23;1849:33;1846:53;;;1895:1;1892;1885:12;1846:53;1918:29;1937:9;1918:29;:::i;:::-;1908:39;;1966:38;2000:2;1989:9;1985:18;1966:38;:::i;:::-;1956:48;;2051:2;2040:9;2036:18;2023:32;2013:42;;2106:2;2095:9;2091:18;2078:32;2129:18;2170:2;2162:6;2159:14;2156:34;;;2186:1;2183;2176:12;2156:34;2224:6;2213:9;2209:22;2199:32;;2269:7;2262:4;2258:2;2254:13;2250:27;2240:55;;2291:1;2288;2281:12;2240:55;2327:2;2314:16;2349:2;2345;2342:10;2339:36;;;2355:18;;:::i;:::-;2430:2;2424:9;2398:2;2484:13;;-1:-1:-1;;2480:22:1;;;2504:2;2476:31;2472:40;2460:53;;;2528:18;;;2548:22;;;2525:46;2522:72;;;2574:18;;:::i;:::-;2614:10;2610:2;2603:22;2649:2;2641:6;2634:18;2689:7;2684:2;2679;2675;2671:11;2667:20;2664:33;2661:53;;;2710:1;2707;2700:12;2661:53;2766:2;2761;2757;2753:11;2748:2;2740:6;2736:15;2723:46;2811:1;2806:2;2801;2793:6;2789:15;2785:24;2778:35;2832:6;2822:16;;;;;;;1706:1138;;;;;;;:::o;2849:347::-;2914:6;2922;2975:2;2963:9;2954:7;2950:23;2946:32;2943:52;;;2991:1;2988;2981:12;2943:52;3014:29;3033:9;3014:29;:::i;:::-;3004:39;;3093:2;3082:9;3078:18;3065:32;3140:5;3133:13;3126:21;3119:5;3116:32;3106:60;;3162:1;3159;3152:12;3106:60;3185:5;3175:15;;;2849:347;;;;;:::o;3201:254::-;3269:6;3277;3330:2;3318:9;3309:7;3305:23;3301:32;3298:52;;;3346:1;3343;3336:12;3298:52;3369:29;3388:9;3369:29;:::i;:::-;3359:39;3445:2;3430:18;;;;3417:32;;-1:-1:-1;;;3201:254:1:o;3460:180::-;3519:6;3572:2;3560:9;3551:7;3547:23;3543:32;3540:52;;;3588:1;3585;3578:12;3540:52;-1:-1:-1;3611:23:1;;3460:180;-1:-1:-1;3460:180:1:o;3645:254::-;3713:6;3721;3774:2;3762:9;3753:7;3749:23;3745:32;3742:52;;;3790:1;3787;3780:12;3742:52;3826:9;3813:23;3803:33;;3855:38;3889:2;3878:9;3874:18;3855:38;:::i;3904:245::-;3962:6;4015:2;4003:9;3994:7;3990:23;3986:32;3983:52;;;4031:1;4028;4021:12;3983:52;4070:9;4057:23;4089:30;4113:5;4089:30;:::i;4154:249::-;4223:6;4276:2;4264:9;4255:7;4251:23;4247:32;4244:52;;;4292:1;4289;4282:12;4244:52;4324:9;4318:16;4343:30;4367:5;4343:30;:::i;4852:579::-;4956:6;4964;4972;4980;5033:2;5021:9;5012:7;5008:23;5004:32;5001:52;;;5049:1;5046;5039:12;5001:52;5085:9;5072:23;5062:33;;5114:38;5148:2;5137:9;5133:18;5114:38;:::i;:::-;5104:48;;5203:2;5192:9;5188:18;5175:32;5230:18;5222:6;5219:30;5216:50;;;5262:1;5259;5252:12;5216:50;5301:70;5363:7;5354:6;5343:9;5339:22;5301:70;:::i;:::-;4852:579;;;;-1:-1:-1;5390:8:1;-1:-1:-1;;;;4852:579:1:o;5436:505::-;5531:6;5539;5547;5600:2;5588:9;5579:7;5575:23;5571:32;5568:52;;;5616:1;5613;5606:12;5568:52;5652:9;5639:23;5629:33;;5713:2;5702:9;5698:18;5685:32;5740:18;5732:6;5729:30;5726:50;;;5772:1;5769;5762:12;5726:50;5811:70;5873:7;5864:6;5853:9;5849:22;5811:70;:::i;:::-;5436:505;;5900:8;;-1:-1:-1;5785:96:1;;-1:-1:-1;;;;5436:505:1:o;5946:248::-;6014:6;6022;6075:2;6063:9;6054:7;6050:23;6046:32;6043:52;;;6091:1;6088;6081:12;6043:52;-1:-1:-1;;6114:23:1;;;6184:2;6169:18;;;6156:32;;-1:-1:-1;5946:248:1:o;6199:547::-;6288:6;6296;6304;6312;6365:2;6353:9;6344:7;6340:23;6336:32;6333:52;;;6381:1;6378;6371:12;6333:52;6417:9;6404:23;6394:33;;6474:2;6463:9;6459:18;6446:32;6436:42;;6529:2;6518:9;6514:18;6501:32;6556:18;6548:6;6545:30;6542:50;;;6588:1;6585;6578:12;6542:50;6627:59;6678:7;6669:6;6658:9;6654:22;6627:59;:::i;6751:479::-;6831:6;6839;6847;6900:2;6888:9;6879:7;6875:23;6871:32;6868:52;;;6916:1;6913;6906:12;6868:52;6952:9;6939:23;6929:33;;7013:2;7002:9;6998:18;6985:32;7040:18;7032:6;7029:30;7026:50;;;7072:1;7069;7062:12;7026:50;7111:59;7162:7;7153:6;7142:9;7138:22;7111:59;:::i;7235:257::-;7276:3;7314:5;7308:12;7341:6;7336:3;7329:19;7357:63;7413:6;7406:4;7401:3;7397:14;7390:4;7383:5;7379:16;7357:63;:::i;:::-;7474:2;7453:15;-1:-1:-1;;7449:29:1;7440:39;;;;7481:4;7436:50;;7235:257;-1:-1:-1;;7235:257:1:o;7731:470::-;7910:3;7948:6;7942:13;7964:53;8010:6;8005:3;7998:4;7990:6;7986:17;7964:53;:::i;:::-;8080:13;;8039:16;;;;8102:57;8080:13;8039:16;8136:4;8124:17;;8102:57;:::i;:::-;8175:20;;7731:470;-1:-1:-1;;;;7731:470:1:o;8206:786::-;8617:25;8612:3;8605:38;8587:3;8672:6;8666:13;8688:62;8743:6;8738:2;8733:3;8729:12;8722:4;8714:6;8710:17;8688:62;:::i;:::-;-1:-1:-1;;;8809:2:1;8769:16;;;8801:11;;;8794:40;8859:13;;8881:63;8859:13;8930:2;8922:11;;8915:4;8903:17;;8881:63;:::i;:::-;8964:17;8983:2;8960:26;;8206:786;-1:-1:-1;;;;8206:786:1:o;9205:488::-;-1:-1:-1;;;;;9474:15:1;;;9456:34;;9526:15;;9521:2;9506:18;;9499:43;9573:2;9558:18;;9551:34;;;9621:3;9616:2;9601:18;;9594:31;;;9399:4;;9642:45;;9667:19;;9659:6;9642:45;:::i;:::-;9634:53;9205:488;-1:-1:-1;;;;;;9205:488:1:o;10072:219::-;10221:2;10210:9;10203:21;10184:4;10241:44;10281:2;10270:9;10266:18;10258:6;10241:44;:::i;10657:414::-;10859:2;10841:21;;;10898:2;10878:18;;;10871:30;10937:34;10932:2;10917:18;;10910:62;-1:-1:-1;;;11003:2:1;10988:18;;10981:48;11061:3;11046:19;;10657:414::o;17724:413::-;17926:2;17908:21;;;17965:2;17945:18;;;17938:30;18004:34;17999:2;17984:18;;17977:62;-1:-1:-1;;;18070:2:1;18055:18;;18048:47;18127:3;18112:19;;17724:413::o;18484:355::-;18686:2;18668:21;;;18725:2;18705:18;;;18698:30;18764:33;18759:2;18744:18;;18737:61;18830:2;18815:18;;18484:355::o;19859:485::-;20136:6;20125:9;20118:25;20179:6;20174:2;20163:9;20159:18;20152:34;20222:3;20217:2;20206:9;20202:18;20195:31;20099:4;20243:45;20283:3;20272:9;20268:19;20260:6;20243:45;:::i;:::-;20235:53;;20330:6;20324:13;20319:2;20308:9;20304:18;20297:41;19859:485;;;;;;;:::o;20349:128::-;20389:3;20420:1;20416:6;20413:1;20410:13;20407:39;;;20426:18;;:::i;:::-;-1:-1:-1;20462:9:1;;20349:128::o;20482:120::-;20522:1;20548;20538:35;;20553:18;;:::i;:::-;-1:-1:-1;20587:9:1;;20482:120::o;20607:168::-;20647:7;20713:1;20709;20705:6;20701:14;20698:1;20695:21;20690:1;20683:9;20676:17;20672:45;20669:71;;;20720:18;;:::i;:::-;-1:-1:-1;20760:9:1;;20607:168::o;20780:125::-;20820:4;20848:1;20845;20842:8;20839:34;;;20853:18;;:::i;:::-;-1:-1:-1;20890:9:1;;20780:125::o;20910:258::-;20982:1;20992:113;21006:6;21003:1;21000:13;20992:113;;;21082:11;;;21076:18;21063:11;;;21056:39;21028:2;21021:10;20992:113;;;21123:6;21120:1;21117:13;21114:48;;;-1:-1:-1;;21158:1:1;21140:16;;21133:27;20910:258::o;21173:136::-;21212:3;21240:5;21230:39;;21249:18;;:::i;:::-;-1:-1:-1;;;21285:18:1;;21173:136::o;21314:380::-;21393:1;21389:12;;;;21436;;;21457:61;;21511:4;21503:6;21499:17;21489:27;;21457:61;21564:2;21556:6;21553:14;21533:18;21530:38;21527:161;;;21610:10;21605:3;21601:20;21598:1;21591:31;21645:4;21642:1;21635:15;21673:4;21670:1;21663:15;21527:161;;21314:380;;;:::o;21699:135::-;21738:3;-1:-1:-1;;21759:17:1;;21756:43;;;21779:18;;:::i;:::-;-1:-1:-1;21826:1:1;21815:13;;21699:135::o;21839:112::-;21871:1;21897;21887:35;;21902:18;;:::i;:::-;-1:-1:-1;21936:9:1;;21839:112::o;21956:127::-;22017:10;22012:3;22008:20;22005:1;21998:31;22048:4;22045:1;22038:15;22072:4;22069:1;22062:15;22088:127;22149:10;22144:3;22140:20;22137:1;22130:31;22180:4;22177:1;22170:15;22204:4;22201:1;22194:15;22220:127;22281:10;22276:3;22272:20;22269:1;22262:31;22312:4;22309:1;22302:15;22336:4;22333:1;22326:15;22352:127;22413:10;22408:3;22404:20;22401:1;22394:31;22444:4;22441:1;22434:15;22468:4;22465:1;22458:15;22484:131;-1:-1:-1;;;;;;22558:32:1;;22548:43;;22538:71;;22605:1;22602;22595:12

Swarm Source

ipfs://7cd3bd63cc976f070ddbf081dc15584cfa7bfae281c930b245095d9b18995193
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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