ETH Price: $2,421.46 (+0.04%)
Gas: 1.08 Gwei

Token

JulienDurixBrushes (JDB)
 

Overview

Max Total Supply

318 JDB

Holders

115

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
Null: 0x000...000
Balance
0 JDB
0x0000000000000000000000000000000000000000
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:
LikeABrush

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-10-18
*/

// File: contracts/JulienDurix/brushes.sol

pragma solidity ^0.8.6;

abstract contract Brushes {
    function burn(uint256 tokenId)
        external
        virtual;

    function ownerOf(uint256 tokenId) public view virtual returns (address);
}
// 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/structs/EnumerableSet.sol


// OpenZeppelin Contracts (last updated v4.7.0) (utils/structs/EnumerableSet.sol)

pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 *
 * [WARNING]
 * ====
 *  Trying to delete such a structure from storage will likely result in data corruption, rendering the structure unusable.
 *  See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
 *
 *  In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an array of EnumerableSet.
 * ====
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;
        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping(bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) {
            // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            if (lastIndex != toDeleteIndex) {
                bytes32 lastValue = set._values[lastIndex];

                // Move the last value to the index where the value to delete is
                set._values[toDeleteIndex] = lastValue;
                // Update the index for the moved value
                set._indexes[lastValue] = valueIndex; // Replace lastValue's index to valueIndex
            }

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        return set._values[index];
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function _values(Set storage set) private view returns (bytes32[] memory) {
        return set._values;
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(Bytes32Set storage set) internal view returns (bytes32[] memory) {
        return _values(set._inner);
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(AddressSet storage set) internal view returns (address[] memory) {
        bytes32[] memory store = _values(set._inner);
        address[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

    /**
     * @dev Returns the value stored at position `index` in the set. O(1).
     *
     * Note that there are no guarantees on the ordering of values inside the
     * array, and it may change when more values are added or removed.
     *
     * Requirements:
     *
     * - `index` must be strictly less than {length}.
     */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }

    /**
     * @dev Return the entire set in an array
     *
     * WARNING: This operation will copy the entire storage to memory, which can be quite expensive. This is designed
     * to mostly be used by view accessors that are queried without any gas fees. Developers should keep in mind that
     * this function has an unbounded cost, and using it as part of a state-changing function may render the function
     * uncallable if the set grows to a point where copying to memory consumes too much gas to fit in a block.
     */
    function values(UintSet storage set) internal view returns (uint256[] memory) {
        bytes32[] memory store = _values(set._inner);
        uint256[] memory result;

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }
}

// 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/access/IAccessControlEnumerable.sol


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

pragma solidity ^0.8.0;


/**
 * @dev External interface of AccessControlEnumerable declared to support ERC165 detection.
 */
interface IAccessControlEnumerable is IAccessControl {
    /**
     * @dev Returns one of the accounts that have `role`. `index` must be a
     * value between 0 and {getRoleMemberCount}, non-inclusive.
     *
     * Role bearers are not sorted in any particular way, and their ordering may
     * change at any point.
     *
     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
     * you perform all queries on the same block. See the following
     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
     * for more information.
     */
    function getRoleMember(bytes32 role, uint256 index) external view returns (address);

    /**
     * @dev Returns the number of accounts that have `role`. Can be used
     * together with {getRoleMember} to enumerate all bearers of a role.
     */
    function getRoleMemberCount(bytes32 role) external view returns (uint256);
}

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


// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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


// OpenZeppelin Contracts (last updated v4.7.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
                /// @solidity memory-safe-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 (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721Receiver.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/token/ERC721/IERC721.sol


// OpenZeppelin Contracts (last updated v4.7.0) (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`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes calldata data
    ) external;

    /**
     * @dev 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 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 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 the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

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

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


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

pragma solidity ^0.8.0;


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

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

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

// File: @openzeppelin/contracts/token/ERC721/extensions/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/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/access/AccessControl.sol


// OpenZeppelin Contracts (last updated v4.7.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);
        _;
    }

    /**
     * @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 `_msgSender()` is missing `role`.
     * Overriding this function changes the behavior of the {onlyRole} modifier.
     *
     * Format of the revert message is described in {_checkRole}.
     *
     * _Available since v4.6._
     */
    function _checkRole(bytes32 role) internal view virtual {
        _checkRole(role, _msgSender());
    }

    /**
     * @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.
     *
     * May emit a {RoleGranted} event.
     */
    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.
     *
     * May emit a {RoleRevoked} event.
     */
    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`.
     *
     * May emit a {RoleRevoked} event.
     */
    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.
     *
     * May emit a {RoleGranted} event.
     *
     * [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.
     *
     * May emit a {RoleGranted} event.
     */
    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.
     *
     * May emit a {RoleRevoked} event.
     */
    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/access/AccessControlEnumerable.sol


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

pragma solidity ^0.8.0;




/**
 * @dev Extension of {AccessControl} that allows enumerating the members of each role.
 */
abstract contract AccessControlEnumerable is IAccessControlEnumerable, AccessControl {
    using EnumerableSet for EnumerableSet.AddressSet;

    mapping(bytes32 => EnumerableSet.AddressSet) private _roleMembers;

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

    /**
     * @dev Returns one of the accounts that have `role`. `index` must be a
     * value between 0 and {getRoleMemberCount}, non-inclusive.
     *
     * Role bearers are not sorted in any particular way, and their ordering may
     * change at any point.
     *
     * WARNING: When using {getRoleMember} and {getRoleMemberCount}, make sure
     * you perform all queries on the same block. See the following
     * https://forum.openzeppelin.com/t/iterating-over-elements-on-enumerableset-in-openzeppelin-contracts/2296[forum post]
     * for more information.
     */
    function getRoleMember(bytes32 role, uint256 index) public view virtual override returns (address) {
        return _roleMembers[role].at(index);
    }

    /**
     * @dev Returns the number of accounts that have `role`. Can be used
     * together with {getRoleMember} to enumerate all bearers of a role.
     */
    function getRoleMemberCount(bytes32 role) public view virtual override returns (uint256) {
        return _roleMembers[role].length();
    }

    /**
     * @dev Overload {_grantRole} to track enumerable memberships
     */
    function _grantRole(bytes32 role, address account) internal virtual override {
        super._grantRole(role, account);
        _roleMembers[role].add(account);
    }

    /**
     * @dev Overload {_revokeRole} to track enumerable memberships
     */
    function _revokeRole(bytes32 role, address account) internal virtual override {
        super._revokeRole(role, account);
        _roleMembers[role].remove(account);
    }
}

// File: @openzeppelin/contracts/security/Pausable.sol


// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)

pragma solidity ^0.8.0;


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

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

    bool private _paused;

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

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

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

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

    /**
     * @dev Throws if the contract is paused.
     */
    function _requireNotPaused() internal view virtual {
        require(!paused(), "Pausable: paused");
    }

    /**
     * @dev Throws if the contract is not paused.
     */
    function _requirePaused() internal view virtual {
        require(paused(), "Pausable: not paused");
    }

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

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

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


// OpenZeppelin Contracts (last updated v4.7.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: address zero is not a valid owner");
        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: invalid token ID");
        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) {
        _requireMinted(tokenId);

        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 overridden 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 token owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        _requireMinted(tokenId);

        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: caller is not token 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: caller is not token 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) {
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == 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 an {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 an {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 Reverts if the `tokenId` has not been minted yet.
     */
    function _requireMinted(uint256 tokenId) internal view virtual {
        require(_exists(tokenId), "ERC721: invalid token ID");
    }

    /**
     * @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 {
                    /// @solidity memory-safe-assembly
                    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/ERC721Pausable.sol


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

pragma solidity ^0.8.0;



/**
 * @dev ERC721 token with pausable token transfers, minting and burning.
 *
 * Useful for scenarios such as preventing trades until the end of an evaluation
 * period, or having an emergency switch for freezing all token transfers in the
 * event of a large bug.
 */
abstract contract ERC721Pausable is ERC721, Pausable {
    /**
     * @dev See {ERC721-_beforeTokenTransfer}.
     *
     * Requirements:
     *
     * - the contract must not be paused.
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, tokenId);

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

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


// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/extensions/ERC721Burnable.sol)

pragma solidity ^0.8.0;



/**
 * @title ERC721 Burnable Token
 * @dev ERC721 Token that can be 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), "ERC721: caller is not token owner nor approved");
        _burn(tokenId);
    }
}

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


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

pragma solidity ^0.8.0;



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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.0;








/**
 * @dev {ERC721} token, including:
 *
 *  - ability for holders to burn (destroy) their tokens
 *  - a minter role that allows for token minting (creation)
 *  - a pauser role that allows to stop all token transfers
 *  - token ID and URI autogeneration
 *
 * This contract uses {AccessControl} to lock permissioned functions using the
 * different roles - head to its documentation for details.
 *
 * The account that deploys the contract will be granted the minter and pauser
 * roles, as well as the default admin role, which will let it grant both minter
 * and pauser roles to other accounts.
 *
 * _Deprecated in favor of https://wizard.openzeppelin.com/[Contracts Wizard]._
 */
contract ERC721PresetMinterPauserAutoId is
    Context,
    AccessControlEnumerable,
    ERC721Enumerable,
    ERC721Burnable,
    ERC721Pausable
{
    using Counters for Counters.Counter;

    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");

    Counters.Counter private _tokenIdTracker;

    string private _baseTokenURI;

    /**
     * @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the
     * account that deploys the contract.
     *
     * Token URIs will be autogenerated based on `baseURI` and their token IDs.
     * See {ERC721-tokenURI}.
     */
    constructor(
        string memory name,
        string memory symbol,
        string memory baseTokenURI
    ) ERC721(name, symbol) {
        _baseTokenURI = baseTokenURI;

        _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());

        _setupRole(MINTER_ROLE, _msgSender());
        _setupRole(PAUSER_ROLE, _msgSender());
    }

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

    /**
     * @dev Creates a new token for `to`. Its token ID will be automatically
     * assigned (and available on the emitted {IERC721-Transfer} event), and the token
     * URI autogenerated based on the base URI passed at construction.
     *
     * See {ERC721-_mint}.
     *
     * Requirements:
     *
     * - the caller must have the `MINTER_ROLE`.
     */
    function mint(address to) public virtual {
        require(hasRole(MINTER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have minter role to mint");

        // We cannot just use balanceOf to create the new tokenId because tokens
        // can be burned (destroyed), so we need a separate counter.
        _mint(to, _tokenIdTracker.current());
        _tokenIdTracker.increment();
    }

    /**
     * @dev Pauses all token transfers.
     *
     * See {ERC721Pausable} and {Pausable-_pause}.
     *
     * Requirements:
     *
     * - the caller must have the `PAUSER_ROLE`.
     */
    function pause() public virtual {
        require(hasRole(PAUSER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have pauser role to pause");
        _pause();
    }

    /**
     * @dev Unpauses all token transfers.
     *
     * See {ERC721Pausable} and {Pausable-_unpause}.
     *
     * Requirements:
     *
     * - the caller must have the `PAUSER_ROLE`.
     */
    function unpause() public virtual {
        require(hasRole(PAUSER_ROLE, _msgSender()), "ERC721PresetMinterPauserAutoId: must have pauser role to unpause");
        _unpause();
    }

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual override(ERC721, ERC721Enumerable, ERC721Pausable) {
        super._beforeTokenTransfer(from, to, tokenId);
    }

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

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


// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;


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

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

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

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

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
    }

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

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

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

// File: contracts/JulienDurix/JulienDurixPostBurn.sol


pragma solidity ^0.8.7;




contract LikeABrush is ERC721PresetMinterPauserAutoId, Ownable {
    Brushes private immutable brushes;
    address public contract_unreveal = 0x6B6C66C7128f2585D8AAd8e4EFdaC33dD3c376cC;
    string public baseURI;
    string public baseURIHidden;
    bytes32 public constant ADMIN_ROLE = keccak256("ADMIN_ROLE");
    bool public revealed = false;


    constructor() ERC721PresetMinterPauserAutoId("JulienDurixBrushes", "JDB", "ipfs://") {
        brushes = Brushes(contract_unreveal);
        _setupRole(ADMIN_ROLE, msg.sender);
        _setupRole(MINTER_ROLE, msg.sender);
     }

    function JulienDurixReveal(uint256 tokenId, address to) payable public {
      require(
            brushes.ownerOf(tokenId) == msg.sender,
            "Must own the brush you're attempting to reveal"
        );
        _setupRole(MINTER_ROLE, msg.sender);
         brushes.burn(tokenId);
         super.mint(to);
        _revokeRole(MINTER_ROLE, msg.sender);
        
    }

    function _baseURI() internal view virtual override returns (string memory) {
        return baseURI;
    }
    
    function setNewbaseURI(string memory newBaseURI) public  returns (string memory) {
        require(hasRole(ADMIN_ROLE, _msgSender()), "NB1");
        baseURI = newBaseURI;
        return baseURI;
    }

    function setNewbaseHiddenURI(string memory newBaseURI) public  returns (string memory) {
        require(hasRole(ADMIN_ROLE, _msgSender()), "NBH");
        baseURIHidden = newBaseURI;
        return baseURIHidden;
    }

    function withdraw(address payable receiver) payable external  returns(bool success) {
        require(hasRole(ADMIN_ROLE, _msgSender()), "WT");
        receiver.transfer(address(this).balance);
        return true;
    }
  
    function adminMinting(address to) public {
        require(hasRole(ADMIN_ROLE, _msgSender()), "MT1");
        super.mint(to);
    }
       function flipReveal() external {
        require(hasRole(ADMIN_ROLE, _msgSender()), "FR");
        revealed = !revealed;
    }

    function tokenURI(uint256 tokenId) public view virtual override returns (string memory)
        {
            require(_exists(tokenId),"NET");
            if (!revealed) {return baseURIHidden;}
            return super.tokenURI(tokenId);
        }

    function setNewContractAdress(address contractAdress) public  returns (address) {
        require(hasRole(ADMIN_ROLE, _msgSender()), "NBH");
        contract_unreveal = contractAdress;
        return contract_unreveal;
    }    
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","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"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"to","type":"address"}],"name":"JulienDurixReveal","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"adminMinting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURIHidden","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contract_unreveal","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"flipReveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"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":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"address","name":"to","type":"address"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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":"address","name":"contractAdress","type":"address"}],"name":"setNewContractAdress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newBaseURI","type":"string"}],"name":"setNewbaseHiddenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newBaseURI","type":"string"}],"name":"setNewbaseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address payable","name":"receiver","type":"address"}],"name":"withdraw","outputs":[{"internalType":"bool","name":"success","type":"bool"}],"stateMutability":"payable","type":"function"}]

60a0604052601080546001600160a01b031916736b6c66c7128f2585d8aad8e4efdac33dd3c376cc1790556013805460ff191690553480156200004157600080fd5b50604051806040016040528060128152602001714a756c69656e44757269784272757368657360701b8152506040518060400160405280600381526020016225222160e91b81525060405180604001604052806007815260200166697066733a2f2f60c81b81525082828160029080519060200190620000c392919062000388565b508051620000d990600390602084019062000388565b5050600c805460ff19169055508051620000fb90600e90602084019062000388565b5062000109600033620001d1565b620001246000805160206200350c83398151915233620001d1565b620001507f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a33620001d1565b5050506200016d62000167620001cd60201b60201c565b620001e1565b60105460601b6001600160601b031916608052620001ac7fa49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c2177533620001d1565b620001c76000805160206200350c83398151915233620001d1565b6200046b565b3390565b620001dd828262000233565b5050565b600f80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6200024a82826200027660201b620016731760201c565b600082815260016020908152604090912062000271918390620016f762000316821b17901c565b505050565b6000828152602081815260408083206001600160a01b038516845290915290205460ff16620001dd576000828152602081815260408083206001600160a01b03851684529091529020805460ff19166001179055620002d23390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60006200032d836001600160a01b03841662000336565b90505b92915050565b60008181526001830160205260408120546200037f5750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915562000330565b50600062000330565b82805462000396906200042e565b90600052602060002090601f016020900481019282620003ba576000855562000405565b82601f10620003d557805160ff191683800117855562000405565b8280016001018555821562000405579182015b8281111562000405578251825591602001919060010190620003e8565b506200041392915062000417565b5090565b5b8082111562000413576000815560010162000418565b600181811c908216806200044357607f821691505b602082108114156200046557634e487b7160e01b600052602260045260246000fd5b50919050565b60805160601c61307b620004916000396000818161134d0152611462015261307b6000f3fe60806040526004361061027d5760003560e01c806370a082311161014f578063ba2e27b3116100c1578063d547741f1161007a578063d547741f14610744578063e343a00614610764578063e63ab1e914610784578063e985e9c5146107b8578063ec7fb1c014610801578063f2fde38b1461082157600080fd5b8063ba2e27b31461069a578063c7a85845146106af578063c87b56dd146106cf578063c91d96e6146106ef578063ca15c87314610702578063d53913931461072257600080fd5b80639010d07c116101135780639010d07c146105f057806391d148541461061057806395d89b4114610630578063a217fddf14610645578063a22cb4651461065a578063b88d4fde1461067a57600080fd5b806370a0823114610566578063715018a61461058657806375b238fc1461059b5780638456cb59146105bd5780638da5cb5b146105d257600080fd5b80633f4ba83a116101f35780635c975abb116101ac5780635c975abb146104b95780635ffa1432146104d1578063634bda7e146104f15780636352211e146105115780636a627842146105315780636c0360eb1461055157600080fd5b80633f4ba83a1461041757806342842e0e1461042c57806342966c681461044c5780634f6ccce71461046c578063518302271461048c57806351cff8d9146104a657600080fd5b806323b872dd1161024557806323b872dd14610352578063248a9ca3146103725780632f2ff15d146103a25780632f745c59146103c257806336568abe146103e25780633b84d9c61461040257600080fd5b806301ffc9a71461028257806306fdde03146102b7578063081812fc146102d9578063095ea7b31461031157806318160ddd14610333575b600080fd5b34801561028e57600080fd5b506102a261029d366004612c1a565b610841565b60405190151581526020015b60405180910390f35b3480156102c357600080fd5b506102cc610852565b6040516102ae9190612daa565b3480156102e557600080fd5b506102f96102f4366004612bba565b6108e4565b6040516001600160a01b0390911681526020016102ae565b34801561031d57600080fd5b5061033161032c366004612b8e565b61090b565b005b34801561033f57600080fd5b50600a545b6040519081526020016102ae565b34801561035e57600080fd5b5061033161036d366004612a9a565b610a26565b34801561037e57600080fd5b5061034461038d366004612bba565b60009081526020819052604090206001015490565b3480156103ae57600080fd5b506103316103bd366004612bd3565b610a58565b3480156103ce57600080fd5b506103446103dd366004612b8e565b610a7d565b3480156103ee57600080fd5b506103316103fd366004612bd3565b610b13565b34801561040e57600080fd5b50610331610b91565b34801561042357600080fd5b50610331610bee565b34801561043857600080fd5b50610331610447366004612a9a565b610c96565b34801561045857600080fd5b50610331610467366004612bba565b610cb1565b34801561047857600080fd5b50610344610487366004612bba565b610ce2565b34801561049857600080fd5b506013546102a29060ff1681565b6102a26104b4366004612a27565b610d75565b3480156104c557600080fd5b50600c5460ff166102a2565b3480156104dd57600080fd5b506010546102f9906001600160a01b031681565b3480156104fd57600080fd5b5061033161050c366004612a27565b610dfe565b34801561051d57600080fd5b506102f961052c366004612bba565b610e51565b34801561053d57600080fd5b5061033161054c366004612a27565b610eb1565b34801561055d57600080fd5b506102cc610f5b565b34801561057257600080fd5b50610344610581366004612a27565b610fe9565b34801561059257600080fd5b5061033161106f565b3480156105a757600080fd5b5061034460008051602061302683398151915281565b3480156105c957600080fd5b50610331611081565b3480156105de57600080fd5b50600f546001600160a01b03166102f9565b3480156105fc57600080fd5b506102f961060b366004612bf8565b611125565b34801561061c57600080fd5b506102a261062b366004612bd3565b611144565b34801561063c57600080fd5b506102cc61116d565b34801561065157600080fd5b50610344600081565b34801561066657600080fd5b50610331610675366004612b5b565b61117c565b34801561068657600080fd5b50610331610695366004612adb565b611187565b3480156106a657600080fd5b506102cc6111bf565b3480156106bb57600080fd5b506102f96106ca366004612a27565b6111cc565b3480156106db57600080fd5b506102cc6106ea366004612bba565b61123b565b6103316106fd366004612bd3565b61132d565b34801561070e57600080fd5b5061034461071d366004612bba565b6114e7565b34801561072e57600080fd5b5061034460008051602061300683398151915281565b34801561075057600080fd5b5061033161075f366004612bd3565b6114fe565b34801561077057600080fd5b506102cc61077f366004612c54565b611523565b34801561079057600080fd5b506103447f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b3480156107c457600080fd5b506102a26107d3366004612a61565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b34801561080d57600080fd5b506102cc61081c366004612c54565b611590565b34801561082d57600080fd5b5061033161083c366004612a27565b6115fd565b600061084c8261170c565b92915050565b60606002805461086190612f02565b80601f016020809104026020016040519081016040528092919081815260200182805461088d90612f02565b80156108da5780601f106108af576101008083540402835291602001916108da565b820191906000526020600020905b8154815290600101906020018083116108bd57829003601f168201915b5050505050905090565b60006108ef82611731565b506000908152600660205260409020546001600160a01b031690565b600061091682610e51565b9050806001600160a01b0316836001600160a01b031614156109895760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b03821614806109a557506109a581336107d3565b610a175760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c00006064820152608401610980565b610a218383611790565b505050565b610a31335b826117fe565b610a4d5760405162461bcd60e51b815260040161098090612e0f565b610a2183838361187d565b600082815260208190526040902060010154610a7381611a24565b610a218383611a2e565b6000610a8883610fe9565b8210610aea5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610980565b506001600160a01b03919091166000908152600860209081526040808320938352929052205490565b6001600160a01b0381163314610b835760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610980565b610b8d8282611a50565b5050565b610ba960008051602061302683398151915233611144565b610bda5760405162461bcd60e51b8152602060048201526002602482015261232960f11b6044820152606401610980565b6013805460ff19811660ff90911615179055565b610c187f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a33611144565b610c8c576040805162461bcd60e51b81526020600482015260248101919091527f4552433732315072657365744d696e7465725061757365724175746f49643a2060448201527f6d75737420686176652070617573657220726f6c6520746f20756e70617573656064820152608401610980565b610c94611a72565b565b610a2183838360405180602001604052806000815250611187565b610cba33610a2b565b610cd65760405162461bcd60e51b815260040161098090612e0f565b610cdf81611ac4565b50565b6000610ced600a5490565b8210610d505760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610980565b600a8281548110610d6357610d63612fae565b90600052602060002001549050919050565b6000610d8f60008051602061302683398151915233611144565b610dc05760405162461bcd60e51b815260206004820152600260248201526115d560f21b6044820152606401610980565b6040516001600160a01b038316904780156108fc02916000818181858888f19350505050158015610df5573d6000803e3d6000fd5b50600192915050565b610e1660008051602061302683398151915233611144565b610e485760405162461bcd60e51b81526020600482015260036024820152624d543160e81b6044820152606401610980565b610cdf81610eb1565b6000818152600460205260408120546001600160a01b03168061084c5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610980565b610ec960008051602061300683398151915233611144565b610f3b5760405162461bcd60e51b815260206004820152603d60248201527f4552433732315072657365744d696e7465725061757365724175746f49643a2060448201527f6d7573742068617665206d696e74657220726f6c6520746f206d696e740000006064820152608401610980565b610f4d81610f48600d5490565b611b6b565b610cdf600d80546001019055565b60118054610f6890612f02565b80601f0160208091040260200160405190810160405280929190818152602001828054610f9490612f02565b8015610fe15780601f10610fb657610100808354040283529160200191610fe1565b820191906000526020600020905b815481529060010190602001808311610fc457829003601f168201915b505050505081565b60006001600160a01b0382166110535760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610980565b506001600160a01b031660009081526005602052604090205490565b611077611cb9565b610c946000611d13565b6110ab7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a33611144565b61111d5760405162461bcd60e51b815260206004820152603e60248201527f4552433732315072657365744d696e7465725061757365724175746f49643a2060448201527f6d75737420686176652070617573657220726f6c6520746f20706175736500006064820152608401610980565b610c94611d65565b600082815260016020526040812061113d9083611da2565b9392505050565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b60606003805461086190612f02565b610b8d338383611dae565b61119133836117fe565b6111ad5760405162461bcd60e51b815260040161098090612e0f565b6111b984848484611e7d565b50505050565b60128054610f6890612f02565b60006111e660008051602061302683398151915233611144565b6112185760405162461bcd60e51b815260206004820152600360248201526209c84960eb1b6044820152606401610980565b50601080546001600160a01b039092166001600160a01b03199092168217905590565b6000818152600460205260409020546060906001600160a01b03166112885760405162461bcd60e51b815260206004820152600360248201526213915560ea1b6044820152606401610980565b60135460ff16611324576012805461129f90612f02565b80601f01602080910402602001604051908101604052809291908181526020018280546112cb90612f02565b80156113185780601f106112ed57610100808354040283529160200191611318565b820191906000526020600020905b8154815290600101906020018083116112fb57829003601f168201915b50505050509050919050565b61084c82611eb0565b6040516331a9108f60e11b81526004810183905233906001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001690636352211e9060240160206040518083038186803b15801561138f57600080fd5b505afa1580156113a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c79190612a44565b6001600160a01b0316146114345760405162461bcd60e51b815260206004820152602e60248201527f4d757374206f776e2074686520627275736820796f7527726520617474656d7060448201526d1d1a5b99c81d1bc81c995d99585b60921b6064820152608401610980565b61144c60008051602061300683398151915233611f16565b604051630852cd8d60e31b8152600481018390527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906342966c6890602401600060405180830381600087803b1580156114ae57600080fd5b505af11580156114c2573d6000803e3d6000fd5b505050506114cf81610eb1565b610b8d60008051602061300683398151915233611a50565b600081815260016020526040812061084c90611f20565b60008281526020819052604090206001015461151981611a24565b610a218383611a50565b606061153d60008051602061302683398151915233611144565b61156f5760405162461bcd60e51b81526020600482015260036024820152624e423160e81b6044820152606401610980565b8151611582906011906020850190612918565b506011805461129f90612f02565b60606115aa60008051602061302683398151915233611144565b6115dc5760405162461bcd60e51b815260206004820152600360248201526209c84960eb1b6044820152606401610980565b81516115ef906012906020850190612918565b506012805461129f90612f02565b611605611cb9565b6001600160a01b03811661166a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610980565b610cdf81611d13565b61167d8282611144565b610b8d576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556116b33390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600061113d836001600160a01b038416611f2a565b60006001600160e01b0319821663780e9d6360e01b148061084c575061084c82611f79565b6000818152600460205260409020546001600160a01b0316610cdf5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610980565b600081815260066020526040902080546001600160a01b0319166001600160a01b03841690811790915581906117c582610e51565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061180a83610e51565b9050806001600160a01b0316846001600160a01b0316148061185157506001600160a01b0380821660009081526007602090815260408083209388168352929052205460ff165b806118755750836001600160a01b031661186a846108e4565b6001600160a01b0316145b949350505050565b826001600160a01b031661189082610e51565b6001600160a01b0316146118f45760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610980565b6001600160a01b0382166119565760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610980565b611961838383611fb9565b61196c600082611790565b6001600160a01b0383166000908152600560205260408120805460019290611995908490612ea8565b90915550506001600160a01b03821660009081526005602052604081208054600192906119c3908490612e5d565b909155505060008181526004602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b610cdf8133611fc4565b611a388282611673565b6000828152600160205260409020610a2190826116f7565b611a5a8282612028565b6000828152600160205260409020610a21908261208d565b611a7a6120a2565b600c805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6000611acf82610e51565b9050611add81600084611fb9565b611ae8600083611790565b6001600160a01b0381166000908152600560205260408120805460019290611b11908490612ea8565b909155505060008281526004602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6001600160a01b038216611bc15760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610980565b6000818152600460205260409020546001600160a01b031615611c265760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610980565b611c3260008383611fb9565b6001600160a01b0382166000908152600560205260408120805460019290611c5b908490612e5d565b909155505060008181526004602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600f546001600160a01b03163314610c945760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610980565b600f80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b611d6d6120eb565b600c805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611aa73390565b600061113d8383612131565b816001600160a01b0316836001600160a01b03161415611e105760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610980565b6001600160a01b03838116600081815260076020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611e8884848461187d565b611e948484848461215b565b6111b95760405162461bcd60e51b815260040161098090612dbd565b6060611ebb82611731565b6000611ec5612268565b90506000815111611ee5576040518060200160405280600081525061113d565b80611eef84612277565b604051602001611f00929190612cc9565b6040516020818303038152906040529392505050565b610b8d8282611a2e565b600061084c825490565b6000818152600183016020526040812054611f715750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561084c565b50600061084c565b60006001600160e01b031982166380ac58cd60e01b1480611faa57506001600160e01b03198216635b5e139f60e01b145b8061084c575061084c82612375565b610a2183838361239a565b611fce8282611144565b610b8d57611fe6816001600160a01b0316601461240c565b611ff183602061240c565b604051602001612002929190612cf8565b60408051601f198184030181529082905262461bcd60e51b825261098091600401612daa565b6120328282611144565b15610b8d576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b600061113d836001600160a01b0384166125a8565b600c5460ff16610c945760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610980565b600c5460ff1615610c945760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610980565b600082600001828154811061214857612148612fae565b9060005260206000200154905092915050565b60006001600160a01b0384163b1561225d57604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061219f903390899088908890600401612d6d565b602060405180830381600087803b1580156121b957600080fd5b505af19250505080156121e9575060408051601f3d908101601f191682019092526121e691810190612c37565b60015b612243573d808015612217576040519150601f19603f3d011682016040523d82523d6000602084013e61221c565b606091505b50805161223b5760405162461bcd60e51b815260040161098090612dbd565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611875565b506001949350505050565b60606011805461086190612f02565b60608161229b5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156122c557806122af81612f3d565b91506122be9050600a83612e75565b915061229f565b60008167ffffffffffffffff8111156122e0576122e0612fc4565b6040519080825280601f01601f19166020018201604052801561230a576020820181803683370190505b5090505b84156118755761231f600183612ea8565b915061232c600a86612f58565b612337906030612e5d565b60f81b81838151811061234c5761234c612fae565b60200101906001600160f81b031916908160001a90535061236e600a86612e75565b945061230e565b60006001600160e01b03198216635a05180f60e01b148061084c575061084c8261269b565b6123a58383836126d0565b600c5460ff1615610a215760405162461bcd60e51b815260206004820152602b60248201527f4552433732315061757361626c653a20746f6b656e207472616e73666572207760448201526a1a1a5b19481c185d5cd95960aa1b6064820152608401610980565b6060600061241b836002612e89565b612426906002612e5d565b67ffffffffffffffff81111561243e5761243e612fc4565b6040519080825280601f01601f191660200182016040528015612468576020820181803683370190505b509050600360fc1b8160008151811061248357612483612fae565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106124b2576124b2612fae565b60200101906001600160f81b031916908160001a90535060006124d6846002612e89565b6124e1906001612e5d565b90505b6001811115612559576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061251557612515612fae565b1a60f81b82828151811061252b5761252b612fae565b60200101906001600160f81b031916908160001a90535060049490941c9361255281612eeb565b90506124e4565b50831561113d5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610980565b600081815260018301602052604081205480156126915760006125cc600183612ea8565b85549091506000906125e090600190612ea8565b905081811461264557600086600001828154811061260057612600612fae565b906000526020600020015490508087600001848154811061262357612623612fae565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061265657612656612f98565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061084c565b600091505061084c565b60006001600160e01b03198216637965db0b60e01b148061084c57506301ffc9a760e01b6001600160e01b031983161461084c565b6001600160a01b03831661272b5761272681600a80546000838152600b60205260408120829055600182018355919091527fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a80155565b61274e565b816001600160a01b0316836001600160a01b03161461274e5761274e8382612788565b6001600160a01b03821661276557610a2181612825565b826001600160a01b0316826001600160a01b031614610a2157610a2182826128d4565b6000600161279584610fe9565b61279f9190612ea8565b6000838152600960205260409020549091508082146127f2576001600160a01b03841660009081526008602090815260408083208584528252808320548484528184208190558352600990915290208190555b5060009182526009602090815260408084208490556001600160a01b039094168352600881528383209183525290812055565b600a5460009061283790600190612ea8565b6000838152600b6020526040812054600a805493945090928490811061285f5761285f612fae565b9060005260206000200154905080600a838154811061288057612880612fae565b6000918252602080832090910192909255828152600b9091526040808220849055858252812055600a8054806128b8576128b8612f98565b6001900381819060005260206000200160009055905550505050565b60006128df83610fe9565b6001600160a01b039093166000908152600860209081526040808320868452825280832085905593825260099052919091209190915550565b82805461292490612f02565b90600052602060002090601f016020900481019282612946576000855561298c565b82601f1061295f57805160ff191683800117855561298c565b8280016001018555821561298c579182015b8281111561298c578251825591602001919060010190612971565b5061299892915061299c565b5090565b5b80821115612998576000815560010161299d565b600067ffffffffffffffff808411156129cc576129cc612fc4565b604051601f8501601f19908116603f011681019082821181831017156129f4576129f4612fc4565b81604052809350858152868686011115612a0d57600080fd5b858560208301376000602087830101525050509392505050565b600060208284031215612a3957600080fd5b813561113d81612fda565b600060208284031215612a5657600080fd5b815161113d81612fda565b60008060408385031215612a7457600080fd5b8235612a7f81612fda565b91506020830135612a8f81612fda565b809150509250929050565b600080600060608486031215612aaf57600080fd5b8335612aba81612fda565b92506020840135612aca81612fda565b929592945050506040919091013590565b60008060008060808587031215612af157600080fd5b8435612afc81612fda565b93506020850135612b0c81612fda565b925060408501359150606085013567ffffffffffffffff811115612b2f57600080fd5b8501601f81018713612b4057600080fd5b612b4f878235602084016129b1565b91505092959194509250565b60008060408385031215612b6e57600080fd5b8235612b7981612fda565b915060208301358015158114612a8f57600080fd5b60008060408385031215612ba157600080fd5b8235612bac81612fda565b946020939093013593505050565b600060208284031215612bcc57600080fd5b5035919050565b60008060408385031215612be657600080fd5b823591506020830135612a8f81612fda565b60008060408385031215612c0b57600080fd5b50508035926020909101359150565b600060208284031215612c2c57600080fd5b813561113d81612fef565b600060208284031215612c4957600080fd5b815161113d81612fef565b600060208284031215612c6657600080fd5b813567ffffffffffffffff811115612c7d57600080fd5b8201601f81018413612c8e57600080fd5b611875848235602084016129b1565b60008151808452612cb5816020860160208601612ebf565b601f01601f19169290920160200192915050565b60008351612cdb818460208801612ebf565b835190830190612cef818360208801612ebf565b01949350505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351612d30816017850160208801612ebf565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351612d61816028840160208801612ebf565b01602801949350505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612da090830184612c9d565b9695505050505050565b60208152600061113d6020830184612c9d565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b60008219821115612e7057612e70612f6c565b500190565b600082612e8457612e84612f82565b500490565b6000816000190483118215151615612ea357612ea3612f6c565b500290565b600082821015612eba57612eba612f6c565b500390565b60005b83811015612eda578181015183820152602001612ec2565b838111156111b95750506000910152565b600081612efa57612efa612f6c565b506000190190565b600181811c90821680612f1657607f821691505b60208210811415612f3757634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415612f5157612f51612f6c565b5060010190565b600082612f6757612f67612f82565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610cdf57600080fd5b6001600160e01b031981168114610cdf57600080fdfe9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6a49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775a2646970667358221220bef4be0f931f69e68de752cd68ec598801450082600432dbd33f4f511b2fa79a64736f6c634300080700339f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6

Deployed Bytecode

0x60806040526004361061027d5760003560e01c806370a082311161014f578063ba2e27b3116100c1578063d547741f1161007a578063d547741f14610744578063e343a00614610764578063e63ab1e914610784578063e985e9c5146107b8578063ec7fb1c014610801578063f2fde38b1461082157600080fd5b8063ba2e27b31461069a578063c7a85845146106af578063c87b56dd146106cf578063c91d96e6146106ef578063ca15c87314610702578063d53913931461072257600080fd5b80639010d07c116101135780639010d07c146105f057806391d148541461061057806395d89b4114610630578063a217fddf14610645578063a22cb4651461065a578063b88d4fde1461067a57600080fd5b806370a0823114610566578063715018a61461058657806375b238fc1461059b5780638456cb59146105bd5780638da5cb5b146105d257600080fd5b80633f4ba83a116101f35780635c975abb116101ac5780635c975abb146104b95780635ffa1432146104d1578063634bda7e146104f15780636352211e146105115780636a627842146105315780636c0360eb1461055157600080fd5b80633f4ba83a1461041757806342842e0e1461042c57806342966c681461044c5780634f6ccce71461046c578063518302271461048c57806351cff8d9146104a657600080fd5b806323b872dd1161024557806323b872dd14610352578063248a9ca3146103725780632f2ff15d146103a25780632f745c59146103c257806336568abe146103e25780633b84d9c61461040257600080fd5b806301ffc9a71461028257806306fdde03146102b7578063081812fc146102d9578063095ea7b31461031157806318160ddd14610333575b600080fd5b34801561028e57600080fd5b506102a261029d366004612c1a565b610841565b60405190151581526020015b60405180910390f35b3480156102c357600080fd5b506102cc610852565b6040516102ae9190612daa565b3480156102e557600080fd5b506102f96102f4366004612bba565b6108e4565b6040516001600160a01b0390911681526020016102ae565b34801561031d57600080fd5b5061033161032c366004612b8e565b61090b565b005b34801561033f57600080fd5b50600a545b6040519081526020016102ae565b34801561035e57600080fd5b5061033161036d366004612a9a565b610a26565b34801561037e57600080fd5b5061034461038d366004612bba565b60009081526020819052604090206001015490565b3480156103ae57600080fd5b506103316103bd366004612bd3565b610a58565b3480156103ce57600080fd5b506103446103dd366004612b8e565b610a7d565b3480156103ee57600080fd5b506103316103fd366004612bd3565b610b13565b34801561040e57600080fd5b50610331610b91565b34801561042357600080fd5b50610331610bee565b34801561043857600080fd5b50610331610447366004612a9a565b610c96565b34801561045857600080fd5b50610331610467366004612bba565b610cb1565b34801561047857600080fd5b50610344610487366004612bba565b610ce2565b34801561049857600080fd5b506013546102a29060ff1681565b6102a26104b4366004612a27565b610d75565b3480156104c557600080fd5b50600c5460ff166102a2565b3480156104dd57600080fd5b506010546102f9906001600160a01b031681565b3480156104fd57600080fd5b5061033161050c366004612a27565b610dfe565b34801561051d57600080fd5b506102f961052c366004612bba565b610e51565b34801561053d57600080fd5b5061033161054c366004612a27565b610eb1565b34801561055d57600080fd5b506102cc610f5b565b34801561057257600080fd5b50610344610581366004612a27565b610fe9565b34801561059257600080fd5b5061033161106f565b3480156105a757600080fd5b5061034460008051602061302683398151915281565b3480156105c957600080fd5b50610331611081565b3480156105de57600080fd5b50600f546001600160a01b03166102f9565b3480156105fc57600080fd5b506102f961060b366004612bf8565b611125565b34801561061c57600080fd5b506102a261062b366004612bd3565b611144565b34801561063c57600080fd5b506102cc61116d565b34801561065157600080fd5b50610344600081565b34801561066657600080fd5b50610331610675366004612b5b565b61117c565b34801561068657600080fd5b50610331610695366004612adb565b611187565b3480156106a657600080fd5b506102cc6111bf565b3480156106bb57600080fd5b506102f96106ca366004612a27565b6111cc565b3480156106db57600080fd5b506102cc6106ea366004612bba565b61123b565b6103316106fd366004612bd3565b61132d565b34801561070e57600080fd5b5061034461071d366004612bba565b6114e7565b34801561072e57600080fd5b5061034460008051602061300683398151915281565b34801561075057600080fd5b5061033161075f366004612bd3565b6114fe565b34801561077057600080fd5b506102cc61077f366004612c54565b611523565b34801561079057600080fd5b506103447f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b3480156107c457600080fd5b506102a26107d3366004612a61565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b34801561080d57600080fd5b506102cc61081c366004612c54565b611590565b34801561082d57600080fd5b5061033161083c366004612a27565b6115fd565b600061084c8261170c565b92915050565b60606002805461086190612f02565b80601f016020809104026020016040519081016040528092919081815260200182805461088d90612f02565b80156108da5780601f106108af576101008083540402835291602001916108da565b820191906000526020600020905b8154815290600101906020018083116108bd57829003601f168201915b5050505050905090565b60006108ef82611731565b506000908152600660205260409020546001600160a01b031690565b600061091682610e51565b9050806001600160a01b0316836001600160a01b031614156109895760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b03821614806109a557506109a581336107d3565b610a175760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c00006064820152608401610980565b610a218383611790565b505050565b610a31335b826117fe565b610a4d5760405162461bcd60e51b815260040161098090612e0f565b610a2183838361187d565b600082815260208190526040902060010154610a7381611a24565b610a218383611a2e565b6000610a8883610fe9565b8210610aea5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610980565b506001600160a01b03919091166000908152600860209081526040808320938352929052205490565b6001600160a01b0381163314610b835760405162461bcd60e51b815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201526e103937b632b9903337b91039b2b63360891b6064820152608401610980565b610b8d8282611a50565b5050565b610ba960008051602061302683398151915233611144565b610bda5760405162461bcd60e51b8152602060048201526002602482015261232960f11b6044820152606401610980565b6013805460ff19811660ff90911615179055565b610c187f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a33611144565b610c8c576040805162461bcd60e51b81526020600482015260248101919091527f4552433732315072657365744d696e7465725061757365724175746f49643a2060448201527f6d75737420686176652070617573657220726f6c6520746f20756e70617573656064820152608401610980565b610c94611a72565b565b610a2183838360405180602001604052806000815250611187565b610cba33610a2b565b610cd65760405162461bcd60e51b815260040161098090612e0f565b610cdf81611ac4565b50565b6000610ced600a5490565b8210610d505760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610980565b600a8281548110610d6357610d63612fae565b90600052602060002001549050919050565b6000610d8f60008051602061302683398151915233611144565b610dc05760405162461bcd60e51b815260206004820152600260248201526115d560f21b6044820152606401610980565b6040516001600160a01b038316904780156108fc02916000818181858888f19350505050158015610df5573d6000803e3d6000fd5b50600192915050565b610e1660008051602061302683398151915233611144565b610e485760405162461bcd60e51b81526020600482015260036024820152624d543160e81b6044820152606401610980565b610cdf81610eb1565b6000818152600460205260408120546001600160a01b03168061084c5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610980565b610ec960008051602061300683398151915233611144565b610f3b5760405162461bcd60e51b815260206004820152603d60248201527f4552433732315072657365744d696e7465725061757365724175746f49643a2060448201527f6d7573742068617665206d696e74657220726f6c6520746f206d696e740000006064820152608401610980565b610f4d81610f48600d5490565b611b6b565b610cdf600d80546001019055565b60118054610f6890612f02565b80601f0160208091040260200160405190810160405280929190818152602001828054610f9490612f02565b8015610fe15780601f10610fb657610100808354040283529160200191610fe1565b820191906000526020600020905b815481529060010190602001808311610fc457829003601f168201915b505050505081565b60006001600160a01b0382166110535760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610980565b506001600160a01b031660009081526005602052604090205490565b611077611cb9565b610c946000611d13565b6110ab7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a33611144565b61111d5760405162461bcd60e51b815260206004820152603e60248201527f4552433732315072657365744d696e7465725061757365724175746f49643a2060448201527f6d75737420686176652070617573657220726f6c6520746f20706175736500006064820152608401610980565b610c94611d65565b600082815260016020526040812061113d9083611da2565b9392505050565b6000918252602082815260408084206001600160a01b0393909316845291905290205460ff1690565b60606003805461086190612f02565b610b8d338383611dae565b61119133836117fe565b6111ad5760405162461bcd60e51b815260040161098090612e0f565b6111b984848484611e7d565b50505050565b60128054610f6890612f02565b60006111e660008051602061302683398151915233611144565b6112185760405162461bcd60e51b815260206004820152600360248201526209c84960eb1b6044820152606401610980565b50601080546001600160a01b039092166001600160a01b03199092168217905590565b6000818152600460205260409020546060906001600160a01b03166112885760405162461bcd60e51b815260206004820152600360248201526213915560ea1b6044820152606401610980565b60135460ff16611324576012805461129f90612f02565b80601f01602080910402602001604051908101604052809291908181526020018280546112cb90612f02565b80156113185780601f106112ed57610100808354040283529160200191611318565b820191906000526020600020905b8154815290600101906020018083116112fb57829003601f168201915b50505050509050919050565b61084c82611eb0565b6040516331a9108f60e11b81526004810183905233906001600160a01b037f0000000000000000000000006b6c66c7128f2585d8aad8e4efdac33dd3c376cc1690636352211e9060240160206040518083038186803b15801561138f57600080fd5b505afa1580156113a3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906113c79190612a44565b6001600160a01b0316146114345760405162461bcd60e51b815260206004820152602e60248201527f4d757374206f776e2074686520627275736820796f7527726520617474656d7060448201526d1d1a5b99c81d1bc81c995d99585b60921b6064820152608401610980565b61144c60008051602061300683398151915233611f16565b604051630852cd8d60e31b8152600481018390527f0000000000000000000000006b6c66c7128f2585d8aad8e4efdac33dd3c376cc6001600160a01b0316906342966c6890602401600060405180830381600087803b1580156114ae57600080fd5b505af11580156114c2573d6000803e3d6000fd5b505050506114cf81610eb1565b610b8d60008051602061300683398151915233611a50565b600081815260016020526040812061084c90611f20565b60008281526020819052604090206001015461151981611a24565b610a218383611a50565b606061153d60008051602061302683398151915233611144565b61156f5760405162461bcd60e51b81526020600482015260036024820152624e423160e81b6044820152606401610980565b8151611582906011906020850190612918565b506011805461129f90612f02565b60606115aa60008051602061302683398151915233611144565b6115dc5760405162461bcd60e51b815260206004820152600360248201526209c84960eb1b6044820152606401610980565b81516115ef906012906020850190612918565b506012805461129f90612f02565b611605611cb9565b6001600160a01b03811661166a5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610980565b610cdf81611d13565b61167d8282611144565b610b8d576000828152602081815260408083206001600160a01b03851684529091529020805460ff191660011790556116b33390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b600061113d836001600160a01b038416611f2a565b60006001600160e01b0319821663780e9d6360e01b148061084c575061084c82611f79565b6000818152600460205260409020546001600160a01b0316610cdf5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b6044820152606401610980565b600081815260066020526040902080546001600160a01b0319166001600160a01b03841690811790915581906117c582610e51565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061180a83610e51565b9050806001600160a01b0316846001600160a01b0316148061185157506001600160a01b0380821660009081526007602090815260408083209388168352929052205460ff165b806118755750836001600160a01b031661186a846108e4565b6001600160a01b0316145b949350505050565b826001600160a01b031661189082610e51565b6001600160a01b0316146118f45760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610980565b6001600160a01b0382166119565760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610980565b611961838383611fb9565b61196c600082611790565b6001600160a01b0383166000908152600560205260408120805460019290611995908490612ea8565b90915550506001600160a01b03821660009081526005602052604081208054600192906119c3908490612e5d565b909155505060008181526004602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b610cdf8133611fc4565b611a388282611673565b6000828152600160205260409020610a2190826116f7565b611a5a8282612028565b6000828152600160205260409020610a21908261208d565b611a7a6120a2565b600c805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b6000611acf82610e51565b9050611add81600084611fb9565b611ae8600083611790565b6001600160a01b0381166000908152600560205260408120805460019290611b11908490612ea8565b909155505060008281526004602052604080822080546001600160a01b0319169055518391906001600160a01b038416907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908390a45050565b6001600160a01b038216611bc15760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610980565b6000818152600460205260409020546001600160a01b031615611c265760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610980565b611c3260008383611fb9565b6001600160a01b0382166000908152600560205260408120805460019290611c5b908490612e5d565b909155505060008181526004602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600f546001600160a01b03163314610c945760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610980565b600f80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b611d6d6120eb565b600c805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611aa73390565b600061113d8383612131565b816001600160a01b0316836001600160a01b03161415611e105760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610980565b6001600160a01b03838116600081815260076020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611e8884848461187d565b611e948484848461215b565b6111b95760405162461bcd60e51b815260040161098090612dbd565b6060611ebb82611731565b6000611ec5612268565b90506000815111611ee5576040518060200160405280600081525061113d565b80611eef84612277565b604051602001611f00929190612cc9565b6040516020818303038152906040529392505050565b610b8d8282611a2e565b600061084c825490565b6000818152600183016020526040812054611f715750815460018181018455600084815260208082209093018490558454848252828601909352604090209190915561084c565b50600061084c565b60006001600160e01b031982166380ac58cd60e01b1480611faa57506001600160e01b03198216635b5e139f60e01b145b8061084c575061084c82612375565b610a2183838361239a565b611fce8282611144565b610b8d57611fe6816001600160a01b0316601461240c565b611ff183602061240c565b604051602001612002929190612cf8565b60408051601f198184030181529082905262461bcd60e51b825261098091600401612daa565b6120328282611144565b15610b8d576000828152602081815260408083206001600160a01b0385168085529252808320805460ff1916905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b600061113d836001600160a01b0384166125a8565b600c5460ff16610c945760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b6044820152606401610980565b600c5460ff1615610c945760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610980565b600082600001828154811061214857612148612fae565b9060005260206000200154905092915050565b60006001600160a01b0384163b1561225d57604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061219f903390899088908890600401612d6d565b602060405180830381600087803b1580156121b957600080fd5b505af19250505080156121e9575060408051601f3d908101601f191682019092526121e691810190612c37565b60015b612243573d808015612217576040519150601f19603f3d011682016040523d82523d6000602084013e61221c565b606091505b50805161223b5760405162461bcd60e51b815260040161098090612dbd565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611875565b506001949350505050565b60606011805461086190612f02565b60608161229b5750506040805180820190915260018152600360fc1b602082015290565b8160005b81156122c557806122af81612f3d565b91506122be9050600a83612e75565b915061229f565b60008167ffffffffffffffff8111156122e0576122e0612fc4565b6040519080825280601f01601f19166020018201604052801561230a576020820181803683370190505b5090505b84156118755761231f600183612ea8565b915061232c600a86612f58565b612337906030612e5d565b60f81b81838151811061234c5761234c612fae565b60200101906001600160f81b031916908160001a90535061236e600a86612e75565b945061230e565b60006001600160e01b03198216635a05180f60e01b148061084c575061084c8261269b565b6123a58383836126d0565b600c5460ff1615610a215760405162461bcd60e51b815260206004820152602b60248201527f4552433732315061757361626c653a20746f6b656e207472616e73666572207760448201526a1a1a5b19481c185d5cd95960aa1b6064820152608401610980565b6060600061241b836002612e89565b612426906002612e5d565b67ffffffffffffffff81111561243e5761243e612fc4565b6040519080825280601f01601f191660200182016040528015612468576020820181803683370190505b509050600360fc1b8160008151811061248357612483612fae565b60200101906001600160f81b031916908160001a905350600f60fb1b816001815181106124b2576124b2612fae565b60200101906001600160f81b031916908160001a90535060006124d6846002612e89565b6124e1906001612e5d565b90505b6001811115612559576f181899199a1a9b1b9c1cb0b131b232b360811b85600f166010811061251557612515612fae565b1a60f81b82828151811061252b5761252b612fae565b60200101906001600160f81b031916908160001a90535060049490941c9361255281612eeb565b90506124e4565b50831561113d5760405162461bcd60e51b815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610980565b600081815260018301602052604081205480156126915760006125cc600183612ea8565b85549091506000906125e090600190612ea8565b905081811461264557600086600001828154811061260057612600612fae565b906000526020600020015490508087600001848154811061262357612623612fae565b6000918252602080832090910192909255918252600188019052604090208390555b855486908061265657612656612f98565b60019003818190600052602060002001600090559055856001016000868152602001908152602001600020600090556001935050505061084c565b600091505061084c565b60006001600160e01b03198216637965db0b60e01b148061084c57506301ffc9a760e01b6001600160e01b031983161461084c565b6001600160a01b03831661272b5761272681600a80546000838152600b60205260408120829055600182018355919091527fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a80155565b61274e565b816001600160a01b0316836001600160a01b03161461274e5761274e8382612788565b6001600160a01b03821661276557610a2181612825565b826001600160a01b0316826001600160a01b031614610a2157610a2182826128d4565b6000600161279584610fe9565b61279f9190612ea8565b6000838152600960205260409020549091508082146127f2576001600160a01b03841660009081526008602090815260408083208584528252808320548484528184208190558352600990915290208190555b5060009182526009602090815260408084208490556001600160a01b039094168352600881528383209183525290812055565b600a5460009061283790600190612ea8565b6000838152600b6020526040812054600a805493945090928490811061285f5761285f612fae565b9060005260206000200154905080600a838154811061288057612880612fae565b6000918252602080832090910192909255828152600b9091526040808220849055858252812055600a8054806128b8576128b8612f98565b6001900381819060005260206000200160009055905550505050565b60006128df83610fe9565b6001600160a01b039093166000908152600860209081526040808320868452825280832085905593825260099052919091209190915550565b82805461292490612f02565b90600052602060002090601f016020900481019282612946576000855561298c565b82601f1061295f57805160ff191683800117855561298c565b8280016001018555821561298c579182015b8281111561298c578251825591602001919060010190612971565b5061299892915061299c565b5090565b5b80821115612998576000815560010161299d565b600067ffffffffffffffff808411156129cc576129cc612fc4565b604051601f8501601f19908116603f011681019082821181831017156129f4576129f4612fc4565b81604052809350858152868686011115612a0d57600080fd5b858560208301376000602087830101525050509392505050565b600060208284031215612a3957600080fd5b813561113d81612fda565b600060208284031215612a5657600080fd5b815161113d81612fda565b60008060408385031215612a7457600080fd5b8235612a7f81612fda565b91506020830135612a8f81612fda565b809150509250929050565b600080600060608486031215612aaf57600080fd5b8335612aba81612fda565b92506020840135612aca81612fda565b929592945050506040919091013590565b60008060008060808587031215612af157600080fd5b8435612afc81612fda565b93506020850135612b0c81612fda565b925060408501359150606085013567ffffffffffffffff811115612b2f57600080fd5b8501601f81018713612b4057600080fd5b612b4f878235602084016129b1565b91505092959194509250565b60008060408385031215612b6e57600080fd5b8235612b7981612fda565b915060208301358015158114612a8f57600080fd5b60008060408385031215612ba157600080fd5b8235612bac81612fda565b946020939093013593505050565b600060208284031215612bcc57600080fd5b5035919050565b60008060408385031215612be657600080fd5b823591506020830135612a8f81612fda565b60008060408385031215612c0b57600080fd5b50508035926020909101359150565b600060208284031215612c2c57600080fd5b813561113d81612fef565b600060208284031215612c4957600080fd5b815161113d81612fef565b600060208284031215612c6657600080fd5b813567ffffffffffffffff811115612c7d57600080fd5b8201601f81018413612c8e57600080fd5b611875848235602084016129b1565b60008151808452612cb5816020860160208601612ebf565b601f01601f19169290920160200192915050565b60008351612cdb818460208801612ebf565b835190830190612cef818360208801612ebf565b01949350505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351612d30816017850160208801612ebf565b7001034b99036b4b9b9b4b733903937b6329607d1b6017918401918201528351612d61816028840160208801612ebf565b01602801949350505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612da090830184612c9d565b9695505050505050565b60208152600061113d6020830184612c9d565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b60008219821115612e7057612e70612f6c565b500190565b600082612e8457612e84612f82565b500490565b6000816000190483118215151615612ea357612ea3612f6c565b500290565b600082821015612eba57612eba612f6c565b500390565b60005b83811015612eda578181015183820152602001612ec2565b838111156111b95750506000910152565b600081612efa57612efa612f6c565b506000190190565b600181811c90821680612f1657607f821691505b60208210811415612f3757634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415612f5157612f51612f6c565b5060010190565b600082612f6757612f67612f82565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610cdf57600080fd5b6001600160e01b031981168114610cdf57600080fdfe9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a6a49807205ce4d355092ef5a8a18f56e8913cf4a201fbe287825b095693c21775a2646970667358221220bef4be0f931f69e68de752cd68ec598801450082600432dbd33f4f511b2fa79a64736f6c63430008070033

Deployed Bytecode Sourcemap

84708:2567:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;81654:254;;;;;;;;;;-1:-1:-1;81654:254:0;;;;;:::i;:::-;;:::i;:::-;;;8428:14:1;;8421:22;8403:41;;8391:2;8376:18;81654:254:0;;;;;;;;56478:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;57991:171::-;;;;;;;;;;-1:-1:-1;57991:171:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;7726:32:1;;;7708:51;;7696:2;7681:18;57991:171:0;7562:203:1;57508:417:0;;;;;;;;;;-1:-1:-1;57508:417:0;;;;;:::i;:::-;;:::i;:::-;;72132:113;;;;;;;;;;-1:-1:-1;72220:10:0;:17;72132:113;;;8601:25:1;;;8589:2;8574:18;72132:113:0;8455:177:1;58691:336:0;;;;;;;;;;-1:-1:-1;58691:336:0;;;;;:::i;:::-;;:::i;45245:131::-;;;;;;;;;;-1:-1:-1;45245:131:0;;;;;:::i;:::-;45319:7;45346:12;;;;;;;;;;:22;;;;45245:131;45686:147;;;;;;;;;;-1:-1:-1;45686:147:0;;;;;:::i;:::-;;:::i;71800:256::-;;;;;;;;;;-1:-1:-1;71800:256:0;;;;;:::i;:::-;;:::i;46830:218::-;;;;;;;;;;-1:-1:-1;46830:218:0;;;;;:::i;:::-;;:::i;86643:129::-;;;;;;;;;;;;;:::i;81150:185::-;;;;;;;;;;;;;:::i;59098:::-;;;;;;;;;;-1:-1:-1;59098:185:0;;;;;:::i;:::-;;:::i;70231:243::-;;;;;;;;;;-1:-1:-1;70231:243:0;;;;;:::i;:::-;;:::i;72322:233::-;;;;;;;;;;-1:-1:-1;72322:233:0;;;;;:::i;:::-;;:::i;85031:28::-;;;;;;;;;;-1:-1:-1;85031:28:0;;;;;;;;86266:224;;;;;;:::i;:::-;;:::i;53162:86::-;;;;;;;;;;-1:-1:-1;53233:7:0;;;;53162:86;;84818:77;;;;;;;;;;-1:-1:-1;84818:77:0;;;;-1:-1:-1;;;;;84818:77:0;;;86500:134;;;;;;;;;;-1:-1:-1;86500:134:0;;;;;:::i;:::-;;:::i;56189:222::-;;;;;;;;;;-1:-1:-1;56189:222:0;;;;;:::i;:::-;;:::i;80130:407::-;;;;;;;;;;-1:-1:-1;80130:407:0;;;;;:::i;:::-;;:::i;84902:21::-;;;;;;;;;;;;;:::i;55920:207::-;;;;;;;;;;-1:-1:-1;55920:207:0;;;;;:::i;:::-;;:::i;83798:103::-;;;;;;;;;;;;;:::i;84964:60::-;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;84964:60:0;;80752:179;;;;;;;;;;;;;:::i;83150:87::-;;;;;;;;;;-1:-1:-1;83223:6:0;;-1:-1:-1;;;;;83223:6:0;83150:87;;50483:153;;;;;;;;;;-1:-1:-1;50483:153:0;;;;;:::i;:::-;;:::i;43705:147::-;;;;;;;;;;-1:-1:-1;43705:147:0;;;;;:::i;:::-;;:::i;56647:104::-;;;;;;;;;;;;;:::i;42810:49::-;;;;;;;;;;-1:-1:-1;42810:49:0;42855:4;42810:49;;58234:155;;;;;;;;;;-1:-1:-1;58234:155:0;;;;;:::i;:::-;;:::i;59354:323::-;;;;;;;;;;-1:-1:-1;59354:323:0;;;;;:::i;:::-;;:::i;84930:27::-;;;;;;;;;;;;;:::i;87040:228::-;;;;;;;;;;-1:-1:-1;87040:228:0;;;;;:::i;:::-;;:::i;86780:252::-;;;;;;;;;;-1:-1:-1;86780:252:0;;;;;:::i;:::-;;:::i;85310:384::-;;;;;;:::i;:::-;;:::i;50810:142::-;;;;;;;;;;-1:-1:-1;50810:142:0;;;;;:::i;:::-;;:::i;78793:62::-;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;78793:62:0;;46126:149;;;;;;;;;;-1:-1:-1;46126:149:0;;;;;:::i;:::-;;:::i;85822:205::-;;;;;;;;;;-1:-1:-1;85822:205:0;;;;;:::i;:::-;;:::i;78862:62::-;;;;;;;;;;;;78900:24;78862:62;;58460:164;;;;;;;;;;-1:-1:-1;58460:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;58581:25:0;;;58557:4;58581:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;58460:164;86035:223;;;;;;;;;;-1:-1:-1;86035:223:0;;;;;:::i;:::-;;:::i;84056:201::-;;;;;;;;;;-1:-1:-1;84056:201:0;;;;;:::i;:::-;;:::i;81654:254::-;81835:4;81864:36;81888:11;81864:23;:36::i;:::-;81857:43;81654:254;-1:-1:-1;;81654:254:0:o;56478:100::-;56532:13;56565:5;56558:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56478:100;:::o;57991:171::-;58067:7;58087:23;58102:7;58087:14;:23::i;:::-;-1:-1:-1;58130:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;58130:24:0;;57991:171::o;57508:417::-;57589:13;57605:23;57620:7;57605:14;:23::i;:::-;57589:39;;57653:5;-1:-1:-1;;;;;57647:11:0;:2;-1:-1:-1;;;;;57647:11:0;;;57639:57;;;;-1:-1:-1;;;57639:57:0;;17291:2:1;57639:57:0;;;17273:21:1;17330:2;17310:18;;;17303:30;17369:34;17349:18;;;17342:62;-1:-1:-1;;;17420:18:1;;;17413:31;17461:19;;57639:57:0;;;;;;;;;40698:10;-1:-1:-1;;;;;57731:21:0;;;;:62;;-1:-1:-1;57756:37:0;57773:5;40698:10;58460:164;:::i;57756:37::-;57709:174;;;;-1:-1:-1;;;57709:174:0;;15455:2:1;57709:174:0;;;15437:21:1;15494:2;15474:18;;;15467:30;15533:34;15513:18;;;15506:62;15604:32;15584:18;;;15577:60;15654:19;;57709:174:0;15253:426:1;57709:174:0;57896:21;57905:2;57909:7;57896:8;:21::i;:::-;57578:347;57508:417;;:::o;58691:336::-;58886:41;40698:10;58905:12;58919:7;58886:18;:41::i;:::-;58878:100;;;;-1:-1:-1;;;58878:100:0;;;;;;;:::i;:::-;58991:28;59001:4;59007:2;59011:7;58991:9;:28::i;45686:147::-;45319:7;45346:12;;;;;;;;;;:22;;;43301:16;43312:4;43301:10;:16::i;:::-;45800:25:::1;45811:4;45817:7;45800:10;:25::i;71800:256::-:0;71897:7;71933:23;71950:5;71933:16;:23::i;:::-;71925:5;:31;71917:87;;;;-1:-1:-1;;;71917:87:0;;10516:2:1;71917:87:0;;;10498:21:1;10555:2;10535:18;;;10528:30;10594:34;10574:18;;;10567:62;-1:-1:-1;;;10645:18:1;;;10638:41;10696:19;;71917:87:0;10314:407:1;71917:87:0;-1:-1:-1;;;;;;72022:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;71800:256::o;46830:218::-;-1:-1:-1;;;;;46926:23:0;;40698:10;46926:23;46918:83;;;;-1:-1:-1;;;46918:83:0;;20129:2:1;46918:83:0;;;20111:21:1;20168:2;20148:18;;;20141:30;20207:34;20187:18;;;20180:62;-1:-1:-1;;;20258:18:1;;;20251:45;20313:19;;46918:83:0;19927:411:1;46918:83:0;47014:26;47026:4;47032:7;47014:11;:26::i;:::-;46830:218;;:::o;86643:129::-;86693:33;-1:-1:-1;;;;;;;;;;;40698:10:0;43705:147;:::i;86693:33::-;86685:48;;;;-1:-1:-1;;;86685:48:0;;16608:2:1;86685:48:0;;;16590:21:1;16647:1;16627:18;;;16620:29;-1:-1:-1;;;16665:18:1;;;16658:32;16707:18;;86685:48:0;16406:325:1;86685:48:0;86756:8;;;-1:-1:-1;;86744:20:0;;86756:8;;;;86755:9;86744:20;;;86643:129::o;81150:185::-;81203:34;78900:24;40698:10;43705:147;:::i;81203:34::-;81195:111;;;;;-1:-1:-1;;;81195:111:0;;19696:2:1;81195:111:0;;;19678:21:1;19715:18;;;19708:30;;;;19774:34;19754:18;;;19747:62;19845:34;19825:18;;;19818:62;19897:19;;81195:111:0;19494:428:1;81195:111:0;81317:10;:8;:10::i;:::-;81150:185::o;59098:::-;59236:39;59253:4;59259:2;59263:7;59236:39;;;;;;;;;;;;:16;:39::i;70231:243::-;70349:41;40698:10;70368:12;40618:98;70349:41;70341:100;;;;-1:-1:-1;;;70341:100:0;;;;;;;:::i;:::-;70452:14;70458:7;70452:5;:14::i;:::-;70231:243;:::o;72322:233::-;72397:7;72433:30;72220:10;:17;;72132:113;72433:30;72425:5;:38;72417:95;;;;-1:-1:-1;;;72417:95:0;;18023:2:1;72417:95:0;;;18005:21:1;18062:2;18042:18;;;18035:30;18101:34;18081:18;;;18074:62;-1:-1:-1;;;18152:18:1;;;18145:42;18204:19;;72417:95:0;17821:408:1;72417:95:0;72530:10;72541:5;72530:17;;;;;;;;:::i;:::-;;;;;;;;;72523:24;;72322:233;;;:::o;86266:224::-;86336:12;86369:33;-1:-1:-1;;;;;;;;;;;40698:10:0;43705:147;:::i;86369:33::-;86361:48;;;;-1:-1:-1;;;86361:48:0;;17693:2:1;86361:48:0;;;17675:21:1;17732:1;17712:18;;;17705:29;-1:-1:-1;;;17750:18:1;;;17743:32;17792:18;;86361:48:0;17491:325:1;86361:48:0;86420:40;;-1:-1:-1;;;;;86420:17:0;;;86438:21;86420:40;;;;;;;;;86438:21;86420:17;:40;;;;;;;;;;;;;;;;;;;;-1:-1:-1;86478:4:0;;86266:224;-1:-1:-1;;86266:224:0:o;86500:134::-;86560:33;-1:-1:-1;;;;;;;;;;;40698:10:0;43705:147;:::i;86560:33::-;86552:49;;;;-1:-1:-1;;;86552:49:0;;12948:2:1;86552:49:0;;;12930:21:1;12987:1;12967:18;;;12960:29;-1:-1:-1;;;13005:18:1;;;12998:33;13048:18;;86552:49:0;12746:326:1;86552:49:0;86612:14;86623:2;86612:10;:14::i;56189:222::-;56261:7;56297:16;;;:7;:16;;;;;;-1:-1:-1;;;;;56297:16:0;56332:19;56324:56;;;;-1:-1:-1;;;56324:56:0;;16938:2:1;56324:56:0;;;16920:21:1;16977:2;16957:18;;;16950:30;-1:-1:-1;;;16996:18:1;;;16989:54;17060:18;;56324:56:0;16736:348:1;80130:407:0;80190:34;-1:-1:-1;;;;;;;;;;;40698:10:0;43705:147;:::i;80190:34::-;80182:108;;;;-1:-1:-1;;;80182:108:0;;18851:2:1;80182:108:0;;;18833:21:1;18890:2;18870:18;;;18863:30;18929:34;18909:18;;;18902:62;19000:31;18980:18;;;18973:59;19049:19;;80182:108:0;18649:425:1;80182:108:0;80455:36;80461:2;80465:25;:15;1221:14;;1129:114;80465:25;80455:5;:36::i;:::-;80502:27;:15;1340:19;;1358:1;1340:19;;;1251:127;84902:21;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;55920:207::-;55992:7;-1:-1:-1;;;;;56020:19:0;;56012:73;;;;-1:-1:-1;;;56012:73:0;;14714:2:1;56012:73:0;;;14696:21:1;14753:2;14733:18;;;14726:30;14792:34;14772:18;;;14765:62;-1:-1:-1;;;14843:18:1;;;14836:39;14892:19;;56012:73:0;14512:405:1;56012:73:0;-1:-1:-1;;;;;;56103:16:0;;;;;:9;:16;;;;;;;55920:207::o;83798:103::-;83036:13;:11;:13::i;:::-;83863:30:::1;83890:1;83863:18;:30::i;80752:179::-:0;80803:34;78900:24;40698:10;43705:147;:::i;80803:34::-;80795:109;;;;-1:-1:-1;;;80795:109:0;;12517:2:1;80795:109:0;;;12499:21:1;12556:2;12536:18;;;12529:30;12595:34;12575:18;;;12568:62;12666:32;12646:18;;;12639:60;12716:19;;80795:109:0;12315:426:1;80795:109:0;80915:8;:6;:8::i;50483:153::-;50573:7;50600:18;;;:12;:18;;;;;:28;;50622:5;50600:21;:28::i;:::-;50593:35;50483:153;-1:-1:-1;;;50483:153:0:o;43705:147::-;43791:4;43815:12;;;;;;;;;;;-1:-1:-1;;;;;43815:29:0;;;;;;;;;;;;;;;43705:147::o;56647:104::-;56703:13;56736:7;56729:14;;;;;:::i;58234:155::-;58329:52;40698:10;58362:8;58372;58329:18;:52::i;59354:323::-;59528:41;40698:10;59561:7;59528:18;:41::i;:::-;59520:100;;;;-1:-1:-1;;;59520:100:0;;;;;;;:::i;:::-;59631:38;59645:4;59651:2;59655:7;59664:4;59631:13;:38::i;:::-;59354:323;;;;:::o;84930:27::-;;;;;;;:::i;87040:228::-;87111:7;87139:33;-1:-1:-1;;;;;;;;;;;40698:10:0;43705:147;:::i;87139:33::-;87131:49;;;;-1:-1:-1;;;87131:49:0;;15124:2:1;87131:49:0;;;15106:21:1;15163:1;15143:18;;;15136:29;-1:-1:-1;;;15181:18:1;;;15174:33;15224:18;;87131:49:0;14922:326:1;87131:49:0;-1:-1:-1;87191:17:0;:34;;-1:-1:-1;;;;;87191:34:0;;;-1:-1:-1;;;;;;87191:34:0;;;;;;;;87040:228::o;86780:252::-;61249:4;61273:16;;;:7;:16;;;;;;86853:13;;-1:-1:-1;;;;;61273:16:0;86892:31;;;;-1:-1:-1;;;86892:31:0;;14038:2:1;86892:31:0;;;14020:21:1;14077:1;14057:18;;;14050:29;-1:-1:-1;;;14095:18:1;;;14088:33;14138:18;;86892:31:0;13836:326:1;86892:31:0;86943:8;;;;86938:38;;86961:13;86954:20;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;86780:252;;;:::o;86938:38::-;86997:23;87012:7;86997:14;:23::i;85310:384::-;85412:24;;-1:-1:-1;;;85412:24:0;;;;;8601:25:1;;;85440:10:0;;-1:-1:-1;;;;;85412:7:0;:15;;;;8574:18:1;;85412:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;85412:38:0;;85390:134;;;;-1:-1:-1;;;85390:134:0;;18436:2:1;85390:134:0;;;18418:21:1;18475:2;18455:18;;;18448:30;18514:34;18494:18;;;18487:62;-1:-1:-1;;;18565:18:1;;;18558:44;18619:19;;85390:134:0;18234:410:1;85390:134:0;85535:35;-1:-1:-1;;;;;;;;;;;85559:10:0;85535;:35::i;:::-;85582:21;;-1:-1:-1;;;85582:21:0;;;;;8601:25:1;;;85582:7:0;-1:-1:-1;;;;;85582:12:0;;;;8574:18:1;;85582:21:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;85615:14;85626:2;85615:10;:14::i;:::-;85640:36;-1:-1:-1;;;;;;;;;;;85665:10:0;85640:11;:36::i;50810:142::-;50890:7;50917:18;;;:12;:18;;;;;:27;;:25;:27::i;46126:149::-;45319:7;45346:12;;;;;;;;;;:22;;;43301:16;43312:4;43301:10;:16::i;:::-;46241:26:::1;46253:4;46259:7;46241:11;:26::i;85822:205::-:0;85888:13;85922:33;-1:-1:-1;;;;;;;;;;;40698:10:0;43705:147;:::i;85922:33::-;85914:49;;;;-1:-1:-1;;;85914:49:0;;10185:2:1;85914:49:0;;;10167:21:1;10224:1;10204:18;;;10197:29;-1:-1:-1;;;10242:18:1;;;10235:33;10285:18;;85914:49:0;9983:326:1;85914:49:0;85974:20;;;;:7;;:20;;;;;:::i;:::-;;86012:7;86005:14;;;;;:::i;86035:223::-;86107:13;86141:33;-1:-1:-1;;;;;;;;;;;40698:10:0;43705:147;:::i;86141:33::-;86133:49;;;;-1:-1:-1;;;86133:49:0;;15124:2:1;86133:49:0;;;15106:21:1;15163:1;15143:18;;;15136:29;-1:-1:-1;;;15181:18:1;;;15174:33;15224:18;;86133:49:0;14922:326:1;86133:49:0;86193:26;;;;:13;;:26;;;;;:::i;:::-;;86237:13;86230:20;;;;;:::i;84056:201::-;83036:13;:11;:13::i;:::-;-1:-1:-1;;;;;84145:22:0;::::1;84137:73;;;::::0;-1:-1:-1;;;84137:73:0;;11347:2:1;84137:73:0::1;::::0;::::1;11329:21:1::0;11386:2;11366:18;;;11359:30;11425:34;11405:18;;;11398:62;-1:-1:-1;;;11476:18:1;;;11469:36;11522:19;;84137:73:0::1;11145:402:1::0;84137:73:0::1;84221:28;84240:8;84221:18;:28::i;48427:238::-:0;48511:22;48519:4;48525:7;48511;:22::i;:::-;48506:152;;48550:6;:12;;;;;;;;;;;-1:-1:-1;;;;;48550:29:0;;;;;;;;;:36;;-1:-1:-1;;48550:36:0;48582:4;48550:36;;;48633:12;40698:10;;40618:98;48633:12;-1:-1:-1;;;;;48606:40:0;48624:7;-1:-1:-1;;;;;48606:40:0;48618:4;48606:40;;;;;;;;;;48427:238;;:::o;10018:152::-;10088:4;10112:50;10117:3;-1:-1:-1;;;;;10137:23:0;;10112:4;:50::i;71492:224::-;71594:4;-1:-1:-1;;;;;;71618:50:0;;-1:-1:-1;;;71618:50:0;;:90;;;71672:36;71696:11;71672:23;:36::i;65966:135::-;61249:4;61273:16;;;:7;:16;;;;;;-1:-1:-1;;;;;61273:16:0;66040:53;;;;-1:-1:-1;;;66040:53:0;;16938:2:1;66040:53:0;;;16920:21:1;16977:2;16957:18;;;16950:30;-1:-1:-1;;;16996:18:1;;;16989:54;17060:18;;66040:53:0;16736:348:1;65245:174:0;65320:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;65320:29:0;-1:-1:-1;;;;;65320:29:0;;;;;;;;:24;;65374:23;65320:24;65374:14;:23::i;:::-;-1:-1:-1;;;;;65365:46:0;;;;;;;;;;;65245:174;;:::o;61478:264::-;61571:4;61588:13;61604:23;61619:7;61604:14;:23::i;:::-;61588:39;;61657:5;-1:-1:-1;;;;;61646:16:0;:7;-1:-1:-1;;;;;61646:16:0;;:52;;;-1:-1:-1;;;;;;58581:25:0;;;58557:4;58581:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;61666:32;61646:87;;;;61726:7;-1:-1:-1;;;;;61702:31:0;:20;61714:7;61702:11;:20::i;:::-;-1:-1:-1;;;;;61702:31:0;;61646:87;61638:96;61478:264;-1:-1:-1;;;;61478:264:0:o;64501:625::-;64660:4;-1:-1:-1;;;;;64633:31:0;:23;64648:7;64633:14;:23::i;:::-;-1:-1:-1;;;;;64633:31:0;;64625:81;;;;-1:-1:-1;;;64625:81:0;;11754:2:1;64625:81:0;;;11736:21:1;11793:2;11773:18;;;11766:30;11832:34;11812:18;;;11805:62;-1:-1:-1;;;11883:18:1;;;11876:35;11928:19;;64625:81:0;11552:401:1;64625:81:0;-1:-1:-1;;;;;64725:16:0;;64717:65;;;;-1:-1:-1;;;64717:65:0;;13279:2:1;64717:65:0;;;13261:21:1;13318:2;13298:18;;;13291:30;13357:34;13337:18;;;13330:62;-1:-1:-1;;;13408:18:1;;;13401:34;13452:19;;64717:65:0;13077:400:1;64717:65:0;64795:39;64816:4;64822:2;64826:7;64795:20;:39::i;:::-;64899:29;64916:1;64920:7;64899:8;:29::i;:::-;-1:-1:-1;;;;;64941:15:0;;;;;;:9;:15;;;;;:20;;64960:1;;64941:15;:20;;64960:1;;64941:20;:::i;:::-;;;;-1:-1:-1;;;;;;;64972:13:0;;;;;;:9;:13;;;;;:18;;64989:1;;64972:13;:18;;64989:1;;64972:18;:::i;:::-;;;;-1:-1:-1;;65001:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;65001:21:0;-1:-1:-1;;;;;65001:21:0;;;;;;;;;65040:27;;65001:16;;65040:27;;;;;;;57578:347;57508:417;;:::o;44156:105::-;44223:30;44234:4;40698:10;44223;:30::i;51045:169::-;51133:31;51150:4;51156:7;51133:16;:31::i;:::-;51175:18;;;;:12;:18;;;;;:31;;51198:7;51175:22;:31::i;51308:174::-;51397:32;51415:4;51421:7;51397:17;:32::i;:::-;51440:18;;;;:12;:18;;;;;:34;;51466:7;51440:25;:34::i;54017:120::-;53026:16;:14;:16::i;:::-;54076:7:::1;:15:::0;;-1:-1:-1;;54076:15:0::1;::::0;;54107:22:::1;40698:10:::0;54116:12:::1;54107:22;::::0;-1:-1:-1;;;;;7726:32:1;;;7708:51;;7696:2;7681:18;54107:22:0::1;;;;;;;54017:120::o:0;63744:420::-;63804:13;63820:23;63835:7;63820:14;:23::i;:::-;63804:39;;63856:48;63877:5;63892:1;63896:7;63856:20;:48::i;:::-;63945:29;63962:1;63966:7;63945:8;:29::i;:::-;-1:-1:-1;;;;;63987:16:0;;;;;;:9;:16;;;;;:21;;64007:1;;63987:16;:21;;64007:1;;63987:21;:::i;:::-;;;;-1:-1:-1;;64026:16:0;;;;:7;:16;;;;;;64019:23;;-1:-1:-1;;;;;;64019:23:0;;;64060:36;64034:7;;64026:16;-1:-1:-1;;;;;64060:36:0;;;;;64026:16;;64060:36;46830:218;;:::o;63076:439::-;-1:-1:-1;;;;;63156:16:0;;63148:61;;;;-1:-1:-1;;;63148:61:0;;15886:2:1;63148:61:0;;;15868:21:1;;;15905:18;;;15898:30;15964:34;15944:18;;;15937:62;16016:18;;63148:61:0;15684:356:1;63148:61:0;61249:4;61273:16;;;:7;:16;;;;;;-1:-1:-1;;;;;61273:16:0;:30;63220:58;;;;-1:-1:-1;;;63220:58:0;;12160:2:1;63220:58:0;;;12142:21:1;12199:2;12179:18;;;12172:30;12238;12218:18;;;12211:58;12286:18;;63220:58:0;11958:352:1;63220:58:0;63291:45;63320:1;63324:2;63328:7;63291:20;:45::i;:::-;-1:-1:-1;;;;;63349:13:0;;;;;;:9;:13;;;;;:18;;63366:1;;63349:13;:18;;63366:1;;63349:18;:::i;:::-;;;;-1:-1:-1;;63378:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;63378:21:0;-1:-1:-1;;;;;63378:21:0;;;;;;;;63417:33;;63378:16;;;63417:33;;63378:16;;63417:33;46830:218;;:::o;83315:132::-;83223:6;;-1:-1:-1;;;;;83223:6:0;40698:10;83379:23;83371:68;;;;-1:-1:-1;;;83371:68:0;;16247:2:1;83371:68:0;;;16229:21:1;;;16266:18;;;16259:30;16325:34;16305:18;;;16298:62;16377:18;;83371:68:0;16045:356:1;84417:191:0;84510:6;;;-1:-1:-1;;;;;84527:17:0;;;-1:-1:-1;;;;;;84527:17:0;;;;;;;84560:40;;84510:6;;;84527:17;84510:6;;84560:40;;84491:16;;84560:40;84480:128;84417:191;:::o;53758:118::-;52767:19;:17;:19::i;:::-;53818:7:::1;:14:::0;;-1:-1:-1;;53818:14:0::1;53828:4;53818:14;::::0;;53848:20:::1;53855:12;40698:10:::0;;40618:98;11314:158;11388:7;11439:22;11443:3;11455:5;11439:3;:22::i;65562:315::-;65717:8;-1:-1:-1;;;;;65708:17:0;:5;-1:-1:-1;;;;;65708:17:0;;;65700:55;;;;-1:-1:-1;;;65700:55:0;;13684:2:1;65700:55:0;;;13666:21:1;13723:2;13703:18;;;13696:30;13762:27;13742:18;;;13735:55;13807:18;;65700:55:0;13482:349:1;65700:55:0;-1:-1:-1;;;;;65766:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;65766:46:0;;;;;;;;;;65828:41;;8403::1;;;65828::0;;8376:18:1;65828:41:0;;;;;;;65562:315;;;:::o;60558:313::-;60714:28;60724:4;60730:2;60734:7;60714:9;:28::i;:::-;60761:47;60784:4;60790:2;60794:7;60803:4;60761:22;:47::i;:::-;60753:110;;;;-1:-1:-1;;;60753:110:0;;;;;;;:::i;56822:281::-;56895:13;56921:23;56936:7;56921:14;:23::i;:::-;56957:21;56981:10;:8;:10::i;:::-;56957:34;;57033:1;57015:7;57009:21;:25;:86;;;;;;;;;;;;;;;;;57061:7;57070:18;:7;:16;:18::i;:::-;57044:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;57002:93;56822:281;-1:-1:-1;;;56822:281:0:o;47755:112::-;47834:25;47845:4;47851:7;47834:10;:25::i;10843:117::-;10906:7;10933:19;10941:3;6327:18;;6244:109;3933:414;3996:4;6126:19;;;:12;;;:19;;;;;;4013:327;;-1:-1:-1;4056:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;4239:18;;4217:19;;;:12;;;:19;;;;;;:40;;;;4272:11;;4013:327;-1:-1:-1;4323:5:0;4316:12;;55551:305;55653:4;-1:-1:-1;;;;;;55690:40:0;;-1:-1:-1;;;55690:40:0;;:105;;-1:-1:-1;;;;;;;55747:48:0;;-1:-1:-1;;;55747:48:0;55690:105;:158;;;;55812:36;55836:11;55812:23;:36::i;81343:239::-;81529:45;81556:4;81562:2;81566:7;81529:26;:45::i;44551:505::-;44640:22;44648:4;44654:7;44640;:22::i;:::-;44635:414;;44828:41;44856:7;-1:-1:-1;;;;;44828:41:0;44866:2;44828:19;:41::i;:::-;44942:38;44970:4;44977:2;44942:19;:38::i;:::-;44733:270;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;44733:270:0;;;;;;;;;;-1:-1:-1;;;44679:358:0;;;;;;;:::i;48845:239::-;48929:22;48937:4;48943:7;48929;:22::i;:::-;48925:152;;;49000:5;48968:12;;;;;;;;;;;-1:-1:-1;;;;;48968:29:0;;;;;;;;;;:37;;-1:-1:-1;;48968:37:0;;;49025:40;40698:10;;48968:12;;49025:40;;49000:5;49025:40;48845:239;;:::o;10346:158::-;10419:4;10443:53;10451:3;-1:-1:-1;;;;;10471:23:0;;10443:7;:53::i;53506:108::-;53233:7;;;;53565:41;;;;-1:-1:-1;;;53565:41:0;;9836:2:1;53565:41:0;;;9818:21:1;9875:2;9855:18;;;9848:30;-1:-1:-1;;;9894:18:1;;;9887:50;9954:18;;53565:41:0;9634:344:1;53321:108:0;53233:7;;;;53391:9;53383:38;;;;-1:-1:-1;;;53383:38:0;;14369:2:1;53383:38:0;;;14351:21:1;14408:2;14388:18;;;14381:30;-1:-1:-1;;;14427:18:1;;;14420:46;14483:18;;53383:38:0;14167:340:1;6707:120:0;6774:7;6801:3;:11;;6813:5;6801:18;;;;;;;;:::i;:::-;;;;;;;;;6794:25;;6707:120;;;;:::o;66665:853::-;66819:4;-1:-1:-1;;;;;66840:13:0;;23147:19;:23;66836:675;;66876:71;;-1:-1:-1;;;66876:71:0;;-1:-1:-1;;;;;66876:36:0;;;;;:71;;40698:10;;66927:4;;66933:7;;66942:4;;66876:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;66876:71:0;;;;;;;;-1:-1:-1;;66876:71:0;;;;;;;;;;;;:::i;:::-;;;66872:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;67117:13:0;;67113:328;;67160:60;;-1:-1:-1;;;67160:60:0;;;;;;;:::i;67113:328::-;67391:6;67385:13;67376:6;67372:2;67368:15;67361:38;66872:584;-1:-1:-1;;;;;;66998:51:0;-1:-1:-1;;;66998:51:0;;-1:-1:-1;66991:58:0;;66836:675;-1:-1:-1;67495:4:0;66665:853;;;;;;:::o;85702:108::-;85762:13;85795:7;85788:14;;;;;:::i;19552:723::-;19608:13;19829:10;19825:53;;-1:-1:-1;;19856:10:0;;;;;;;;;;;;-1:-1:-1;;;19856:10:0;;;;;19552:723::o;19825:53::-;19903:5;19888:12;19944:78;19951:9;;19944:78;;19977:8;;;;:::i;:::-;;-1:-1:-1;20000:10:0;;-1:-1:-1;20008:2:0;20000:10;;:::i;:::-;;;19944:78;;;20032:19;20064:6;20054:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;20054:17:0;;20032:39;;20082:154;20089:10;;20082:154;;20116:11;20126:1;20116:11;;:::i;:::-;;-1:-1:-1;20185:10:0;20193:2;20185:5;:10;:::i;:::-;20172:24;;:2;:24;:::i;:::-;20159:39;;20142:6;20149;20142:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;20142:56:0;;;;;;;;-1:-1:-1;20213:11:0;20222:2;20213:11;;:::i;:::-;;;20082:154;;49670:214;49755:4;-1:-1:-1;;;;;;49779:57:0;;-1:-1:-1;;;49779:57:0;;:97;;;49840:36;49864:11;49840:23;:36::i;69411:275::-;69555:45;69582:4;69588:2;69592:7;69555:26;:45::i;:::-;53233:7;;;;69621:9;69613:65;;;;-1:-1:-1;;;69613:65:0;;9424:2:1;69613:65:0;;;9406:21:1;9463:2;9443:18;;;9436:30;9502:34;9482:18;;;9475:62;-1:-1:-1;;;9553:18:1;;;9546:41;9604:19;;69613:65:0;9222:407:1;20853:451:0;20928:13;20954:19;20986:10;20990:6;20986:1;:10;:::i;:::-;:14;;20999:1;20986:14;:::i;:::-;20976:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;20976:25:0;;20954:47;;-1:-1:-1;;;21012:6:0;21019:1;21012:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;21012:15:0;;;;;;;;;-1:-1:-1;;;21038:6:0;21045:1;21038:9;;;;;;;;:::i;:::-;;;;:15;-1:-1:-1;;;;;21038:15:0;;;;;;;;-1:-1:-1;21069:9:0;21081:10;21085:6;21081:1;:10;:::i;:::-;:14;;21094:1;21081:14;:::i;:::-;21069:26;;21064:135;21101:1;21097;:5;21064:135;;;-1:-1:-1;;;21149:5:0;21157:3;21149:11;21136:25;;;;;;;:::i;:::-;;;;21124:6;21131:1;21124:9;;;;;;;;:::i;:::-;;;;:37;-1:-1:-1;;;;;21124:37:0;;;;;;;;-1:-1:-1;21186:1:0;21176:11;;;;;21104:3;;;:::i;:::-;;;21064:135;;;-1:-1:-1;21217:10:0;;21209:55;;;;-1:-1:-1;;;21209:55:0;;9063:2:1;21209:55:0;;;9045:21:1;;;9082:18;;;9075:30;9141:34;9121:18;;;9114:62;9193:18;;21209:55:0;8861:356:1;4523:1420:0;4589:4;4728:19;;;:12;;;:19;;;;;;4764:15;;4760:1176;;5139:21;5163:14;5176:1;5163:10;:14;:::i;:::-;5212:18;;5139:38;;-1:-1:-1;5192:17:0;;5212:22;;5233:1;;5212:22;:::i;:::-;5192:42;;5268:13;5255:9;:26;5251:405;;5302:17;5322:3;:11;;5334:9;5322:22;;;;;;;;:::i;:::-;;;;;;;;;5302:42;;5476:9;5447:3;:11;;5459:13;5447:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;5561:23;;;:12;;;:23;;;;;:36;;;5251:405;5737:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;5832:3;:12;;:19;5845:5;5832:19;;;;;;;;;;;5825:26;;;5875:4;5868:11;;;;;;;4760:1176;5919:5;5912:12;;;;;43409:204;43494:4;-1:-1:-1;;;;;;43518:47:0;;-1:-1:-1;;;43518:47:0;;:87;;-1:-1:-1;;;;;;;;;;33117:40:0;;;43569:36;33008:157;73168:589;-1:-1:-1;;;;;73374:18:0;;73370:187;;73409:40;73441:7;74584:10;:17;;74557:24;;;;:15;:24;;;;;:44;;;74612:24;;;;;;;;;;;;74480:164;73409:40;73370:187;;;73479:2;-1:-1:-1;;;;;73471:10:0;:4;-1:-1:-1;;;;;73471:10:0;;73467:90;;73498:47;73531:4;73537:7;73498:32;:47::i;:::-;-1:-1:-1;;;;;73571:16:0;;73567:183;;73604:45;73641:7;73604:36;:45::i;73567:183::-;73677:4;-1:-1:-1;;;;;73671:10:0;:2;-1:-1:-1;;;;;73671:10:0;;73667:83;;73698:40;73726:2;73730:7;73698:27;:40::i;75271:988::-;75537:22;75587:1;75562:22;75579:4;75562:16;:22::i;:::-;:26;;;;:::i;:::-;75599:18;75620:26;;;:17;:26;;;;;;75537:51;;-1:-1:-1;75753:28:0;;;75749:328;;-1:-1:-1;;;;;75820:18:0;;75798:19;75820:18;;;:12;:18;;;;;;;;:34;;;;;;;;;75871:30;;;;;;:44;;;75988:30;;:17;:30;;;;;:43;;;75749:328;-1:-1:-1;76173:26:0;;;;:17;:26;;;;;;;;76166:33;;;-1:-1:-1;;;;;76217:18:0;;;;;:12;:18;;;;;:34;;;;;;;76210:41;75271:988::o;76554:1079::-;76832:10;:17;76807:22;;76832:21;;76852:1;;76832:21;:::i;:::-;76864:18;76885:24;;;:15;:24;;;;;;77258:10;:26;;76807:46;;-1:-1:-1;76885:24:0;;76807:46;;77258:26;;;;;;:::i;:::-;;;;;;;;;77236:48;;77322:11;77297:10;77308;77297:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;77402:28;;;:15;:28;;;;;;;:41;;;77574:24;;;;;77567:31;77609:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;76625:1008;;;76554:1079;:::o;74058:221::-;74143:14;74160:20;74177:2;74160:16;:20::i;:::-;-1:-1:-1;;;;;74191:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;74236:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;74058:221:0:o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:631:1;78:5;108:18;149:2;141:6;138:14;135:40;;;155:18;;:::i;:::-;230:2;224:9;198:2;284:15;;-1:-1:-1;;280:24:1;;;306:2;276:33;272:42;260:55;;;330:18;;;350:22;;;327:46;324:72;;;376:18;;:::i;:::-;416:10;412:2;405:22;445:6;436:15;;475:6;467;460:22;515:3;506:6;501:3;497:16;494:25;491:45;;;532:1;529;522:12;491:45;582:6;577:3;570:4;562:6;558:17;545:44;637:1;630:4;621:6;613;609:19;605:30;598:41;;;;14:631;;;;;:::o;650:247::-;709:6;762:2;750:9;741:7;737:23;733:32;730:52;;;778:1;775;768:12;730:52;817:9;804:23;836:31;861:5;836:31;:::i;902:251::-;972:6;1025:2;1013:9;1004:7;1000:23;996:32;993:52;;;1041:1;1038;1031:12;993:52;1073:9;1067:16;1092:31;1117:5;1092:31;:::i;1418:388::-;1486:6;1494;1547:2;1535:9;1526:7;1522:23;1518:32;1515:52;;;1563:1;1560;1553:12;1515:52;1602:9;1589:23;1621:31;1646:5;1621:31;:::i;:::-;1671:5;-1:-1:-1;1728:2:1;1713:18;;1700:32;1741:33;1700:32;1741:33;:::i;:::-;1793:7;1783:17;;;1418:388;;;;;:::o;1811:456::-;1888:6;1896;1904;1957:2;1945:9;1936:7;1932:23;1928:32;1925:52;;;1973:1;1970;1963:12;1925:52;2012:9;1999:23;2031:31;2056:5;2031:31;:::i;:::-;2081:5;-1:-1:-1;2138:2:1;2123:18;;2110:32;2151:33;2110:32;2151:33;:::i;:::-;1811:456;;2203:7;;-1:-1:-1;;;2257:2:1;2242:18;;;;2229:32;;1811:456::o;2272:794::-;2367:6;2375;2383;2391;2444:3;2432:9;2423:7;2419:23;2415:33;2412:53;;;2461:1;2458;2451:12;2412:53;2500:9;2487:23;2519:31;2544:5;2519:31;:::i;:::-;2569:5;-1:-1:-1;2626:2:1;2611:18;;2598:32;2639:33;2598:32;2639:33;:::i;:::-;2691:7;-1:-1:-1;2745:2:1;2730:18;;2717:32;;-1:-1:-1;2800:2:1;2785:18;;2772:32;2827:18;2816:30;;2813:50;;;2859:1;2856;2849:12;2813:50;2882:22;;2935:4;2927:13;;2923:27;-1:-1:-1;2913:55:1;;2964:1;2961;2954:12;2913:55;2987:73;3052:7;3047:2;3034:16;3029:2;3025;3021:11;2987:73;:::i;:::-;2977:83;;;2272:794;;;;;;;:::o;3071:416::-;3136:6;3144;3197:2;3185:9;3176:7;3172:23;3168:32;3165:52;;;3213:1;3210;3203:12;3165:52;3252:9;3239:23;3271:31;3296:5;3271:31;:::i;:::-;3321:5;-1:-1:-1;3378:2:1;3363:18;;3350:32;3420:15;;3413:23;3401:36;;3391:64;;3451:1;3448;3441:12;3492:315;3560:6;3568;3621:2;3609:9;3600:7;3596:23;3592:32;3589:52;;;3637:1;3634;3627:12;3589:52;3676:9;3663:23;3695:31;3720:5;3695:31;:::i;:::-;3745:5;3797:2;3782:18;;;;3769:32;;-1:-1:-1;;;3492:315:1:o;3812:180::-;3871:6;3924:2;3912:9;3903:7;3899:23;3895:32;3892:52;;;3940:1;3937;3930:12;3892:52;-1:-1:-1;3963:23:1;;3812:180;-1:-1:-1;3812:180:1:o;3997:315::-;4065:6;4073;4126:2;4114:9;4105:7;4101:23;4097:32;4094:52;;;4142:1;4139;4132:12;4094:52;4178:9;4165:23;4155:33;;4238:2;4227:9;4223:18;4210:32;4251:31;4276:5;4251:31;:::i;4317:248::-;4385:6;4393;4446:2;4434:9;4425:7;4421:23;4417:32;4414:52;;;4462:1;4459;4452:12;4414:52;-1:-1:-1;;4485:23:1;;;4555:2;4540:18;;;4527:32;;-1:-1:-1;4317:248:1:o;4570:245::-;4628:6;4681:2;4669:9;4660:7;4656:23;4652:32;4649:52;;;4697:1;4694;4687:12;4649:52;4736:9;4723:23;4755:30;4779:5;4755:30;:::i;4820:249::-;4889:6;4942:2;4930:9;4921:7;4917:23;4913:32;4910:52;;;4958:1;4955;4948:12;4910:52;4990:9;4984:16;5009:30;5033:5;5009:30;:::i;5074:450::-;5143:6;5196:2;5184:9;5175:7;5171:23;5167:32;5164:52;;;5212:1;5209;5202:12;5164:52;5252:9;5239:23;5285:18;5277:6;5274:30;5271:50;;;5317:1;5314;5307:12;5271:50;5340:22;;5393:4;5385:13;;5381:27;-1:-1:-1;5371:55:1;;5422:1;5419;5412:12;5371:55;5445:73;5510:7;5505:2;5492:16;5487:2;5483;5479:11;5445:73;:::i;6034:257::-;6075:3;6113:5;6107:12;6140:6;6135:3;6128:19;6156:63;6212:6;6205:4;6200:3;6196:14;6189:4;6182:5;6178:16;6156:63;:::i;:::-;6273:2;6252:15;-1:-1:-1;;6248:29:1;6239:39;;;;6280:4;6235:50;;6034:257;-1:-1:-1;;6034:257:1:o;6296:470::-;6475:3;6513:6;6507:13;6529:53;6575:6;6570:3;6563:4;6555:6;6551:17;6529:53;:::i;:::-;6645:13;;6604:16;;;;6667:57;6645:13;6604:16;6701:4;6689:17;;6667:57;:::i;:::-;6740:20;;6296:470;-1:-1:-1;;;;6296:470:1:o;6771:786::-;7182:25;7177:3;7170:38;7152:3;7237:6;7231:13;7253:62;7308:6;7303:2;7298:3;7294:12;7287:4;7279:6;7275:17;7253:62;:::i;:::-;-1:-1:-1;;;7374:2:1;7334:16;;;7366:11;;;7359:40;7424:13;;7446:63;7424:13;7495:2;7487:11;;7480:4;7468:17;;7446:63;:::i;:::-;7529:17;7548:2;7525:26;;6771:786;-1:-1:-1;;;;6771:786:1:o;7770:488::-;-1:-1:-1;;;;;8039:15:1;;;8021:34;;8091:15;;8086:2;8071:18;;8064:43;8138:2;8123:18;;8116:34;;;8186:3;8181:2;8166:18;;8159:31;;;7964:4;;8207:45;;8232:19;;8224:6;8207:45;:::i;:::-;8199:53;7770:488;-1:-1:-1;;;;;;7770:488:1:o;8637:219::-;8786:2;8775:9;8768:21;8749:4;8806:44;8846:2;8835:9;8831:18;8823:6;8806:44;:::i;10726:414::-;10928:2;10910:21;;;10967:2;10947:18;;;10940:30;11006:34;11001:2;10986:18;;10979:62;-1:-1:-1;;;11072:2:1;11057:18;;11050:48;11130:3;11115:19;;10726:414::o;19079:410::-;19281:2;19263:21;;;19320:2;19300:18;;;19293:30;19359:34;19354:2;19339:18;;19332:62;-1:-1:-1;;;19425:2:1;19410:18;;19403:44;19479:3;19464:19;;19079:410::o;20525:128::-;20565:3;20596:1;20592:6;20589:1;20586:13;20583:39;;;20602:18;;:::i;:::-;-1:-1:-1;20638:9:1;;20525:128::o;20658:120::-;20698:1;20724;20714:35;;20729:18;;:::i;:::-;-1:-1:-1;20763:9:1;;20658:120::o;20783:168::-;20823:7;20889:1;20885;20881:6;20877:14;20874:1;20871:21;20866:1;20859:9;20852:17;20848:45;20845:71;;;20896:18;;:::i;:::-;-1:-1:-1;20936:9:1;;20783:168::o;20956:125::-;20996:4;21024:1;21021;21018:8;21015:34;;;21029:18;;:::i;:::-;-1:-1:-1;21066:9:1;;20956:125::o;21086:258::-;21158:1;21168:113;21182:6;21179:1;21176:13;21168:113;;;21258:11;;;21252:18;21239:11;;;21232:39;21204:2;21197:10;21168:113;;;21299:6;21296:1;21293:13;21290:48;;;-1:-1:-1;;21334:1:1;21316:16;;21309:27;21086:258::o;21349:136::-;21388:3;21416:5;21406:39;;21425:18;;:::i;:::-;-1:-1:-1;;;21461:18:1;;21349:136::o;21490:380::-;21569:1;21565:12;;;;21612;;;21633:61;;21687:4;21679:6;21675:17;21665:27;;21633:61;21740:2;21732:6;21729:14;21709:18;21706:38;21703:161;;;21786:10;21781:3;21777:20;21774:1;21767:31;21821:4;21818:1;21811:15;21849:4;21846:1;21839:15;21703:161;;21490:380;;;:::o;21875:135::-;21914:3;-1:-1:-1;;21935:17:1;;21932:43;;;21955:18;;:::i;:::-;-1:-1:-1;22002:1:1;21991:13;;21875:135::o;22015:112::-;22047:1;22073;22063:35;;22078:18;;:::i;:::-;-1:-1:-1;22112:9:1;;22015:112::o;22132:127::-;22193:10;22188:3;22184:20;22181:1;22174:31;22224:4;22221:1;22214:15;22248:4;22245:1;22238:15;22264:127;22325:10;22320:3;22316:20;22313:1;22306:31;22356:4;22353:1;22346:15;22380:4;22377:1;22370:15;22396:127;22457:10;22452:3;22448:20;22445:1;22438:31;22488:4;22485:1;22478:15;22512:4;22509:1;22502:15;22528:127;22589:10;22584:3;22580:20;22577:1;22570:31;22620:4;22617:1;22610:15;22644:4;22641:1;22634:15;22660:127;22721:10;22716:3;22712:20;22709:1;22702:31;22752:4;22749:1;22742:15;22776:4;22773:1;22766:15;22792:131;-1:-1:-1;;;;;22867:31:1;;22857:42;;22847:70;;22913:1;22910;22903:12;22928:131;-1:-1:-1;;;;;;23002:32:1;;22992:43;;22982:71;;23049:1;23046;23039:12

Swarm Source

ipfs://bef4be0f931f69e68de752cd68ec598801450082600432dbd33f4f511b2fa79a
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.