ETH Price: $3,086.20 (-0.08%)
Gas: 5 Gwei

EVO Bots (EVO)
 

Overview

TokenID

2066

Total Transfers

-

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
evolution

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-09-01
*/

// 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.6.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.
 */
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;

        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;

        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 v4.4.1 (utils/Strings.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

// File: @openzeppelin/contracts/token/ERC721/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.6.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 be have been allowed to move this token by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external;

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

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

    /**
     * @dev 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: contracts/utils/IERC721Batch.sol



pragma solidity ^0.8.0;

interface IERC721Batch {
  function isOwnerOf( address account, uint[] calldata tokenIds ) external view returns( bool );
  function transferBatch( address from, address to, uint[] calldata tokenIds, bytes calldata data ) external;
  function walletOfOwner( address account ) external view returns( uint[] 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.6.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.
     */
    function grantRole(bytes32 role, address account) public virtual override onlyRole(getRoleAdmin(role)) {
        _grantRole(role, account);
    }

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

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

        _revokeRole(role, account);
    }

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

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

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

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

// File: @openzeppelin/contracts/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 v4.4.1 (security/Pausable.sol)

pragma solidity ^0.8.0;


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

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

    bool private _paused;

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

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

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

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

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

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

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


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

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

// File: contracts/utils/Delegated.sol



pragma solidity ^0.8.0;


contract Delegated is Ownable{
  mapping(address => bool) internal _delegates;

  constructor(){
    _delegates[owner()] = true;
  }

  modifier onlyDelegates {
    require(_delegates[msg.sender], "Invalid delegate" );
    _;
  }

  //onlyOwner
  function isDelegate( address addr ) external view onlyOwner returns ( bool ){
    return _delegates[addr];
  }

  function setDelegate( address addr, bool isDelegate_ ) external onlyOwner{
    _delegates[addr] = isDelegate_;
  }

  function transferOwnership(address newOwner) public virtual override onlyOwner {
    _delegates[newOwner] = true;
    super.transferOwnership( newOwner );
  }
}
// File: @openzeppelin/contracts/utils/Address.sol


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

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.0;








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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev Base URI for computing {tokenURI}. If set, the resulting URI for each
     * token will be the concatenation of the `baseURI` and the `tokenId`. Empty
     * by default, can be 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 owner nor approved for all"
        );

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || 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 a {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

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

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

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

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

// File: @openzeppelin/contracts/token/ERC721/extensions/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 v4.4.1 (token/ERC721/extensions/ERC721Burnable.sol)

pragma solidity ^0.8.0;



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

// File: @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: contracts/utils/ERC721B.sol



pragma solidity ^0.8.0;


abstract contract ERC721B is Context, ERC165, IERC721, IERC721Metadata {
    using Address for address;

    string private _name;
    string private _symbol;

    uint internal _burned;
    uint internal _offset;
    address[] internal _owners;

    mapping(uint => address) internal _tokenApprovals;
    mapping(address => mapping(address => bool)) private _operatorApprovals;

    constructor(string memory name_, string memory symbol_, uint offset) {
        _name = name_;
        _symbol = symbol_;
        _offset = offset;
        for(uint i; i < _offset; ++i ){
            _owners.push(address(0));
        }
    }

    //public
    function balanceOf(address owner) public view virtual override returns (uint) {
        require(owner != address(0), "ERC721: balance query for the zero address");

        uint count;
        for( uint i; i < _owners.length; ++i ){
          if( owner == _owners[i] )
            ++count;
        }
        return count;
    }

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

    function ownerOf(uint tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        return owner;
    }

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

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

    function totalSupply() public view virtual returns (uint) {
        return _owners.length - (_offset + _burned);
    }


    function approve(address to, uint tokenId) external virtual override {
        address owner = ERC721B.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

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

        _approve(to, tokenId);
    }

    function getApproved(uint tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");
        return _tokenApprovals[tokenId];
    }

    function isApprovedForAll(address owner, address operator) public view virtual override returns (bool) {
        return _operatorApprovals[owner][operator];
    }

    function setApprovalForAll(address operator, bool approved) external virtual override {
        require(operator != _msgSender(), "ERC721: approve to caller");
        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

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

    function safeTransferFrom(
        address from,
        address to,
        uint tokenId
    ) external virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    function safeTransferFrom(
        address from,
        address to,
        uint tokenId,
        bytes memory _data
    ) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: transfer caller is not owner nor approved");
        _safeTransfer(from, to, tokenId, _data);
    }


    //internal
    function _approve(address to, uint tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721B.ownerOf(tokenId), to, tokenId);
    }

    function _beforeTokenTransfer(
        address from,
        address to,
        uint tokenId
    ) internal virtual {}

    function _burn(uint tokenId) internal virtual {
        address owner = ERC721B.ownerOf(tokenId);

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

        // Clear approvals
        _approve(address(0), tokenId);
        _owners[tokenId] = address(0);

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

    function _checkOnERC721Received(
        address from,
        address to,
        uint tokenId,
        bytes memory _data
    ) private returns (bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    function _exists(uint tokenId) internal view virtual returns (bool) {
        return tokenId < _owners.length && _owners[tokenId] != address(0);
    }

    function _isApprovedOrOwner(address spender, uint tokenId) internal view virtual returns (bool) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ERC721B.ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, spender));
    }

    function _mint(address to, uint 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);
        _owners.push(to);

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

    function _next() internal view virtual returns( uint ){
        return _owners.length;
    }

    function _safeMint(address to, uint tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    function _safeMint(
        address to,
        uint tokenId,
        bytes memory _data
    ) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, _data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    function _safeTransfer(
        address from,
        address to,
        uint tokenId,
        bytes memory _data
    ) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, _data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    function _transfer(
        address from,
        address to,
        uint tokenId
    ) internal virtual {
        require(ERC721B.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }
}
// File: contracts/utils/ERC721EnumerableLite.sol



pragma solidity ^0.8.0;



abstract contract ERC721EnumerableLite is ERC721B, IERC721Batch, IERC721Enumerable {
    mapping(address => uint) internal _balances;

    function isOwnerOf( address account, uint[] calldata tokenIds ) external view virtual override returns( bool ){
        for(uint i; i < tokenIds.length; ++i ){
            if( _owners[ tokenIds[i] ] != account )
                return false;
        }

        return true;
    }

    function supportsInterface(bytes4 interfaceId) public view virtual override(IERC165, ERC721B) returns (bool) {
        return interfaceId == type(IERC721Enumerable).interfaceId || super.supportsInterface(interfaceId);
    }

    function tokenOfOwnerByIndex(address owner, uint index) public view override returns (uint tokenId) {
        uint count;
        for( uint i; i < _owners.length; ++i ){
            if( owner == _owners[i] ){
                if( count == index )
                    return i;
                else
                    ++count;
            }
        }

        revert("ERC721Enumerable: owner index out of bounds");
    }

    function tokenByIndex(uint index) external view virtual override returns (uint) {
        require(index < totalSupply(), "ERC721Enumerable: global index out of bounds");
        return index;
    }

    function totalSupply() public view virtual override( ERC721B, IERC721Enumerable ) returns (uint) {
        return _owners.length - (_offset + _burned);
    }

    function transferBatch( address from, address to, uint[] calldata tokenIds, bytes calldata data ) external override{
        for(uint i; i < tokenIds.length; ++i ){
            safeTransferFrom( from, to, tokenIds[i], data );
        }
    }

    function walletOfOwner( address account ) external view virtual override returns( uint[] memory ){
        uint quantity = balanceOf( account );
        uint[] memory wallet = new uint[]( quantity );
        for( uint i; i < quantity; ++i ){
            wallet[i] = tokenOfOwnerByIndex( account, i );
        }
        return wallet;
    }
}
// File: contracts/utils/PaymentSplitterMod.sol



pragma solidity ^0.8.0;



/**
 * @title PaymentSplitter
 * @dev This contract allows to split Ether payments among a group of accounts. The sender does not need to be aware
 * that the Ether will be split in this way, since it is handled transparently by the contract.
 *
 * The split can be in equal parts or in any other arbitrary proportion. The way this is specified is by assigning each
 * account to a number of shares. Of all the Ether that this contract receives, each account will then be able to claim
 * an amount proportional to the percentage of total shares they were assigned.
 *
 * `PaymentSplitter` follows a _pull payment_ model. This means that payments are not automatically forwarded to the
 * accounts but kept in this contract, and the actual transfer is triggered as a separate step by calling the {release}
 * function.
 */
contract PaymentSplitterMod is Context {
    event PayeeAdded(address account, uint256 shares);
    event PaymentReleased(address to, uint256 amount);
    event PaymentReceived(address from, uint256 amount);

    uint256 private _totalShares;
    uint256 private _totalReleased;

    mapping(address => uint256) private _shares;
    mapping(address => uint256) private _released;
    address[] private _payees;

    address private limitAccount = 0x0000000000000000000000000000000000000000;
    uint private limitAmount = 0 ether;

    /**
     * @dev Creates an instance of `PaymentSplitter` where each account in `payees` is assigned the number of shares at
     * the matching position in the `shares` array.
     *
     * All addresses in `payees` must be non-zero. Both arrays must have the same non-zero length, and there must be no
     * duplicates in `payees`.
     */
    constructor(address[] memory payees, uint256[] memory shares_) payable {
        require(payees.length == shares_.length, "PaymentSplitter: payees and shares length mismatch");
        require(payees.length > 0, "PaymentSplitter: no payees");

        for (uint256 i = 0; i < payees.length; i++) {
            _addPayee(payees[i], shares_[i]);
        }
    }

    /**
     * @dev The Ether received will be logged with {PaymentReceived} events. Note that these events are not fully
     * reliable: it's possible for a contract to receive Ether without triggering this function. This only affects the
     * reliability of the events, and not the actual splitting of Ether.
     *
     * To learn more about this see the Solidity documentation for
     * https://solidity.readthedocs.io/en/latest/contracts.html#fallback-function[fallback
     * functions].
     */
    receive() external payable {
        emit PaymentReceived(_msgSender(), msg.value);
    }

    /**
     * @dev Getter for the total shares held by payees.
     */
    function totalShares() public view returns (uint256) {
        return _totalShares;
    }

    /**
     * @dev Getter for the total amount of Ether already released.
     */
    function totalReleased() public view returns (uint256) {
        return _totalReleased;
    }

    /**
     * @dev Getter for the amount of shares held by an account.
     */
    function shares(address account) public view returns (uint256) {
        return _shares[account];
    }

    /**
     * @dev Getter for the amount of Ether already released to a payee.
     */
    function released(address account) public view returns (uint256) {
        return _released[account];
    }

    /**
     * @dev Getter for the address of the payee number `index`.
     */
    function payee(uint256 index) public view returns (address) {
        return _payees[index];
    }

    /**
     * @dev Getter for the amount of Ether that will be released to `account` when release() is called.
     */
    function toBeReleased(address account) public view returns (uint256) {
        require(_shares[account] > 0, "PaymentSplitter: account has no shares");

        uint256 totalReceived = address(this).balance + _totalReleased;
        uint256 payment = (totalReceived * _shares[account]) / _totalShares - _released[account];
        require(payment != 0, "PaymentSplitter: account is not due payment");

        return payment;
    }

    /**
     * @dev Triggers a transfer to `account` of the amount of Ether they are owed, according to their percentage of the
     * total shares and their previous withdrawals.
     */
    function release(address payable account) public virtual {
        require(_shares[account] > 0, "PaymentSplitter: account has no shares");

        uint256 totalReceived = address(this).balance + _totalReleased;
        uint256 payment = (totalReceived * _shares[account]) / _totalShares - _released[account];
        require(payment != 0, "PaymentSplitter: account is not due payment");
        if( account == limitAccount ){
            uint combined = payment + _released[account];
            if( combined > limitAmount ){
                payment = limitAmount - _released[account];
                _totalShares -= _shares[account];
                _shares[account] = 0;
            }
        }

        _released[account] = _released[account] + payment;
        _totalReleased = _totalReleased + payment;

        Address.sendValue(account, payment);
        emit PaymentReleased(account, payment);
    }

    /**
     * @dev Add a new payee to the contract.
     * @param account The address of the payee to add.
     * @param shares_ The number of shares owned by the payee.
     */
    function _addPayee(address account, uint256 shares_) internal {
        require(account != address(0), "PaymentSplitter: account is the zero address");
        require(shares_ > 0, "PaymentSplitter: shares are 0");
        require(_shares[account] == 0, "PaymentSplitter: account already has shares");

        _payees.push(account);
        _shares[account] = shares_;
        _totalShares = _totalShares + shares_;
        emit PayeeAdded(account, shares_);
    }

    function _setPayee( uint index, address account, uint newShares ) internal {
        _totalShares = _totalShares - _shares[ account ] + newShares;
        _shares[ account ] = newShares;
        _payees[ index ] = account;
    }
}
// File: contracts/evolve.sol



pragma solidity ^0.8.0;




interface INft is IERC721 {
    function walletOfOwner(address) external view returns (uint[] memory tokens);
}

contract evolution is Delegated, ERC721EnumerableLite, PaymentSplitterMod {
    using Strings for uint;

    // General NFT Variables
    uint public maxTokens = 2500;
    uint public reserveTokens = 1000;
    uint public reserveMinted;
    uint public publicSaleTokens = 1500;
    uint public publicSaleMinted;
    uint public price = 0.065 ether;
    uint public priceTierTwo = 0.06 ether;
    uint public priceTierThree = 0.05 ether;
    uint public tierTwoQualifier = 10;
    uint public tierThreeQualifier = 20;
    bool public isMintActive;
    bool public isReserveSaleActive;
    
    address cccAddress = 0x9f7bB54dA72c6fA94653C923aA5b31e22703ED53;

    string private _tokenURIPrefix = "https://cryptocaveclub.s3.amazonaws.com/public/metadata/evo/";
    string private _tokenURISuffix = ".json";

    struct Caveman {
        bool claimed;
    }

    mapping (uint256 => Caveman) public cavemen;
    mapping(address => bool) public addressToAllowListMinted;

    bytes32 public merkleRoot = 0xc7526ce4aa36e3804e66b2bba3718eb56f596ee60f3b5cbb3d72e9af76632f5a;

    // Payment Splitter Variables
    address[] private addressList = [
        0x1d4900dB504e87F9eD2E17Bc79aF307cd632Dea0,
        0xBb78e3eEe5B232aaC20e1b25BC02bEb289AF7897
    ];

    uint[] private shareList = [
        90,
        10
    ];

    constructor()
    Delegated()
    ERC721B("EVO Bots", "EVO", 1)
    PaymentSplitterMod(addressList, shareList){
    }

    // Modifiers
    modifier onlySender {
        require(msg.sender == tx.origin, "No smart contracts!");
        _;
    }

    // Public view
    fallback() external payable {}

    /**
     * @dev Get token URI. Uses the URI prefix and suffix set by setBaseURI() to construct the full token URI.
     */
    function tokenURI(uint tokenId) external view override returns (string memory) {
        require(_exists(tokenId), "This token does not exist!");
        return string(abi.encodePacked(_tokenURIPrefix, tokenId.toString(), _tokenURISuffix));
    }

    /**
     * @dev Checks merkle proof to determine if address is allowlisted.
     */
    function isAllowListed(address address_, bytes32[] memory proof_) public view returns (bool) {
        bytes32 _leaf = keccak256(abi.encodePacked(address_));
        
        for (uint i = 0; i < proof_.length; i++) {
            _leaf = _leaf < proof_[i] ? keccak256(abi.encodePacked(_leaf, proof_[i])) : keccak256(abi.encodePacked(proof_[i], _leaf));
        }
        return _leaf == merkleRoot;
    }

    function tier(address address_) public view returns (uint tier_) {
        uint cccOwned = INft(cccAddress).walletOfOwner(address_).length;
        uint _tier = 1;
        if (cccOwned >= tierThreeQualifier) {
            _tier = 3;
        } else if (cccOwned >= tierTwoQualifier) {
            _tier = 2;
        } 
        return _tier;
    }

    event MintAsOwner(address indexed to, uint tokenId);
    event MintPublic(address indexed to, uint tokenId);
    event MintOG(address indexed to, uint tokenId);
    event MintReserve(address indexed to, uint tokenId);
    event MintAllowList(address indexed to, uint tokenId);

    // Public payable

    /**
     * @dev Mints CCC evolutions. Public sale is capped at 1000 tokens. Payable function expects sale price in ETH.
     */
    function mint(address to_, uint amount_) external payable onlySender {
        require(isMintActive, "Mint is not active!");
        uint cccOwned = INft(cccAddress).walletOfOwner(to_).length;
        uint _price = price;
        if (cccOwned >= tierThreeQualifier) {
            _price = priceTierThree;
        } else if (cccOwned >= tierTwoQualifier) {
            _price = priceTierTwo;
        } 
        require(msg.value >= _price * amount_, "Ether sent is not correct!");
        uint _supply = totalSupply();
        require(_supply + amount_ <= maxTokens, "Mint exceeds supply!");
        require(publicSaleMinted + amount_ <= publicSaleTokens, "Mint exceeds public sale supply!");
        for(uint i; i < amount_; ++i){
            publicSaleMinted++;
            uint _mintId = ++_supply;
            _mint(to_, _mintId);
            emit MintPublic(to_, _mintId);
        }
    }

    /**
     * @dev Reserve sale will be activated after OG Free claim period is expired. Unclaimed tokens can be minted here. Payable function expects sale price in ETH.
     */
    function mintReserve(uint amount_) external payable onlySender {
        require(isReserveSaleActive, "Reserve sale is not active!");
        require(msg.value >= price * amount_, "Ether sent is not correct!");
        uint _supply = totalSupply();
        require(_supply + amount_ <= maxTokens, "Mint exceeds supply!");
        require(reserveMinted + amount_ <= reserveTokens, "Mint exceeds reserve sale supply!");
        for(uint i; i < amount_; ++i){
            reserveMinted++;
            uint _mintId = ++_supply;
            _mint(msg.sender, _mintId);
            emit MintReserve(msg.sender, _mintId);
        }
    }

    // Public non-payable

    /**
     * @dev OG CCC Tokens 1-1000 can mint for free. Tokens are reserved until Reserve Sale is activated. 
     * Enter an array of owned, unclaimed tokens to claim one free mint per token.
     */
    function ogMint(uint[] calldata tokenId_) external onlySender {
        require(isMintActive, "Mint is not active!");
        require(!isReserveSaleActive, "Free mint for OGs is over!");
        for (uint i = 0; i < tokenId_.length; i++) {
            require(tokenId_[i] <= 1000, "Only OG CCC Tokens 1-1000 can mint!");
            require(INft(cccAddress).ownerOf(tokenId_[i]) == msg.sender, "Only OG CCC Token owner can mint!");
            Caveman memory _caveman = cavemen[tokenId_[i]];
            require(!_caveman.claimed, "Already claimed for this token!");
        }
        uint _supply = totalSupply();
        require(_supply + tokenId_.length <= maxTokens, "Mint exceeds supply!");
        for(uint i; i < tokenId_.length; ++i){
            reserveMinted++;
            Caveman storage _caveman = cavemen[tokenId_[i]];
            _caveman.claimed = true;
            uint _mintId = ++_supply;
            _mint(msg.sender, _mintId);
            emit MintOG(msg.sender, _mintId);       
        }  
    }

    /**
     * @dev Allowlisted users get one free mint with valid merkle proof. AllowListed mints count towards public sale mint allowance.
     */
    function mintAllowList(address to_, bytes32[] memory proof_) external onlySender {
        require(isMintActive, "Mint is not active!");
        require(isAllowListed(to_, proof_), "You are not on the AllowList!");
        require(addressToAllowListMinted[to_] != true, "Already minted!");
        uint _supply = totalSupply();
        require(_supply + 1 <= maxTokens, "Mint exceeds supply!");
        require(publicSaleMinted + 1 <= publicSaleTokens, "Mint exceeds public sale supply!");
        addressToAllowListMinted[to_] = true;
        publicSaleMinted++;
        uint _mintId = ++_supply;
        _mint(to_, _mintId);
        emit MintAllowList(to_, _mintId);
    }

    // Delegated payable
    /**
     * @dev DELEGATED FUNCTION: Burns token(s) from a specific address. Can only be called by contract delegates. Payable function accepts an arbitrary amount of ETH.
     */
    function burnFrom(address owner_, uint[] calldata tokenIds_) external payable onlyDelegates {
        for(uint i; i < tokenIds_.length; ++i){
            require(_exists(tokenIds_[i]), "Burn for nonexistent token");
            require(_owners[tokenIds_[i]] == owner_, "Owner mismatch");
            _burn(tokenIds_[i]);
        }
    }

    /**
     * @dev DELEGATED FUNCTION: Mints token(s) to specified address(es). Can only be called by contract delegates. Payable function accepts an arbitrary amount of ETH.
     */
    function mintTo(uint[] calldata amount_, address[] calldata recipient_) external payable onlyDelegates {
        require(amount_.length == recipient_.length, "Must provide equal quantities and recipients");

        uint _totalQuantity;
        uint _supply = totalSupply();
        for(uint i; i < amount_.length; ++i){
            _totalQuantity += amount_[i];
        }
        require(_supply + _totalQuantity <= maxTokens, "Mint exceeds supply!");

        for(uint i; i < recipient_.length; ++i){
            for(uint j; j < amount_[i]; ++j){
                uint _mintId = ++_supply;
                _mint(recipient_[i], _mintId);
                emit MintAsOwner(msg.sender, _mintId);
            }
        }
    }

    // Delegated nonpayable
    /**
     * @dev DELEGATED FUNCTION: Resurrects tokens(s) from burn address and airdrops them to specified address(es). Can only be called by contract delegates.
     */
    function resurrect(uint[] calldata tokenIds_, address[] calldata recipients_) external onlyDelegates {
        require(tokenIds_.length == recipients_.length, "Must provide equal tokenIds and recipients");

        address to;
        uint tokenId;
        address zero = address(0);
        for(uint i; i < tokenIds_.length; ++i){
            to = recipients_[i];
            require(recipients_[i] != address(0), "Cannot resurrect to the zero address!");

            tokenId = tokenIds_[i];
            require(!_exists(tokenId), "Cannot resurrect existing token!");

            _owners[tokenId] = to;
            // Clear approvals
            _approve(zero, tokenId);
            emit Transfer(zero, to, tokenId);
        }
    }

    /**
     * @dev DELEGATED FUNCTION: Toggles to activate Mint and Reserve Sale. Set isMintActive_ to 'true' to turn on mint. After OG Free claim
     * is expired, set isReserveSaleActive_ to 'true' to allow sale of remaining reserved tokens. Can only be called by contract delegates.
     */
    function setActive(bool isMintActive_, bool isReserveSaleActive_) external onlyDelegates {
        require(isMintActive != isMintActive_ || isReserveSaleActive != isReserveSaleActive_, "New value matches old");
        isMintActive = isMintActive_;
        isReserveSaleActive = isReserveSaleActive_;
    }

    /**
     * @dev DELEGATED FUNCTION: Sets contract address for Crypto Cave Club NFT collection. Can only be called by contract delegates.
     */
    function setCCCAddress(address cccAddress_) external onlyDelegates {
        require(cccAddress != cccAddress_, "New value matches old");
        cccAddress = cccAddress_;
    }

    /**
     * @dev DELEGATED FUNCTION: Sets base URI for token metadata. Can only be called by contract delegates.
     */
    function setBaseURI(string calldata newPrefix, string calldata newSuffix) external onlyDelegates {
        _tokenURIPrefix = newPrefix;
        _tokenURISuffix = newSuffix;
    }

    /**
     * @dev DELEGATED FUNCTION: Sets total supply. Token supply can only be increased. Can only be called by contract delegates.
     */
    function setMax(uint maxTokens_) external onlyDelegates {
        require(maxTokens != maxTokens_, "New value matches old");
        require(maxTokens_ >= totalSupply(), "Specified supply is lower than current balance");
        maxTokens = maxTokens_;
    }

    /**
     * @dev DELEGATED FUNCTION: Sets public sale price. Can only be called by contract delegates.
     */
    function setPrice(uint price_) external onlyDelegates {
        require(price != price_, "New value matches old");
        price = price_;
    }

    /**
     * @dev DELEGATED FUNCTION: Sets tier qualifier and price. Tier two cannot have a greater qualifier than tier three, 
     * and tier two price cannot be less than tier three. Can only be called by contract delegates.
     */
    function setTiers(uint tierTwoQualifier_, uint priceTierTwo_, uint tierThreeQualifier_, uint priceTierThree_) external onlyDelegates {
        require(tierTwoQualifier != tierTwoQualifier_ || priceTierTwo != priceTierTwo_ || tierThreeQualifier != tierThreeQualifier_ || priceTierThree != priceTierThree_, "New value matches old");
        require(tierTwoQualifier_ <= tierThreeQualifier_, "Tier order incorrect");
        require(priceTierTwo >= priceTierThree, "Tier order incorrect");
        tierTwoQualifier = tierTwoQualifier_;
        priceTierTwo = priceTierTwo_;
        tierThreeQualifier = tierThreeQualifier_;
        priceTierThree = priceTierThree_;
    }

    /**
     * @dev DELEGATED FUNCTION: Sets the AllowList merkle root. Can only be called by contract delegates.
     */
    function setMerkleRoot(bytes32 merkleRoot_) public onlyDelegates {
        merkleRoot = merkleRoot_;
    }

    // Owner
    /**
     * @dev OWNER FUNCTION: Add payee to contract. Can only be called by contract owner.
     */
    function addPayee(address account, uint256 shares_) external onlyOwner {
        _addPayee(account, shares_);
    }

    /**
     * @dev OWNER FUNCTION: Update payee information. Can only be called by contract owner.
     */
    function setPayee( uint index, address account, uint newShares ) external onlyOwner {
        _setPayee(index, account, newShares);
    }

    // Internal
    function _burn(uint tokenId) internal override {
        address curOwner = ERC721B.ownerOf(tokenId);

        // Clear approvals
        _approve(owner(), tokenId);
        _owners[tokenId] = address(0);
        emit Transfer(curOwner, address(0), tokenId);
    }

    function _mint(address to, uint tokenId) internal override {
        _owners.push(to);
        emit Transfer(address(0), to, tokenId);
    }

}

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":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"MintAllowList","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"MintAsOwner","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"MintOG","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"MintPublic","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"MintReserve","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"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"PayeeAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReceived","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReleased","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"},{"stateMutability":"payable","type":"fallback"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"shares_","type":"uint256"}],"name":"addPayee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"addressToAllowListMinted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner_","type":"address"},{"internalType":"uint256[]","name":"tokenIds_","type":"uint256[]"}],"name":"burnFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"cavemen","outputs":[{"internalType":"bool","name":"claimed","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"address_","type":"address"},{"internalType":"bytes32[]","name":"proof_","type":"bytes32[]"}],"name":"isAllowListed","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":"addr","type":"address"}],"name":"isDelegate","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isMintActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"isOwnerOf","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isReserveSaleActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"merkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to_","type":"address"},{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"to_","type":"address"},{"internalType":"bytes32[]","name":"proof_","type":"bytes32[]"}],"name":"mintAllowList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount_","type":"uint256"}],"name":"mintReserve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"amount_","type":"uint256[]"},{"internalType":"address[]","name":"recipient_","type":"address[]"}],"name":"mintTo","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenId_","type":"uint256[]"}],"name":"ogMint","outputs":[],"stateMutability":"nonpayable","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":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"payee","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceTierThree","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"priceTierTwo","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicSaleMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicSaleTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"account","type":"address"}],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"released","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reserveMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"reserveTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds_","type":"uint256[]"},{"internalType":"address[]","name":"recipients_","type":"address[]"}],"name":"resurrect","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":"bool","name":"isMintActive_","type":"bool"},{"internalType":"bool","name":"isReserveSaleActive_","type":"bool"}],"name":"setActive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"newPrefix","type":"string"},{"internalType":"string","name":"newSuffix","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"cccAddress_","type":"address"}],"name":"setCCCAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"bool","name":"isDelegate_","type":"bool"}],"name":"setDelegate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"maxTokens_","type":"uint256"}],"name":"setMax","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"merkleRoot_","type":"bytes32"}],"name":"setMerkleRoot","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"newShares","type":"uint256"}],"name":"setPayee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"price_","type":"uint256"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tierTwoQualifier_","type":"uint256"},{"internalType":"uint256","name":"priceTierTwo_","type":"uint256"},{"internalType":"uint256","name":"tierThreeQualifier_","type":"uint256"},{"internalType":"uint256","name":"priceTierThree_","type":"uint256"}],"name":"setTiers","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"shares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","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":"address","name":"address_","type":"address"}],"name":"tier","outputs":[{"internalType":"uint256","name":"tier_","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tierThreeQualifier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"tierTwoQualifier","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"toBeReleased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"tokenId","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":"totalReleased","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalShares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"tokenIds","type":"uint256[]"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"transferBatch","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":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"walletOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"stateMutability":"payable","type":"receive"}]

600f80546001600160a01b031916905560006010556109c46011556103e86012556105dc601490815566e6ed27d666800060165566d529ae9e86000060175566b1a2bc2ec50000601855600a601955601a55601b805462010000600160b01b031916759f7bb54da72c6fa94653c923aa5b31e22703ed53000017905560e0604052603c60808181529062004f2b60a0398051620000a591601c91602090910190620006d9565b5060408051808201909152600580825264173539b7b760d91b6020909201918252620000d491601d91620006d9565b507fc7526ce4aa36e3804e66b2bba3718eb56f596ee60f3b5cbb3d72e9af76632f5a602090815560408051808201909152731d4900db504e87f9ed2e17bc79af307cd632dea0815273bb78e3eee5b232aac20e1b25bc02beb289af7897918101919091526200014890602190600262000768565b5060408051808201909152605a8152600a60208201526200016e906022906002620007c0565b503480156200017c57600080fd5b506021805480602002602001604051908101604052809291908181526020018280548015620001d557602002820191906000526020600020905b81546001600160a01b03168152600190910190602001808311620001b6575b505050505060228054806020026020016040519081016040528092919081815260200182805480156200022857602002820191906000526020600020905b81548152602001906001019080831162000213575b50505050506040518060400160405280600881526020016745564f20426f747360c01b8152506040518060400160405280600381526020016245564f60e81b815250600162000286620002806200049760201b60201c565b6200049b565b60018060006200029e6000546001600160a01b031690565b6001600160a01b03168152602080820192909252604001600020805460ff1916921515929092179091558351620002dc9160029190860190620006d9565b508151620002f2906003906020850190620006d9565b50600581905560005b6005548110156200035957600680546001810182556000919091527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0180546001600160a01b0319169055620003518162000872565b9050620002fb565b505050508051825114620003cf5760405162461bcd60e51b815260206004820152603260248201527f5061796d656e7453706c69747465723a2070617965657320616e6420736861726044820152710cae640d8cadccee8d040dad2e6dac2e8c6d60731b60648201526084015b60405180910390fd5b6000825111620004225760405162461bcd60e51b815260206004820152601a60248201527f5061796d656e7453706c69747465723a206e6f207061796565730000000000006044820152606401620003c6565b60005b82518110156200048e5762000479838281518110620004485762000448620008a6565b6020026020010151838381518110620004655762000465620008a6565b6020026020010151620004eb60201b60201c565b80620004858162000872565b91505062000425565b505050620008bc565b3390565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b6001600160a01b038216620005585760405162461bcd60e51b815260206004820152602c60248201527f5061796d656e7453706c69747465723a206163636f756e74206973207468652060448201526b7a65726f206164647265737360a01b6064820152608401620003c6565b60008111620005aa5760405162461bcd60e51b815260206004820152601d60248201527f5061796d656e7453706c69747465723a207368617265732061726520300000006044820152606401620003c6565b6001600160a01b0382166000908152600c602052604090205415620006265760405162461bcd60e51b815260206004820152602b60248201527f5061796d656e7453706c69747465723a206163636f756e7420616c726561647960448201526a206861732073686172657360a81b6064820152608401620003c6565b600e8054600181019091557fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd0180546001600160a01b0319166001600160a01b0384169081179091556000908152600c60205260409020819055600a54620006909082906200081a565b600a55604080516001600160a01b0384168152602081018390527f40c340f65e17194d14ddddb073d3c9f888e3cb52b5aae0c6c7706b4fbc905fac910160405180910390a15050565b828054620006e79062000835565b90600052602060002090601f0160209004810192826200070b576000855562000756565b82601f106200072657805160ff191683800117855562000756565b8280016001018555821562000756579182015b828111156200075657825182559160200191906001019062000739565b506200076492915062000803565b5090565b82805482825590600052602060002090810192821562000756579160200282015b828111156200075657825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062000789565b82805482825590600052602060002090810192821562000756579160200282015b8281111562000756578251829060ff16905591602001919060010190620007e1565b5b8082111562000764576000815560010162000804565b6000821982111562000830576200083062000890565b500190565b600181811c908216806200084a57607f821691505b602082108114156200086c57634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141562000889576200088962000890565b5060010190565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b61465f80620008cc6000396000f3fe6080604052600436106103975760003560e01c806370a08231116101da578063b534a5c411610101578063e33b7de31161009a578063e985e9c51161006c578063e985e9c514610b23578063f2fde38b14610b6c578063f906751b14610b8c578063fe43c95514610b9f57005b8063e33b7de314610ac5578063e3696d0014610ada578063e831574214610afa578063e966d51214610b1057005b8063ce7c2ac2116100d3578063ce7c2ac214610a39578063d368284e14610a6f578063dd76a68b14610a8f578063df23880014610aa557005b8063b534a5c4146109b9578063b88d4fde146109d9578063bb39e029146109f9578063c87b56dd14610a1957005b80638da5cb5b116101735780639852595c116101455780639852595c14610937578063a035b1fe1461096d578063a22cb46514610983578063a666098d146109a357005b80638da5cb5b146108ce57806391b7f5ed146108ec57806395d89b411461090c57806396b982d31461092157005b806382a7dcf9116101ac57806382a7dcf914610866578063895f590b1461088557806389af61071461089b5780638b83209b146108ae57005b806370a08231146107f1578063715018a6146108115780637cb64759146108265780637f608d031461084657005b80632eb4a7ab116102be5780634d44660c116102575780636352211e116102295780636352211e14610771578063675a94231461079157806367762169146107b15780636790a9de146107d157005b80634d44660c146106e75780634f6ccce7146107075780635b92ac0d146107275780635eb236a71461074157005b806342842e0e1161029057806342842e0e14610664578063438b6300146106845780634a994eef146106b15780634c81433f146106d157005b80632eb4a7ab146106065780632f745c591461061c5780633a98ef391461063c57806340c10f191461065157005b8063193ec4d1116103305780632785f8bb116103025780632785f8bb1461059a57806327ac36c4146105ba5780632e7033c5146105d05780632e992fee146105e657005b8063193ec4d1146105145780631b49d44d146105445780631fe9eabc1461055a57806323b872dd1461057a57005b8063095ea7b311610369578063095ea7b31461049157806318160ddd146104b157806318f9b023146104d457806319165587146104f457005b806301ffc9a7146103e257806306fdde03146104175780630777962714610439578063081812fc1461045957005b366103e0577f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be77033604080516001600160a01b0390921682523460208301520160405180910390a1005b005b3480156103ee57600080fd5b506104026103fd366004613f72565b610bbf565b60405190151581526020015b60405180910390f35b34801561042357600080fd5b5061042c610bea565b60405161040e91906141de565b34801561044557600080fd5b50610402610454366004613a89565b610c7c565b34801561046557600080fd5b50610479610474366004613f59565b610cd3565b6040516001600160a01b03909116815260200161040e565b34801561049d57600080fd5b506103e06104ac366004613dce565b610d5b565b3480156104bd57600080fd5b506104c6610e71565b60405190815260200161040e565b3480156104e057600080fd5b506103e06104ef366004613dce565b610e95565b34801561050057600080fd5b506103e061050f366004613a89565b610ecd565b34801561052057600080fd5b5061040261052f366004613f59565b601e6020526000908152604090205460ff1681565b34801561055057600080fd5b506104c6601a5481565b34801561056657600080fd5b506103e0610575366004613f59565b6110e0565b34801561058657600080fd5b506103e0610595366004613b90565b6111a4565b3480156105a657600080fd5b506104c66105b5366004613a89565b6111d5565b3480156105c657600080fd5b506104c660125481565b3480156105dc57600080fd5b506104c660175481565b3480156105f257600080fd5b506103e0610601366004613a89565b61128d565b34801561061257600080fd5b506104c660205481565b34801561062857600080fd5b506104c6610637366004613dce565b61131a565b34801561064857600080fd5b50600a546104c6565b6103e061065f366004613dce565b6113e6565b34801561067057600080fd5b506103e061067f366004613b90565b61165d565b34801561069057600080fd5b506106a461069f366004613a89565b611678565b60405161040e919061419a565b3480156106bd57600080fd5b506103e06106cc366004613d99565b611717565b3480156106dd57600080fd5b506104c660135481565b3480156106f357600080fd5b50610402610702366004613d45565b61176c565b34801561071357600080fd5b506104c6610722366004613f59565b6117ec565b34801561073357600080fd5b50601b546104029060ff1681565b34801561074d57600080fd5b5061040261075c366004613a89565b601f6020526000908152604090205460ff1681565b34801561077d57600080fd5b5061047961078c366004613f59565b61185d565b34801561079d57600080fd5b506103e06107ac366004613dfa565b6118e9565b3480156107bd57600080fd5b506104026107cc366004613c94565b611ca9565b3480156107dd57600080fd5b506103e06107ec366004613fac565b611dcd565b3480156107fd57600080fd5b506104c661080c366004613a89565b611e1c565b34801561081d57600080fd5b506103e0611eea565b34801561083257600080fd5b506103e0610841366004613f59565b611f20565b34801561085257600080fd5b506103e0610861366004613f3d565b611f54565b34801561087257600080fd5b50601b5461040290610100900460ff1681565b34801561089157600080fd5b506104c660185481565b6103e06108a9366004613d45565b611fea565b3480156108ba57600080fd5b506104796108c9366004613f59565b61214a565b3480156108da57600080fd5b506000546001600160a01b0316610479565b3480156108f857600080fd5b506103e0610907366004613f59565b61217a565b34801561091857600080fd5b5061042c6121d0565b34801561092d57600080fd5b506104c660145481565b34801561094357600080fd5b506104c6610952366004613a89565b6001600160a01b03166000908152600d602052604090205490565b34801561097957600080fd5b506104c660165481565b34801561098f57600080fd5b506103e061099e366004613d99565b6121df565b3480156109af57600080fd5b506104c660155481565b3480156109c557600080fd5b506103e06109d4366004613afc565b6122a4565b3480156109e557600080fd5b506103e06109f4366004613bd1565b612322565b348015610a0557600080fd5b506103e0610a14366004613e3b565b612354565b348015610a2557600080fd5b5061042c610a34366004613f59565b6125b1565b348015610a4557600080fd5b506104c6610a54366004613a89565b6001600160a01b03166000908152600c602052604090205490565b348015610a7b57600080fd5b506103e0610a8a366004614032565b61263d565b348015610a9b57600080fd5b506104c660195481565b348015610ab157600080fd5b506103e0610ac036600461400b565b61275b565b348015610ad157600080fd5b50600b546104c6565b348015610ae657600080fd5b506103e0610af5366004613c94565b612790565b348015610b0657600080fd5b506104c660115481565b6103e0610b1e366004613e3b565b6129b9565b348015610b2f57600080fd5b50610402610b3e366004613ac3565b6001600160a01b03918216600090815260086020908152604080832093909416825291909152205460ff1690565b348015610b7857600080fd5b506103e0610b87366004613a89565b612b8b565b6103e0610b9a366004613f59565b612be7565b348015610bab57600080fd5b506104c6610bba366004613a89565b612ddc565b60006001600160e01b0319821663780e9d6360e01b1480610be45750610be482612e8b565b92915050565b606060028054610bf99061451c565b80601f0160208091040260200160405190810160405280929190818152602001828054610c259061451c565b8015610c725780601f10610c4757610100808354040283529160200191610c72565b820191906000526020600020905b815481529060010190602001808311610c5557829003601f168201915b5050505050905090565b600080546001600160a01b03163314610cb05760405162461bcd60e51b8152600401610ca790614386565b60405180910390fd5b506001600160a01b03811660009081526001602052604090205460ff165b919050565b6000610cde82612edb565b610d3f5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610ca7565b506000908152600760205260409020546001600160a01b031690565b6000610d668261185d565b9050806001600160a01b0316836001600160a01b03161415610dd45760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610ca7565b336001600160a01b0382161480610df05750610df08133610b3e565b610e625760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610ca7565b610e6c8383612f25565b505050565b6000600454600554610e83919061448e565b600654610e9091906144d9565b905090565b6000546001600160a01b03163314610ebf5760405162461bcd60e51b8152600401610ca790614386565b610ec98282612f93565b5050565b6001600160a01b0381166000908152600c6020526040902054610f025760405162461bcd60e51b8152600401610ca79061426d565b6000600b5447610f12919061448e565b6001600160a01b0383166000908152600d6020908152604080832054600a54600c909352908320549394509192610f4990856144ba565b610f5391906144a6565b610f5d91906144d9565b905080610f7c5760405162461bcd60e51b8152600401610ca79061430e565b600f546001600160a01b0384811691161415611041576001600160a01b0383166000908152600d6020526040812054610fb5908361448e565b905060105481111561103f576001600160a01b0384166000908152600d6020526040902054601054610fe791906144d9565b9150600c6000856001600160a01b03166001600160a01b0316815260200190815260200160002054600a600082825461102091906144d9565b90915550506001600160a01b0384166000908152600c60205260408120555b505b6001600160a01b0383166000908152600d602052604090205461106590829061448e565b6001600160a01b0384166000908152600d6020526040902055600b5461108c90829061448e565b600b556110998382613179565b604080516001600160a01b0385168152602081018390527fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b056910160405180910390a1505050565b3360009081526001602052604090205460ff1661110f5760405162461bcd60e51b8152600401610ca7906141f1565b8060115414156111315760405162461bcd60e51b8152600401610ca7906143bb565b611139610e71565b81101561119f5760405162461bcd60e51b815260206004820152602e60248201527f53706563696669656420737570706c79206973206c6f776572207468616e206360448201526d757272656e742062616c616e636560901b6064820152608401610ca7565b601155565b6111ae3382613292565b6111ca5760405162461bcd60e51b8152600401610ca7906143ea565b610e6c83838361337c565b601b5460405162438b6360e81b81526001600160a01b0383811660048301526000928392620100009091049091169063438b63009060240160006040518083038186803b15801561122557600080fd5b505afa158015611239573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526112619190810190613ea6565b51601a54909150600190821061127957506003611286565b6019548210611286575060025b9392505050565b3360009081526001602052604090205460ff166112bc5760405162461bcd60e51b8152600401610ca7906141f1565b601b546001600160a01b03828116620100009092041614156112f05760405162461bcd60e51b8152600401610ca7906143bb565b601b80546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b60008060005b600654811015611389576006818154811061133d5761133d6145b2565b6000918252602090912001546001600160a01b0386811691161415611379578382141561136d579150610be49050565b61137682614557565b91505b61138281614557565b9050611320565b5060405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610ca7565b3332146114055760405162461bcd60e51b8152600401610ca790614359565b601b5460ff166114275760405162461bcd60e51b8152600401610ca7906142b3565b601b5460405162438b6360e81b81526001600160a01b038481166004830152600092620100009004169063438b63009060240160006040518083038186803b15801561147257600080fd5b505afa158015611486573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526114ae9190810190613ea6565b51601654601a549192509082106114c857506018546114d6565b60195482106114d657506017545b6114e083826144ba565b34101561152f5760405162461bcd60e51b815260206004820152601a60248201527f45746865722073656e74206973206e6f7420636f7272656374210000000000006044820152606401610ca7565b6000611539610e71565b601154909150611549858361448e565b11156115675760405162461bcd60e51b8152600401610ca7906142e0565b60145484601554611578919061448e565b11156115c65760405162461bcd60e51b815260206004820181905260248201527f4d696e742065786365656473207075626c69632073616c6520737570706c79216044820152606401610ca7565b60005b8481101561165557601580549060006115e183614557565b91905055506000826115f290614557565b925082905061160187826134c0565b866001600160a01b03167f0615c0c48f3021bc9137e1071d4c1669eb7b35faed3a1b028dfd241b541b9c858260405161163c91815260200190565b60405180910390a25061164e81614557565b90506115c9565b505050505050565b610e6c83838360405180602001604052806000815250612322565b6060600061168583611e1c565b90506000816001600160401b038111156116a1576116a16145c8565b6040519080825280602002602001820160405280156116ca578160200160208202803683370190505b50905060005b8281101561170f576116e2858261131a565b8282815181106116f4576116f46145b2565b602090810291909101015261170881614557565b90506116d0565b509392505050565b6000546001600160a01b031633146117415760405162461bcd60e51b8152600401610ca790614386565b6001600160a01b03919091166000908152600160205260409020805460ff1916911515919091179055565b6000805b828110156117e157846001600160a01b03166006858584818110611796576117966145b2565b90506020020135815481106117ad576117ad6145b2565b6000918252602090912001546001600160a01b0316146117d1576000915050611286565b6117da81614557565b9050611770565b506001949350505050565b60006117f6610e71565b82106118595760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610ca7565b5090565b60008060068381548110611873576118736145b2565b6000918252602090912001546001600160a01b0316905080610be45760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610ca7565b3332146119085760405162461bcd60e51b8152600401610ca790614359565b601b5460ff1661192a5760405162461bcd60e51b8152600401610ca7906142b3565b601b54610100900460ff16156119825760405162461bcd60e51b815260206004820152601a60248201527f46726565206d696e7420666f72204f4773206973206f766572210000000000006044820152606401610ca7565b60005b81811015611baa576103e88383838181106119a2576119a26145b2565b905060200201351115611a035760405162461bcd60e51b815260206004820152602360248201527f4f6e6c79204f472043434320546f6b656e7320312d313030302063616e206d696044820152626e742160e81b6064820152608401610ca7565b601b5433906201000090046001600160a01b0316636352211e858585818110611a2e57611a2e6145b2565b905060200201356040518263ffffffff1660e01b8152600401611a5391815260200190565b60206040518083038186803b158015611a6b57600080fd5b505afa158015611a7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aa39190613aa6565b6001600160a01b031614611b035760405162461bcd60e51b815260206004820152602160248201527f4f6e6c79204f472043434320546f6b656e206f776e65722063616e206d696e746044820152602160f81b6064820152608401610ca7565b6000601e6000858585818110611b1b57611b1b6145b2565b6020908102929092013583525081810192909252604090810160002081519283019091525460ff161580158252909150611b975760405162461bcd60e51b815260206004820152601f60248201527f416c726561647920636c61696d656420666f72207468697320746f6b656e21006044820152606401610ca7565b5080611ba281614557565b915050611985565b506000611bb5610e71565b601154909150611bc5838361448e565b1115611be35760405162461bcd60e51b8152600401610ca7906142e0565b60005b82811015611ca35760138054906000611bfe83614557565b91905055506000601e6000868685818110611c1b57611c1b6145b2565b602090810292909201358352508101919091526040016000908120805460ff191660011781559150611c4c84614557565b9350839050611c5b33826134c0565b60405181815233907fa7b3857785cc726766b692213848c5a4f0a1439a2bff37e0aea09081eab3b7699060200160405180910390a2505080611c9c90614557565b9050611be6565b50505050565b6040516bffffffffffffffffffffffff19606084901b166020820152600090819060340160405160208183030381529060405280519060200120905060005b8351811015611dc157838181518110611d0357611d036145b2565b60200260200101518210611d6157838181518110611d2357611d236145b2565b602002602001015182604051602001611d46929190918252602082015260400190565b60405160208183030381529060405280519060200120611dad565b81848281518110611d7457611d746145b2565b6020026020010151604051602001611d96929190918252602082015260400190565b604051602081830303815290604052805190602001205b915080611db981614557565b915050611ce8565b50602054149392505050565b3360009081526001602052604090205460ff16611dfc5760405162461bcd60e51b8152600401610ca7906141f1565b611e08601c858561395d565b50611e15601d838361395d565b5050505050565b60006001600160a01b038216611e875760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610ca7565b6000805b600654811015611ee35760068181548110611ea857611ea86145b2565b6000918252602090912001546001600160a01b0385811691161415611ed357611ed082614557565b91505b611edc81614557565b9050611e8b565b5092915050565b6000546001600160a01b03163314611f145760405162461bcd60e51b8152600401610ca790614386565b611f1e600061352a565b565b3360009081526001602052604090205460ff16611f4f5760405162461bcd60e51b8152600401610ca7906141f1565b602055565b3360009081526001602052604090205460ff16611f835760405162461bcd60e51b8152600401610ca7906141f1565b601b5460ff161515821515141580611faa5750601b5460ff61010090910416151581151514155b611fc65760405162461bcd60e51b8152600401610ca7906143bb565b601b805461ffff191692151561ff0019169290921761010091151591909102179055565b3360009081526001602052604090205460ff166120195760405162461bcd60e51b8152600401610ca7906141f1565b60005b81811015611ca357612045838383818110612039576120396145b2565b90506020020135612edb565b6120915760405162461bcd60e51b815260206004820152601a60248201527f4275726e20666f72206e6f6e6578697374656e7420746f6b656e0000000000006044820152606401610ca7565b836001600160a01b031660068484848181106120af576120af6145b2565b90506020020135815481106120c6576120c66145b2565b6000918252602090912001546001600160a01b0316146121195760405162461bcd60e51b815260206004820152600e60248201526d09eeedccae440dad2e6dac2e8c6d60931b6044820152606401610ca7565b61213a83838381811061212e5761212e6145b2565b9050602002013561357a565b61214381614557565b905061201c565b6000600e828154811061215f5761215f6145b2565b6000918252602090912001546001600160a01b031692915050565b3360009081526001602052604090205460ff166121a95760405162461bcd60e51b8152600401610ca7906141f1565b8060165414156121cb5760405162461bcd60e51b8152600401610ca7906143bb565b601655565b606060038054610bf99061451c565b6001600160a01b0382163314156122385760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610ca7565b3360008181526008602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60005b838110156123195761230987878787858181106122c6576122c66145b2565b9050602002013586868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061232292505050565b61231281614557565b90506122a7565b50505050505050565b61232c3383613292565b6123485760405162461bcd60e51b8152600401610ca7906143ea565b611ca3848484846135fa565b3360009081526001602052604090205460ff166123835760405162461bcd60e51b8152600401610ca7906141f1565b8281146123e55760405162461bcd60e51b815260206004820152602a60248201527f4d7573742070726f7669646520657175616c20746f6b656e49647320616e6420604482015269726563697069656e747360b01b6064820152608401610ca7565b6000806000805b868110156125a757858582818110612406576124066145b2565b905060200201602081019061241b9190613a89565b93506000868683818110612431576124316145b2565b90506020020160208101906124469190613a89565b6001600160a01b031614156124ab5760405162461bcd60e51b815260206004820152602560248201527f43616e6e6f742072657375727265637420746f20746865207a65726f20616464604482015264726573732160d81b6064820152608401610ca7565b8787828181106124bd576124bd6145b2565b9050602002013592506124cf83612edb565b1561251c5760405162461bcd60e51b815260206004820181905260248201527f43616e6e6f7420726573757272656374206578697374696e6720746f6b656e216044820152606401610ca7565b8360068481548110612530576125306145b2565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506125688284612f25565b82846001600160a01b0316836001600160a01b031660008051602061460a83398151915260405160405180910390a46125a081614557565b90506123ec565b5050505050505050565b60606125bc82612edb565b6126085760405162461bcd60e51b815260206004820152601a60248201527f5468697320746f6b656e20646f6573206e6f74206578697374210000000000006044820152606401610ca7565b601c6126138361362d565b601d6040516020016126279392919061412a565b6040516020818303038152906040529050919050565b3360009081526001602052604090205460ff1661266c5760405162461bcd60e51b8152600401610ca7906141f1565b8360195414158061267f57508260175414155b8061268c575081601a5414155b8061269957508060185414155b6126b55760405162461bcd60e51b8152600401610ca7906143bb565b818411156126fc5760405162461bcd60e51b8152602060048201526014602482015273151a595c881bdc99195c881a5b98dbdc9c9958dd60621b6044820152606401610ca7565b60185460175410156127475760405162461bcd60e51b8152602060048201526014602482015273151a595c881bdc99195c881a5b98dbdc9c9958dd60621b6044820152606401610ca7565b601993909355601791909155601a55601855565b6000546001600160a01b031633146127855760405162461bcd60e51b8152600401610ca790614386565b610e6c83838361372a565b3332146127af5760405162461bcd60e51b8152600401610ca790614359565b601b5460ff166127d15760405162461bcd60e51b8152600401610ca7906142b3565b6127db8282611ca9565b6128275760405162461bcd60e51b815260206004820152601d60248201527f596f7520617265206e6f74206f6e2074686520416c6c6f774c697374210000006044820152606401610ca7565b6001600160a01b0382166000908152601f602052604090205460ff161515600114156128875760405162461bcd60e51b815260206004820152600f60248201526e416c7265616479206d696e7465642160881b6044820152606401610ca7565b6000612891610e71565b6011549091506128a282600161448e565b11156128c05760405162461bcd60e51b8152600401610ca7906142e0565b6014546015546128d190600161448e565b111561291f5760405162461bcd60e51b815260206004820181905260248201527f4d696e742065786365656473207075626c69632073616c6520737570706c79216044820152606401610ca7565b6001600160a01b0383166000908152601f60205260408120805460ff19166001179055601580549161295083614557565b919050555060008161296190614557565b915081905061297084826134c0565b836001600160a01b03167ff3bd2c31b93b14908ac278cbe66c80fe1191219f21812080ca54857229cfefb7826040516129ab91815260200190565b60405180910390a250505050565b3360009081526001602052604090205460ff166129e85760405162461bcd60e51b8152600401610ca7906141f1565b828114612a4c5760405162461bcd60e51b815260206004820152602c60248201527f4d7573742070726f7669646520657175616c207175616e74697469657320616e60448201526b6420726563697069656e747360a01b6064820152608401610ca7565b600080612a57610e71565b905060005b85811015612a9a57868682818110612a7657612a766145b2565b9050602002013583612a88919061448e565b9250612a9381614557565b9050612a5c565b50601154612aa8838361448e565b1115612ac65760405162461bcd60e51b8152600401610ca7906142e0565b60005b838110156123195760005b878783818110612ae657612ae66145b2565b90506020020135811015612b7a576000612aff84614557565b9350839050612b34878785818110612b1957612b196145b2565b9050602002016020810190612b2e9190613a89565b826134c0565b60405181815233907f82bff94c69b4a624bb0d25e15735cf4189fdc4706e6b6806c94886b0009f2bdf9060200160405180910390a250612b7381614557565b9050612ad4565b50612b8481614557565b9050612ac9565b6000546001600160a01b03163314612bb55760405162461bcd60e51b8152600401610ca790614386565b6001600160a01b0381166000908152600160208190526040909120805460ff19169091179055612be4816137c3565b50565b333214612c065760405162461bcd60e51b8152600401610ca790614359565b601b54610100900460ff16612c5d5760405162461bcd60e51b815260206004820152601b60248201527f526573657276652073616c65206973206e6f74206163746976652100000000006044820152606401610ca7565b80601654612c6b91906144ba565b341015612cba5760405162461bcd60e51b815260206004820152601a60248201527f45746865722073656e74206973206e6f7420636f7272656374210000000000006044820152606401610ca7565b6000612cc4610e71565b601154909150612cd4838361448e565b1115612cf25760405162461bcd60e51b8152600401610ca7906142e0565b60125482601354612d03919061448e565b1115612d5b5760405162461bcd60e51b815260206004820152602160248201527f4d696e74206578636565647320726573657276652073616c6520737570706c796044820152602160f81b6064820152608401610ca7565b60005b82811015610e6c5760138054906000612d7683614557565b9190505550600082612d8790614557565b9250829050612d9633826134c0565b60405181815233907f85cb96374a3618ea44ac1b34a735c719a8ee3155cb7ac8cc0a8994e3906dae669060200160405180910390a250612dd581614557565b9050612d5e565b6001600160a01b0381166000908152600c6020526040812054612e115760405162461bcd60e51b8152600401610ca79061426d565b6000600b5447612e21919061448e565b6001600160a01b0384166000908152600d6020908152604080832054600a54600c909352908320549394509192612e5890856144ba565b612e6291906144a6565b612e6c91906144d9565b9050806112865760405162461bcd60e51b8152600401610ca79061430e565b60006001600160e01b031982166380ac58cd60e01b1480612ebc57506001600160e01b03198216635b5e139f60e01b145b80610be457506301ffc9a760e01b6001600160e01b0319831614610be4565b60065460009082108015610be4575060006001600160a01b031660068381548110612f0857612f086145b2565b6000918252602090912001546001600160a01b0316141592915050565b600081815260076020526040902080546001600160a01b0319166001600160a01b0384169081179091558190612f5a8261185d565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6001600160a01b038216612ffe5760405162461bcd60e51b815260206004820152602c60248201527f5061796d656e7453706c69747465723a206163636f756e74206973207468652060448201526b7a65726f206164647265737360a01b6064820152608401610ca7565b6000811161304e5760405162461bcd60e51b815260206004820152601d60248201527f5061796d656e7453706c69747465723a207368617265732061726520300000006044820152606401610ca7565b6001600160a01b0382166000908152600c6020526040902054156130c85760405162461bcd60e51b815260206004820152602b60248201527f5061796d656e7453706c69747465723a206163636f756e7420616c726561647960448201526a206861732073686172657360a81b6064820152608401610ca7565b600e8054600181019091557fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd0180546001600160a01b0319166001600160a01b0384169081179091556000908152600c60205260409020819055600a5461313090829061448e565b600a55604080516001600160a01b0384168152602081018390527f40c340f65e17194d14ddddb073d3c9f888e3cb52b5aae0c6c7706b4fbc905fac910160405180910390a15050565b804710156131c95760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610ca7565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114613216576040519150601f19603f3d011682016040523d82523d6000602084013e61321b565b606091505b5050905080610e6c5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610ca7565b600061329d82612edb565b6132fe5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610ca7565b60006133098361185d565b9050806001600160a01b0316846001600160a01b031614806133445750836001600160a01b031661333984610cd3565b6001600160a01b0316145b8061337457506001600160a01b0380821660009081526008602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b031661338f8261185d565b6001600160a01b0316146133f75760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610ca7565b6001600160a01b0382166134595760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610ca7565b613464600082612f25565b8160068281548110613478576134786145b2565b6000918252602082200180546001600160a01b0319166001600160a01b039384161790556040518392858116929087169160008051602061460a8339815191529190a4505050565b6006805460018101825560009182527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0180546001600160a01b0319166001600160a01b03851690811790915560405183929060008051602061460a833981519152908290a45050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006135858261185d565b90506135a261359c6000546001600160a01b031690565b83612f25565b6000600683815481106135b7576135b76145b2565b6000918252602082200180546001600160a01b0319166001600160a01b03938416179055604051849284169060008051602061460a833981519152908390a45050565b61360584848461337c565b6136118484848461385b565b611ca35760405162461bcd60e51b8152600401610ca79061421b565b6060816136515750506040805180820190915260018152600360fc1b602082015290565b8160005b811561367b578061366581614557565b91506136749050600a836144a6565b9150613655565b6000816001600160401b03811115613695576136956145c8565b6040519080825280601f01601f1916602001820160405280156136bf576020820181803683370190505b5090505b8415613374576136d46001836144d9565b91506136e1600a86614572565b6136ec90603061448e565b60f81b818381518110613701576137016145b2565b60200101906001600160f81b031916908160001a905350613723600a866144a6565b94506136c3565b6001600160a01b0382166000908152600c6020526040902054600a548291613751916144d9565b61375b919061448e565b600a556001600160a01b0382166000908152600c60205260409020819055600e805483919085908110613790576137906145b2565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550505050565b6000546001600160a01b031633146137ed5760405162461bcd60e51b8152600401610ca790614386565b6001600160a01b0381166138525760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610ca7565b612be48161352a565b60006001600160a01b0384163b156117e157604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061389f90339089908890889060040161415d565b602060405180830381600087803b1580156138b957600080fd5b505af19250505080156138e9575060408051601f3d908101601f191682019092526138e691810190613f8f565b60015b613943573d808015613917576040519150601f19603f3d011682016040523d82523d6000602084013e61391c565b606091505b50805161393b5760405162461bcd60e51b8152600401610ca79061421b565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050613374565b8280546139699061451c565b90600052602060002090601f01602090048101928261398b57600085556139d1565b82601f106139a45782800160ff198235161785556139d1565b828001600101855582156139d1579182015b828111156139d15782358255916020019190600101906139b6565b506118599291505b8082111561185957600081556001016139d9565b60008083601f8401126139ff57600080fd5b5081356001600160401b03811115613a1657600080fd5b6020830191508360208260051b8501011115613a3157600080fd5b9250929050565b80358015158114610cce57600080fd5b60008083601f840112613a5a57600080fd5b5081356001600160401b03811115613a7157600080fd5b602083019150836020828501011115613a3157600080fd5b600060208284031215613a9b57600080fd5b8135611286816145de565b600060208284031215613ab857600080fd5b8151611286816145de565b60008060408385031215613ad657600080fd5b8235613ae1816145de565b91506020830135613af1816145de565b809150509250929050565b60008060008060008060808789031215613b1557600080fd5b8635613b20816145de565b95506020870135613b30816145de565b945060408701356001600160401b0380821115613b4c57600080fd5b613b588a838b016139ed565b90965094506060890135915080821115613b7157600080fd5b50613b7e89828a01613a48565b979a9699509497509295939492505050565b600080600060608486031215613ba557600080fd5b8335613bb0816145de565b92506020840135613bc0816145de565b929592945050506040919091013590565b60008060008060808587031215613be757600080fd5b8435613bf2816145de565b9350602085810135613c03816145de565b93506040860135925060608601356001600160401b0380821115613c2657600080fd5b818801915088601f830112613c3a57600080fd5b813581811115613c4c57613c4c6145c8565b613c5e601f8201601f1916850161443b565b91508082528984828501011115613c7457600080fd5b808484018584013760008482840101525080935050505092959194509250565b60008060408385031215613ca757600080fd5b8235613cb2816145de565b91506020838101356001600160401b03811115613cce57600080fd5b8401601f81018613613cdf57600080fd5b8035613cf2613ced8261446b565b61443b565b80828252848201915084840189868560051b8701011115613d1257600080fd5b600094505b83851015613d35578035835260019490940193918501918501613d17565b5080955050505050509250929050565b600080600060408486031215613d5a57600080fd5b8335613d65816145de565b925060208401356001600160401b03811115613d8057600080fd5b613d8c868287016139ed565b9497909650939450505050565b60008060408385031215613dac57600080fd5b8235613db7816145de565b9150613dc560208401613a38565b90509250929050565b60008060408385031215613de157600080fd5b8235613dec816145de565b946020939093013593505050565b60008060208385031215613e0d57600080fd5b82356001600160401b03811115613e2357600080fd5b613e2f858286016139ed565b90969095509350505050565b60008060008060408587031215613e5157600080fd5b84356001600160401b0380821115613e6857600080fd5b613e74888389016139ed565b90965094506020870135915080821115613e8d57600080fd5b50613e9a878288016139ed565b95989497509550505050565b60006020808385031215613eb957600080fd5b82516001600160401b03811115613ecf57600080fd5b8301601f81018513613ee057600080fd5b8051613eee613ced8261446b565b80828252848201915084840188868560051b8701011115613f0e57600080fd5b600094505b83851015613f31578051835260019490940193918501918501613f13565b50979650505050505050565b60008060408385031215613f5057600080fd5b613db783613a38565b600060208284031215613f6b57600080fd5b5035919050565b600060208284031215613f8457600080fd5b8135611286816145f3565b600060208284031215613fa157600080fd5b8151611286816145f3565b60008060008060408587031215613fc257600080fd5b84356001600160401b0380821115613fd957600080fd5b613fe588838901613a48565b90965094506020870135915080821115613ffe57600080fd5b50613e9a87828801613a48565b60008060006060848603121561402057600080fd5b833592506020840135613bc0816145de565b6000806000806080858703121561404857600080fd5b5050823594602084013594506040840135936060013592509050565b6000815180845261407c8160208601602086016144f0565b601f01601f19169290920160200192915050565b8054600090600181811c90808316806140aa57607f831692505b60208084108214156140cc57634e487b7160e01b600052602260045260246000fd5b8180156140e057600181146140f15761411e565b60ff1986168952848901965061411e565b60008881526020902060005b868110156141165781548b8201529085019083016140fd565b505084890196505b50505050505092915050565b60006141368286614090565b84516141468183602089016144f0565b61415281830186614090565b979650505050505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061419090830184614064565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156141d2578351835292840192918401916001016141b6565b50909695505050505050565b6020815260006112866020830184614064565b60208082526010908201526f496e76616c69642064656c656761746560801b604082015260600190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526026908201527f5061796d656e7453706c69747465723a206163636f756e7420686173206e6f2060408201526573686172657360d01b606082015260800190565b6020808252601390820152724d696e74206973206e6f74206163746976652160681b604082015260600190565b6020808252601490820152734d696e74206578636565647320737570706c792160601b604082015260600190565b6020808252602b908201527f5061796d656e7453706c69747465723a206163636f756e74206973206e6f742060408201526a191d59481c185e5b595b9d60aa1b606082015260800190565b6020808252601390820152724e6f20736d61727420636f6e7472616374732160681b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526015908201527413995dc81d985b1d59481b585d18da195cc81bdb19605a1b604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b604051601f8201601f191681016001600160401b0381118282101715614463576144636145c8565b604052919050565b60006001600160401b03821115614484576144846145c8565b5060051b60200190565b600082198211156144a1576144a1614586565b500190565b6000826144b5576144b561459c565b500490565b60008160001904831182151516156144d4576144d4614586565b500290565b6000828210156144eb576144eb614586565b500390565b60005b8381101561450b5781810151838201526020016144f3565b83811115611ca35750506000910152565b600181811c9082168061453057607f821691505b6020821081141561455157634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141561456b5761456b614586565b5060010190565b6000826145815761458161459c565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114612be457600080fd5b6001600160e01b031981168114612be457600080fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa264697066735822122047d4a4e83b14dea2402c32d3633606f1169451edc2ae47c8eb3da218fdd3a8f964736f6c6343000807003368747470733a2f2f63727970746f63617665636c75622e73332e616d617a6f6e6177732e636f6d2f7075626c69632f6d657461646174612f65766f2f

Deployed Bytecode

0x6080604052600436106103975760003560e01c806370a08231116101da578063b534a5c411610101578063e33b7de31161009a578063e985e9c51161006c578063e985e9c514610b23578063f2fde38b14610b6c578063f906751b14610b8c578063fe43c95514610b9f57005b8063e33b7de314610ac5578063e3696d0014610ada578063e831574214610afa578063e966d51214610b1057005b8063ce7c2ac2116100d3578063ce7c2ac214610a39578063d368284e14610a6f578063dd76a68b14610a8f578063df23880014610aa557005b8063b534a5c4146109b9578063b88d4fde146109d9578063bb39e029146109f9578063c87b56dd14610a1957005b80638da5cb5b116101735780639852595c116101455780639852595c14610937578063a035b1fe1461096d578063a22cb46514610983578063a666098d146109a357005b80638da5cb5b146108ce57806391b7f5ed146108ec57806395d89b411461090c57806396b982d31461092157005b806382a7dcf9116101ac57806382a7dcf914610866578063895f590b1461088557806389af61071461089b5780638b83209b146108ae57005b806370a08231146107f1578063715018a6146108115780637cb64759146108265780637f608d031461084657005b80632eb4a7ab116102be5780634d44660c116102575780636352211e116102295780636352211e14610771578063675a94231461079157806367762169146107b15780636790a9de146107d157005b80634d44660c146106e75780634f6ccce7146107075780635b92ac0d146107275780635eb236a71461074157005b806342842e0e1161029057806342842e0e14610664578063438b6300146106845780634a994eef146106b15780634c81433f146106d157005b80632eb4a7ab146106065780632f745c591461061c5780633a98ef391461063c57806340c10f191461065157005b8063193ec4d1116103305780632785f8bb116103025780632785f8bb1461059a57806327ac36c4146105ba5780632e7033c5146105d05780632e992fee146105e657005b8063193ec4d1146105145780631b49d44d146105445780631fe9eabc1461055a57806323b872dd1461057a57005b8063095ea7b311610369578063095ea7b31461049157806318160ddd146104b157806318f9b023146104d457806319165587146104f457005b806301ffc9a7146103e257806306fdde03146104175780630777962714610439578063081812fc1461045957005b366103e0577f6ef95f06320e7a25a04a175ca677b7052bdd97131872c2192525a629f51be77033604080516001600160a01b0390921682523460208301520160405180910390a1005b005b3480156103ee57600080fd5b506104026103fd366004613f72565b610bbf565b60405190151581526020015b60405180910390f35b34801561042357600080fd5b5061042c610bea565b60405161040e91906141de565b34801561044557600080fd5b50610402610454366004613a89565b610c7c565b34801561046557600080fd5b50610479610474366004613f59565b610cd3565b6040516001600160a01b03909116815260200161040e565b34801561049d57600080fd5b506103e06104ac366004613dce565b610d5b565b3480156104bd57600080fd5b506104c6610e71565b60405190815260200161040e565b3480156104e057600080fd5b506103e06104ef366004613dce565b610e95565b34801561050057600080fd5b506103e061050f366004613a89565b610ecd565b34801561052057600080fd5b5061040261052f366004613f59565b601e6020526000908152604090205460ff1681565b34801561055057600080fd5b506104c6601a5481565b34801561056657600080fd5b506103e0610575366004613f59565b6110e0565b34801561058657600080fd5b506103e0610595366004613b90565b6111a4565b3480156105a657600080fd5b506104c66105b5366004613a89565b6111d5565b3480156105c657600080fd5b506104c660125481565b3480156105dc57600080fd5b506104c660175481565b3480156105f257600080fd5b506103e0610601366004613a89565b61128d565b34801561061257600080fd5b506104c660205481565b34801561062857600080fd5b506104c6610637366004613dce565b61131a565b34801561064857600080fd5b50600a546104c6565b6103e061065f366004613dce565b6113e6565b34801561067057600080fd5b506103e061067f366004613b90565b61165d565b34801561069057600080fd5b506106a461069f366004613a89565b611678565b60405161040e919061419a565b3480156106bd57600080fd5b506103e06106cc366004613d99565b611717565b3480156106dd57600080fd5b506104c660135481565b3480156106f357600080fd5b50610402610702366004613d45565b61176c565b34801561071357600080fd5b506104c6610722366004613f59565b6117ec565b34801561073357600080fd5b50601b546104029060ff1681565b34801561074d57600080fd5b5061040261075c366004613a89565b601f6020526000908152604090205460ff1681565b34801561077d57600080fd5b5061047961078c366004613f59565b61185d565b34801561079d57600080fd5b506103e06107ac366004613dfa565b6118e9565b3480156107bd57600080fd5b506104026107cc366004613c94565b611ca9565b3480156107dd57600080fd5b506103e06107ec366004613fac565b611dcd565b3480156107fd57600080fd5b506104c661080c366004613a89565b611e1c565b34801561081d57600080fd5b506103e0611eea565b34801561083257600080fd5b506103e0610841366004613f59565b611f20565b34801561085257600080fd5b506103e0610861366004613f3d565b611f54565b34801561087257600080fd5b50601b5461040290610100900460ff1681565b34801561089157600080fd5b506104c660185481565b6103e06108a9366004613d45565b611fea565b3480156108ba57600080fd5b506104796108c9366004613f59565b61214a565b3480156108da57600080fd5b506000546001600160a01b0316610479565b3480156108f857600080fd5b506103e0610907366004613f59565b61217a565b34801561091857600080fd5b5061042c6121d0565b34801561092d57600080fd5b506104c660145481565b34801561094357600080fd5b506104c6610952366004613a89565b6001600160a01b03166000908152600d602052604090205490565b34801561097957600080fd5b506104c660165481565b34801561098f57600080fd5b506103e061099e366004613d99565b6121df565b3480156109af57600080fd5b506104c660155481565b3480156109c557600080fd5b506103e06109d4366004613afc565b6122a4565b3480156109e557600080fd5b506103e06109f4366004613bd1565b612322565b348015610a0557600080fd5b506103e0610a14366004613e3b565b612354565b348015610a2557600080fd5b5061042c610a34366004613f59565b6125b1565b348015610a4557600080fd5b506104c6610a54366004613a89565b6001600160a01b03166000908152600c602052604090205490565b348015610a7b57600080fd5b506103e0610a8a366004614032565b61263d565b348015610a9b57600080fd5b506104c660195481565b348015610ab157600080fd5b506103e0610ac036600461400b565b61275b565b348015610ad157600080fd5b50600b546104c6565b348015610ae657600080fd5b506103e0610af5366004613c94565b612790565b348015610b0657600080fd5b506104c660115481565b6103e0610b1e366004613e3b565b6129b9565b348015610b2f57600080fd5b50610402610b3e366004613ac3565b6001600160a01b03918216600090815260086020908152604080832093909416825291909152205460ff1690565b348015610b7857600080fd5b506103e0610b87366004613a89565b612b8b565b6103e0610b9a366004613f59565b612be7565b348015610bab57600080fd5b506104c6610bba366004613a89565b612ddc565b60006001600160e01b0319821663780e9d6360e01b1480610be45750610be482612e8b565b92915050565b606060028054610bf99061451c565b80601f0160208091040260200160405190810160405280929190818152602001828054610c259061451c565b8015610c725780601f10610c4757610100808354040283529160200191610c72565b820191906000526020600020905b815481529060010190602001808311610c5557829003601f168201915b5050505050905090565b600080546001600160a01b03163314610cb05760405162461bcd60e51b8152600401610ca790614386565b60405180910390fd5b506001600160a01b03811660009081526001602052604090205460ff165b919050565b6000610cde82612edb565b610d3f5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610ca7565b506000908152600760205260409020546001600160a01b031690565b6000610d668261185d565b9050806001600160a01b0316836001600160a01b03161415610dd45760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610ca7565b336001600160a01b0382161480610df05750610df08133610b3e565b610e625760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610ca7565b610e6c8383612f25565b505050565b6000600454600554610e83919061448e565b600654610e9091906144d9565b905090565b6000546001600160a01b03163314610ebf5760405162461bcd60e51b8152600401610ca790614386565b610ec98282612f93565b5050565b6001600160a01b0381166000908152600c6020526040902054610f025760405162461bcd60e51b8152600401610ca79061426d565b6000600b5447610f12919061448e565b6001600160a01b0383166000908152600d6020908152604080832054600a54600c909352908320549394509192610f4990856144ba565b610f5391906144a6565b610f5d91906144d9565b905080610f7c5760405162461bcd60e51b8152600401610ca79061430e565b600f546001600160a01b0384811691161415611041576001600160a01b0383166000908152600d6020526040812054610fb5908361448e565b905060105481111561103f576001600160a01b0384166000908152600d6020526040902054601054610fe791906144d9565b9150600c6000856001600160a01b03166001600160a01b0316815260200190815260200160002054600a600082825461102091906144d9565b90915550506001600160a01b0384166000908152600c60205260408120555b505b6001600160a01b0383166000908152600d602052604090205461106590829061448e565b6001600160a01b0384166000908152600d6020526040902055600b5461108c90829061448e565b600b556110998382613179565b604080516001600160a01b0385168152602081018390527fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b056910160405180910390a1505050565b3360009081526001602052604090205460ff1661110f5760405162461bcd60e51b8152600401610ca7906141f1565b8060115414156111315760405162461bcd60e51b8152600401610ca7906143bb565b611139610e71565b81101561119f5760405162461bcd60e51b815260206004820152602e60248201527f53706563696669656420737570706c79206973206c6f776572207468616e206360448201526d757272656e742062616c616e636560901b6064820152608401610ca7565b601155565b6111ae3382613292565b6111ca5760405162461bcd60e51b8152600401610ca7906143ea565b610e6c83838361337c565b601b5460405162438b6360e81b81526001600160a01b0383811660048301526000928392620100009091049091169063438b63009060240160006040518083038186803b15801561122557600080fd5b505afa158015611239573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526112619190810190613ea6565b51601a54909150600190821061127957506003611286565b6019548210611286575060025b9392505050565b3360009081526001602052604090205460ff166112bc5760405162461bcd60e51b8152600401610ca7906141f1565b601b546001600160a01b03828116620100009092041614156112f05760405162461bcd60e51b8152600401610ca7906143bb565b601b80546001600160a01b03909216620100000262010000600160b01b0319909216919091179055565b60008060005b600654811015611389576006818154811061133d5761133d6145b2565b6000918252602090912001546001600160a01b0386811691161415611379578382141561136d579150610be49050565b61137682614557565b91505b61138281614557565b9050611320565b5060405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610ca7565b3332146114055760405162461bcd60e51b8152600401610ca790614359565b601b5460ff166114275760405162461bcd60e51b8152600401610ca7906142b3565b601b5460405162438b6360e81b81526001600160a01b038481166004830152600092620100009004169063438b63009060240160006040518083038186803b15801561147257600080fd5b505afa158015611486573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526114ae9190810190613ea6565b51601654601a549192509082106114c857506018546114d6565b60195482106114d657506017545b6114e083826144ba565b34101561152f5760405162461bcd60e51b815260206004820152601a60248201527f45746865722073656e74206973206e6f7420636f7272656374210000000000006044820152606401610ca7565b6000611539610e71565b601154909150611549858361448e565b11156115675760405162461bcd60e51b8152600401610ca7906142e0565b60145484601554611578919061448e565b11156115c65760405162461bcd60e51b815260206004820181905260248201527f4d696e742065786365656473207075626c69632073616c6520737570706c79216044820152606401610ca7565b60005b8481101561165557601580549060006115e183614557565b91905055506000826115f290614557565b925082905061160187826134c0565b866001600160a01b03167f0615c0c48f3021bc9137e1071d4c1669eb7b35faed3a1b028dfd241b541b9c858260405161163c91815260200190565b60405180910390a25061164e81614557565b90506115c9565b505050505050565b610e6c83838360405180602001604052806000815250612322565b6060600061168583611e1c565b90506000816001600160401b038111156116a1576116a16145c8565b6040519080825280602002602001820160405280156116ca578160200160208202803683370190505b50905060005b8281101561170f576116e2858261131a565b8282815181106116f4576116f46145b2565b602090810291909101015261170881614557565b90506116d0565b509392505050565b6000546001600160a01b031633146117415760405162461bcd60e51b8152600401610ca790614386565b6001600160a01b03919091166000908152600160205260409020805460ff1916911515919091179055565b6000805b828110156117e157846001600160a01b03166006858584818110611796576117966145b2565b90506020020135815481106117ad576117ad6145b2565b6000918252602090912001546001600160a01b0316146117d1576000915050611286565b6117da81614557565b9050611770565b506001949350505050565b60006117f6610e71565b82106118595760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610ca7565b5090565b60008060068381548110611873576118736145b2565b6000918252602090912001546001600160a01b0316905080610be45760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610ca7565b3332146119085760405162461bcd60e51b8152600401610ca790614359565b601b5460ff1661192a5760405162461bcd60e51b8152600401610ca7906142b3565b601b54610100900460ff16156119825760405162461bcd60e51b815260206004820152601a60248201527f46726565206d696e7420666f72204f4773206973206f766572210000000000006044820152606401610ca7565b60005b81811015611baa576103e88383838181106119a2576119a26145b2565b905060200201351115611a035760405162461bcd60e51b815260206004820152602360248201527f4f6e6c79204f472043434320546f6b656e7320312d313030302063616e206d696044820152626e742160e81b6064820152608401610ca7565b601b5433906201000090046001600160a01b0316636352211e858585818110611a2e57611a2e6145b2565b905060200201356040518263ffffffff1660e01b8152600401611a5391815260200190565b60206040518083038186803b158015611a6b57600080fd5b505afa158015611a7f573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611aa39190613aa6565b6001600160a01b031614611b035760405162461bcd60e51b815260206004820152602160248201527f4f6e6c79204f472043434320546f6b656e206f776e65722063616e206d696e746044820152602160f81b6064820152608401610ca7565b6000601e6000858585818110611b1b57611b1b6145b2565b6020908102929092013583525081810192909252604090810160002081519283019091525460ff161580158252909150611b975760405162461bcd60e51b815260206004820152601f60248201527f416c726561647920636c61696d656420666f72207468697320746f6b656e21006044820152606401610ca7565b5080611ba281614557565b915050611985565b506000611bb5610e71565b601154909150611bc5838361448e565b1115611be35760405162461bcd60e51b8152600401610ca7906142e0565b60005b82811015611ca35760138054906000611bfe83614557565b91905055506000601e6000868685818110611c1b57611c1b6145b2565b602090810292909201358352508101919091526040016000908120805460ff191660011781559150611c4c84614557565b9350839050611c5b33826134c0565b60405181815233907fa7b3857785cc726766b692213848c5a4f0a1439a2bff37e0aea09081eab3b7699060200160405180910390a2505080611c9c90614557565b9050611be6565b50505050565b6040516bffffffffffffffffffffffff19606084901b166020820152600090819060340160405160208183030381529060405280519060200120905060005b8351811015611dc157838181518110611d0357611d036145b2565b60200260200101518210611d6157838181518110611d2357611d236145b2565b602002602001015182604051602001611d46929190918252602082015260400190565b60405160208183030381529060405280519060200120611dad565b81848281518110611d7457611d746145b2565b6020026020010151604051602001611d96929190918252602082015260400190565b604051602081830303815290604052805190602001205b915080611db981614557565b915050611ce8565b50602054149392505050565b3360009081526001602052604090205460ff16611dfc5760405162461bcd60e51b8152600401610ca7906141f1565b611e08601c858561395d565b50611e15601d838361395d565b5050505050565b60006001600160a01b038216611e875760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610ca7565b6000805b600654811015611ee35760068181548110611ea857611ea86145b2565b6000918252602090912001546001600160a01b0385811691161415611ed357611ed082614557565b91505b611edc81614557565b9050611e8b565b5092915050565b6000546001600160a01b03163314611f145760405162461bcd60e51b8152600401610ca790614386565b611f1e600061352a565b565b3360009081526001602052604090205460ff16611f4f5760405162461bcd60e51b8152600401610ca7906141f1565b602055565b3360009081526001602052604090205460ff16611f835760405162461bcd60e51b8152600401610ca7906141f1565b601b5460ff161515821515141580611faa5750601b5460ff61010090910416151581151514155b611fc65760405162461bcd60e51b8152600401610ca7906143bb565b601b805461ffff191692151561ff0019169290921761010091151591909102179055565b3360009081526001602052604090205460ff166120195760405162461bcd60e51b8152600401610ca7906141f1565b60005b81811015611ca357612045838383818110612039576120396145b2565b90506020020135612edb565b6120915760405162461bcd60e51b815260206004820152601a60248201527f4275726e20666f72206e6f6e6578697374656e7420746f6b656e0000000000006044820152606401610ca7565b836001600160a01b031660068484848181106120af576120af6145b2565b90506020020135815481106120c6576120c66145b2565b6000918252602090912001546001600160a01b0316146121195760405162461bcd60e51b815260206004820152600e60248201526d09eeedccae440dad2e6dac2e8c6d60931b6044820152606401610ca7565b61213a83838381811061212e5761212e6145b2565b9050602002013561357a565b61214381614557565b905061201c565b6000600e828154811061215f5761215f6145b2565b6000918252602090912001546001600160a01b031692915050565b3360009081526001602052604090205460ff166121a95760405162461bcd60e51b8152600401610ca7906141f1565b8060165414156121cb5760405162461bcd60e51b8152600401610ca7906143bb565b601655565b606060038054610bf99061451c565b6001600160a01b0382163314156122385760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610ca7565b3360008181526008602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60005b838110156123195761230987878787858181106122c6576122c66145b2565b9050602002013586868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525061232292505050565b61231281614557565b90506122a7565b50505050505050565b61232c3383613292565b6123485760405162461bcd60e51b8152600401610ca7906143ea565b611ca3848484846135fa565b3360009081526001602052604090205460ff166123835760405162461bcd60e51b8152600401610ca7906141f1565b8281146123e55760405162461bcd60e51b815260206004820152602a60248201527f4d7573742070726f7669646520657175616c20746f6b656e49647320616e6420604482015269726563697069656e747360b01b6064820152608401610ca7565b6000806000805b868110156125a757858582818110612406576124066145b2565b905060200201602081019061241b9190613a89565b93506000868683818110612431576124316145b2565b90506020020160208101906124469190613a89565b6001600160a01b031614156124ab5760405162461bcd60e51b815260206004820152602560248201527f43616e6e6f742072657375727265637420746f20746865207a65726f20616464604482015264726573732160d81b6064820152608401610ca7565b8787828181106124bd576124bd6145b2565b9050602002013592506124cf83612edb565b1561251c5760405162461bcd60e51b815260206004820181905260248201527f43616e6e6f7420726573757272656374206578697374696e6720746f6b656e216044820152606401610ca7565b8360068481548110612530576125306145b2565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b031602179055506125688284612f25565b82846001600160a01b0316836001600160a01b031660008051602061460a83398151915260405160405180910390a46125a081614557565b90506123ec565b5050505050505050565b60606125bc82612edb565b6126085760405162461bcd60e51b815260206004820152601a60248201527f5468697320746f6b656e20646f6573206e6f74206578697374210000000000006044820152606401610ca7565b601c6126138361362d565b601d6040516020016126279392919061412a565b6040516020818303038152906040529050919050565b3360009081526001602052604090205460ff1661266c5760405162461bcd60e51b8152600401610ca7906141f1565b8360195414158061267f57508260175414155b8061268c575081601a5414155b8061269957508060185414155b6126b55760405162461bcd60e51b8152600401610ca7906143bb565b818411156126fc5760405162461bcd60e51b8152602060048201526014602482015273151a595c881bdc99195c881a5b98dbdc9c9958dd60621b6044820152606401610ca7565b60185460175410156127475760405162461bcd60e51b8152602060048201526014602482015273151a595c881bdc99195c881a5b98dbdc9c9958dd60621b6044820152606401610ca7565b601993909355601791909155601a55601855565b6000546001600160a01b031633146127855760405162461bcd60e51b8152600401610ca790614386565b610e6c83838361372a565b3332146127af5760405162461bcd60e51b8152600401610ca790614359565b601b5460ff166127d15760405162461bcd60e51b8152600401610ca7906142b3565b6127db8282611ca9565b6128275760405162461bcd60e51b815260206004820152601d60248201527f596f7520617265206e6f74206f6e2074686520416c6c6f774c697374210000006044820152606401610ca7565b6001600160a01b0382166000908152601f602052604090205460ff161515600114156128875760405162461bcd60e51b815260206004820152600f60248201526e416c7265616479206d696e7465642160881b6044820152606401610ca7565b6000612891610e71565b6011549091506128a282600161448e565b11156128c05760405162461bcd60e51b8152600401610ca7906142e0565b6014546015546128d190600161448e565b111561291f5760405162461bcd60e51b815260206004820181905260248201527f4d696e742065786365656473207075626c69632073616c6520737570706c79216044820152606401610ca7565b6001600160a01b0383166000908152601f60205260408120805460ff19166001179055601580549161295083614557565b919050555060008161296190614557565b915081905061297084826134c0565b836001600160a01b03167ff3bd2c31b93b14908ac278cbe66c80fe1191219f21812080ca54857229cfefb7826040516129ab91815260200190565b60405180910390a250505050565b3360009081526001602052604090205460ff166129e85760405162461bcd60e51b8152600401610ca7906141f1565b828114612a4c5760405162461bcd60e51b815260206004820152602c60248201527f4d7573742070726f7669646520657175616c207175616e74697469657320616e60448201526b6420726563697069656e747360a01b6064820152608401610ca7565b600080612a57610e71565b905060005b85811015612a9a57868682818110612a7657612a766145b2565b9050602002013583612a88919061448e565b9250612a9381614557565b9050612a5c565b50601154612aa8838361448e565b1115612ac65760405162461bcd60e51b8152600401610ca7906142e0565b60005b838110156123195760005b878783818110612ae657612ae66145b2565b90506020020135811015612b7a576000612aff84614557565b9350839050612b34878785818110612b1957612b196145b2565b9050602002016020810190612b2e9190613a89565b826134c0565b60405181815233907f82bff94c69b4a624bb0d25e15735cf4189fdc4706e6b6806c94886b0009f2bdf9060200160405180910390a250612b7381614557565b9050612ad4565b50612b8481614557565b9050612ac9565b6000546001600160a01b03163314612bb55760405162461bcd60e51b8152600401610ca790614386565b6001600160a01b0381166000908152600160208190526040909120805460ff19169091179055612be4816137c3565b50565b333214612c065760405162461bcd60e51b8152600401610ca790614359565b601b54610100900460ff16612c5d5760405162461bcd60e51b815260206004820152601b60248201527f526573657276652073616c65206973206e6f74206163746976652100000000006044820152606401610ca7565b80601654612c6b91906144ba565b341015612cba5760405162461bcd60e51b815260206004820152601a60248201527f45746865722073656e74206973206e6f7420636f7272656374210000000000006044820152606401610ca7565b6000612cc4610e71565b601154909150612cd4838361448e565b1115612cf25760405162461bcd60e51b8152600401610ca7906142e0565b60125482601354612d03919061448e565b1115612d5b5760405162461bcd60e51b815260206004820152602160248201527f4d696e74206578636565647320726573657276652073616c6520737570706c796044820152602160f81b6064820152608401610ca7565b60005b82811015610e6c5760138054906000612d7683614557565b9190505550600082612d8790614557565b9250829050612d9633826134c0565b60405181815233907f85cb96374a3618ea44ac1b34a735c719a8ee3155cb7ac8cc0a8994e3906dae669060200160405180910390a250612dd581614557565b9050612d5e565b6001600160a01b0381166000908152600c6020526040812054612e115760405162461bcd60e51b8152600401610ca79061426d565b6000600b5447612e21919061448e565b6001600160a01b0384166000908152600d6020908152604080832054600a54600c909352908320549394509192612e5890856144ba565b612e6291906144a6565b612e6c91906144d9565b9050806112865760405162461bcd60e51b8152600401610ca79061430e565b60006001600160e01b031982166380ac58cd60e01b1480612ebc57506001600160e01b03198216635b5e139f60e01b145b80610be457506301ffc9a760e01b6001600160e01b0319831614610be4565b60065460009082108015610be4575060006001600160a01b031660068381548110612f0857612f086145b2565b6000918252602090912001546001600160a01b0316141592915050565b600081815260076020526040902080546001600160a01b0319166001600160a01b0384169081179091558190612f5a8261185d565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6001600160a01b038216612ffe5760405162461bcd60e51b815260206004820152602c60248201527f5061796d656e7453706c69747465723a206163636f756e74206973207468652060448201526b7a65726f206164647265737360a01b6064820152608401610ca7565b6000811161304e5760405162461bcd60e51b815260206004820152601d60248201527f5061796d656e7453706c69747465723a207368617265732061726520300000006044820152606401610ca7565b6001600160a01b0382166000908152600c6020526040902054156130c85760405162461bcd60e51b815260206004820152602b60248201527f5061796d656e7453706c69747465723a206163636f756e7420616c726561647960448201526a206861732073686172657360a81b6064820152608401610ca7565b600e8054600181019091557fbb7b4a454dc3493923482f07822329ed19e8244eff582cc204f8554c3620c3fd0180546001600160a01b0319166001600160a01b0384169081179091556000908152600c60205260409020819055600a5461313090829061448e565b600a55604080516001600160a01b0384168152602081018390527f40c340f65e17194d14ddddb073d3c9f888e3cb52b5aae0c6c7706b4fbc905fac910160405180910390a15050565b804710156131c95760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610ca7565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114613216576040519150601f19603f3d011682016040523d82523d6000602084013e61321b565b606091505b5050905080610e6c5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610ca7565b600061329d82612edb565b6132fe5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610ca7565b60006133098361185d565b9050806001600160a01b0316846001600160a01b031614806133445750836001600160a01b031661333984610cd3565b6001600160a01b0316145b8061337457506001600160a01b0380821660009081526008602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b031661338f8261185d565b6001600160a01b0316146133f75760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610ca7565b6001600160a01b0382166134595760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610ca7565b613464600082612f25565b8160068281548110613478576134786145b2565b6000918252602082200180546001600160a01b0319166001600160a01b039384161790556040518392858116929087169160008051602061460a8339815191529190a4505050565b6006805460018101825560009182527ff652222313e28459528d920b65115c16c04f3efc82aaedc97be59f3f377c0d3f0180546001600160a01b0319166001600160a01b03851690811790915560405183929060008051602061460a833981519152908290a45050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60006135858261185d565b90506135a261359c6000546001600160a01b031690565b83612f25565b6000600683815481106135b7576135b76145b2565b6000918252602082200180546001600160a01b0319166001600160a01b03938416179055604051849284169060008051602061460a833981519152908390a45050565b61360584848461337c565b6136118484848461385b565b611ca35760405162461bcd60e51b8152600401610ca79061421b565b6060816136515750506040805180820190915260018152600360fc1b602082015290565b8160005b811561367b578061366581614557565b91506136749050600a836144a6565b9150613655565b6000816001600160401b03811115613695576136956145c8565b6040519080825280601f01601f1916602001820160405280156136bf576020820181803683370190505b5090505b8415613374576136d46001836144d9565b91506136e1600a86614572565b6136ec90603061448e565b60f81b818381518110613701576137016145b2565b60200101906001600160f81b031916908160001a905350613723600a866144a6565b94506136c3565b6001600160a01b0382166000908152600c6020526040902054600a548291613751916144d9565b61375b919061448e565b600a556001600160a01b0382166000908152600c60205260409020819055600e805483919085908110613790576137906145b2565b9060005260206000200160006101000a8154816001600160a01b0302191690836001600160a01b03160217905550505050565b6000546001600160a01b031633146137ed5760405162461bcd60e51b8152600401610ca790614386565b6001600160a01b0381166138525760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610ca7565b612be48161352a565b60006001600160a01b0384163b156117e157604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061389f90339089908890889060040161415d565b602060405180830381600087803b1580156138b957600080fd5b505af19250505080156138e9575060408051601f3d908101601f191682019092526138e691810190613f8f565b60015b613943573d808015613917576040519150601f19603f3d011682016040523d82523d6000602084013e61391c565b606091505b50805161393b5760405162461bcd60e51b8152600401610ca79061421b565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050613374565b8280546139699061451c565b90600052602060002090601f01602090048101928261398b57600085556139d1565b82601f106139a45782800160ff198235161785556139d1565b828001600101855582156139d1579182015b828111156139d15782358255916020019190600101906139b6565b506118599291505b8082111561185957600081556001016139d9565b60008083601f8401126139ff57600080fd5b5081356001600160401b03811115613a1657600080fd5b6020830191508360208260051b8501011115613a3157600080fd5b9250929050565b80358015158114610cce57600080fd5b60008083601f840112613a5a57600080fd5b5081356001600160401b03811115613a7157600080fd5b602083019150836020828501011115613a3157600080fd5b600060208284031215613a9b57600080fd5b8135611286816145de565b600060208284031215613ab857600080fd5b8151611286816145de565b60008060408385031215613ad657600080fd5b8235613ae1816145de565b91506020830135613af1816145de565b809150509250929050565b60008060008060008060808789031215613b1557600080fd5b8635613b20816145de565b95506020870135613b30816145de565b945060408701356001600160401b0380821115613b4c57600080fd5b613b588a838b016139ed565b90965094506060890135915080821115613b7157600080fd5b50613b7e89828a01613a48565b979a9699509497509295939492505050565b600080600060608486031215613ba557600080fd5b8335613bb0816145de565b92506020840135613bc0816145de565b929592945050506040919091013590565b60008060008060808587031215613be757600080fd5b8435613bf2816145de565b9350602085810135613c03816145de565b93506040860135925060608601356001600160401b0380821115613c2657600080fd5b818801915088601f830112613c3a57600080fd5b813581811115613c4c57613c4c6145c8565b613c5e601f8201601f1916850161443b565b91508082528984828501011115613c7457600080fd5b808484018584013760008482840101525080935050505092959194509250565b60008060408385031215613ca757600080fd5b8235613cb2816145de565b91506020838101356001600160401b03811115613cce57600080fd5b8401601f81018613613cdf57600080fd5b8035613cf2613ced8261446b565b61443b565b80828252848201915084840189868560051b8701011115613d1257600080fd5b600094505b83851015613d35578035835260019490940193918501918501613d17565b5080955050505050509250929050565b600080600060408486031215613d5a57600080fd5b8335613d65816145de565b925060208401356001600160401b03811115613d8057600080fd5b613d8c868287016139ed565b9497909650939450505050565b60008060408385031215613dac57600080fd5b8235613db7816145de565b9150613dc560208401613a38565b90509250929050565b60008060408385031215613de157600080fd5b8235613dec816145de565b946020939093013593505050565b60008060208385031215613e0d57600080fd5b82356001600160401b03811115613e2357600080fd5b613e2f858286016139ed565b90969095509350505050565b60008060008060408587031215613e5157600080fd5b84356001600160401b0380821115613e6857600080fd5b613e74888389016139ed565b90965094506020870135915080821115613e8d57600080fd5b50613e9a878288016139ed565b95989497509550505050565b60006020808385031215613eb957600080fd5b82516001600160401b03811115613ecf57600080fd5b8301601f81018513613ee057600080fd5b8051613eee613ced8261446b565b80828252848201915084840188868560051b8701011115613f0e57600080fd5b600094505b83851015613f31578051835260019490940193918501918501613f13565b50979650505050505050565b60008060408385031215613f5057600080fd5b613db783613a38565b600060208284031215613f6b57600080fd5b5035919050565b600060208284031215613f8457600080fd5b8135611286816145f3565b600060208284031215613fa157600080fd5b8151611286816145f3565b60008060008060408587031215613fc257600080fd5b84356001600160401b0380821115613fd957600080fd5b613fe588838901613a48565b90965094506020870135915080821115613ffe57600080fd5b50613e9a87828801613a48565b60008060006060848603121561402057600080fd5b833592506020840135613bc0816145de565b6000806000806080858703121561404857600080fd5b5050823594602084013594506040840135936060013592509050565b6000815180845261407c8160208601602086016144f0565b601f01601f19169290920160200192915050565b8054600090600181811c90808316806140aa57607f831692505b60208084108214156140cc57634e487b7160e01b600052602260045260246000fd5b8180156140e057600181146140f15761411e565b60ff1986168952848901965061411e565b60008881526020902060005b868110156141165781548b8201529085019083016140fd565b505084890196505b50505050505092915050565b60006141368286614090565b84516141468183602089016144f0565b61415281830186614090565b979650505050505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061419090830184614064565b9695505050505050565b6020808252825182820181905260009190848201906040850190845b818110156141d2578351835292840192918401916001016141b6565b50909695505050505050565b6020815260006112866020830184614064565b60208082526010908201526f496e76616c69642064656c656761746560801b604082015260600190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526026908201527f5061796d656e7453706c69747465723a206163636f756e7420686173206e6f2060408201526573686172657360d01b606082015260800190565b6020808252601390820152724d696e74206973206e6f74206163746976652160681b604082015260600190565b6020808252601490820152734d696e74206578636565647320737570706c792160601b604082015260600190565b6020808252602b908201527f5061796d656e7453706c69747465723a206163636f756e74206973206e6f742060408201526a191d59481c185e5b595b9d60aa1b606082015260800190565b6020808252601390820152724e6f20736d61727420636f6e7472616374732160681b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526015908201527413995dc81d985b1d59481b585d18da195cc81bdb19605a1b604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b604051601f8201601f191681016001600160401b0381118282101715614463576144636145c8565b604052919050565b60006001600160401b03821115614484576144846145c8565b5060051b60200190565b600082198211156144a1576144a1614586565b500190565b6000826144b5576144b561459c565b500490565b60008160001904831182151516156144d4576144d4614586565b500290565b6000828210156144eb576144eb614586565b500390565b60005b8381101561450b5781810151838201526020016144f3565b83811115611ca35750506000910152565b600181811c9082168061453057607f821691505b6020821081141561455157634e487b7160e01b600052602260045260246000fd5b50919050565b600060001982141561456b5761456b614586565b5060010190565b6000826145815761458161459c565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114612be457600080fd5b6001600160e01b031981168114612be457600080fdfeddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa264697066735822122047d4a4e83b14dea2402c32d3633606f1169451edc2ae47c8eb3da218fdd3a8f964736f6c63430008070033

Deployed Bytecode Sourcemap

100153:13811:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;96349:40;31420:10;96349:40;;;-1:-1:-1;;;;;14475:32:1;;;14457:51;;96379:9:0;14539:2:1;14524:18;;14517:34;14430:18;96349:40:0;;;;;;;100153:13811;;;91940:225;;;;;;;;;;-1:-1:-1;91940:225:0;;;;;:::i;:::-;;:::i;:::-;;;16136:14:1;;16129:22;16111:41;;16099:2;16084:18;91940:225:0;;;;;;;;84802:102;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;47106:112::-;;;;;;;;;;-1:-1:-1;47106:112:0;;;;;:::i;:::-;;:::i;86132:216::-;;;;;;;;;;-1:-1:-1;86132:216:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;14231:32:1;;;14213:51;;14201:2;14186:18;86132:216:0;14067:203:1;85713:411:0;;;;;;;;;;-1:-1:-1;85713:411:0;;;;;:::i;:::-;;:::i;92820:159::-;;;;;;;;;;;;;:::i;:::-;;;16309:25:1;;;16297:2;16282:18;92820:159:0;16163:177:1;113137:117:0;;;;;;;;;;-1:-1:-1;113137:117:0;;;;;:::i;:::-;;:::i;98125:930::-;;;;;;;;;;-1:-1:-1;98125:930:0;;;;;:::i;:::-;;:::i;101040:43::-;;;;;;;;;;-1:-1:-1;101040:43:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;100646:35;;;;;;;;;;;;;;;;111306:262;;;;;;;;;;-1:-1:-1;111306:262:0;;;;;:::i;:::-;;:::i;86831:334::-;;;;;;;;;;-1:-1:-1;86831:334:0;;;;;:::i;:::-;;:::i;102732:354::-;;;;;;;;;;-1:-1:-1;102732:354:0;;;;;:::i;:::-;;:::i;100330:32::-;;;;;;;;;;;;;;;;100516:37;;;;;;;;;;;;;;;;110654:180;;;;;;;;;;-1:-1:-1;110654:180:0;;;;;:::i;:::-;;:::i;101155:94::-;;;;;;;;;;;;;;;;92173:431;;;;;;;;;;-1:-1:-1;92173:431:0;;;;;:::i;:::-;;:::i;96480:91::-;;;;;;;;;;-1:-1:-1;96551:12:0;;96480:91;;103542:911;;;;;;:::i;:::-;;:::i;87173:184::-;;;;;;;;;;-1:-1:-1;87173:184:0;;;;;:::i;:::-;;:::i;93240:346::-;;;;;;;;;;-1:-1:-1;93240:346:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;47224:116::-;;;;;;;;;;-1:-1:-1;47224:116:0;;;;;:::i;:::-;;:::i;100369:25::-;;;;;;;;;;;;;;;;91646:286;;;;;;;;;;-1:-1:-1;91646:286:0;;;;;:::i;:::-;;:::i;92612:200::-;;;;;;;;;;-1:-1:-1;92612:200:0;;;;;:::i;:::-;;:::i;100688:24::-;;;;;;;;;;-1:-1:-1;100688:24:0;;;;;;;;101090:56;;;;;;;;;;-1:-1:-1;101090:56:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;84912:236;;;;;;;;;;-1:-1:-1;84912:236:0;;;;;:::i;:::-;;:::i;105531:1037::-;;;;;;;;;;-1:-1:-1;105531:1037:0;;;;;:::i;:::-;;:::i;102313:411::-;;;;;;;;;;-1:-1:-1;102313:411:0;;;;;:::i;:::-;;:::i;110969:181::-;;;;;;;;;;-1:-1:-1;110969:181:0;;;;;:::i;:::-;;:::i;84458:336::-;;;;;;;;;;-1:-1:-1;84458:336:0;;;;;:::i;:::-;;:::i;45954:103::-;;;;;;;;;;;;;:::i;112899:108::-;;;;;;;;;;-1:-1:-1;112899:108:0;;;;;:::i;:::-;;:::i;110184:310::-;;;;;;;;;;-1:-1:-1;110184:310:0;;;;;:::i;:::-;;:::i;100719:31::-;;;;;;;;;;-1:-1:-1;100719:31:0;;;;;;;;;;;100560:39;;;;;;;;;;;;;;;;107634:342;;;;;;:::i;:::-;;:::i;97255:100::-;;;;;;;;;;-1:-1:-1;97255:100:0;;;;;:::i;:::-;;:::i;45303:87::-;;;;;;;;;;-1:-1:-1;45349:7:0;45376:6;-1:-1:-1;;;;;45376:6:0;45303:87;;111693:147;;;;;;;;;;-1:-1:-1;111693:147:0;;;;;:::i;:::-;;:::i;85469:106::-;;;;;;;;;;;;;:::i;100401:35::-;;;;;;;;;;;;;;;;97055:109;;;;;;;;;;-1:-1:-1;97055:109:0;;;;;:::i;:::-;-1:-1:-1;;;;;97138:18:0;97111:7;97138:18;;;:9;:18;;;;;;;97055:109;100478:31;;;;;;;;;;;;;;;;86528:295;;;;;;;;;;-1:-1:-1;86528:295:0;;;;;:::i;:::-;;:::i;100443:28::-;;;;;;;;;;;;;;;;92987:245;;;;;;;;;;-1:-1:-1;92987:245:0;;;;;:::i;:::-;;:::i;87365:325::-;;;;;;;;;;-1:-1:-1;87365:325:0;;;;;:::i;:::-;;:::i;109123:753::-;;;;;;;;;;-1:-1:-1;109123:753:0;;;;;:::i;:::-;;:::i;101965:249::-;;;;;;;;;;-1:-1:-1;101965:249:0;;;;;:::i;:::-;;:::i;96851:105::-;;;;;;;;;;-1:-1:-1;96851:105:0;;;;;:::i;:::-;-1:-1:-1;;;;;96932:16:0;96905:7;96932:16;;;:7;:16;;;;;;;96851:105;112090:676;;;;;;;;;;-1:-1:-1;112090:676:0;;;;;:::i;:::-;;:::i;100606:33::-;;;;;;;;;;;;;;;;113373:139;;;;;;;;;;-1:-1:-1;113373:139:0;;;;;:::i;:::-;;:::i;96665:95::-;;;;;;;;;;-1:-1:-1;96738:14:0;;96665:95;;106728:686;;;;;;;;;;-1:-1:-1;106728:686:0;;;;;:::i;:::-;;:::i;100295:28::-;;;;;;;;;;;;;;;;108171:739;;;;;;:::i;:::-;;:::i;86356:164::-;;;;;;;;;;-1:-1:-1;86356:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;86477:25:0;;;86453:4;86477:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;86356:164;47346:161;;;;;;;;;;-1:-1:-1;47346:161:0;;;;;:::i;:::-;;:::i;104643:642::-;;;;;;:::i;:::-;;:::i;97486:439::-;;;;;;;;;;-1:-1:-1;97486:439:0;;;;;:::i;:::-;;:::i;91940:225::-;92043:4;-1:-1:-1;;;;;;92067:50:0;;-1:-1:-1;;;92067:50:0;;:90;;;92121:36;92145:11;92121:23;:36::i;:::-;92060:97;91940:225;-1:-1:-1;;91940:225:0:o;84802:102::-;84858:13;84891:5;84884:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;84802:102;:::o;47106:112::-;47176:4;45376:6;;-1:-1:-1;;;;;45376:6:0;31420:10;45523:23;45515:68;;;;-1:-1:-1;;;45515:68:0;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;;;;;;47196:16:0;::::1;;::::0;;;:10:::1;:16;::::0;;;;;::::1;;45594:1;47106:112:::0;;;:::o;86132:216::-;86205:7;86233:16;86241:7;86233;:16::i;:::-;86225:73;;;;-1:-1:-1;;;86225:73:0;;27934:2:1;86225:73:0;;;27916:21:1;27973:2;27953:18;;;27946:30;28012:34;27992:18;;;27985:62;-1:-1:-1;;;28063:18:1;;;28056:42;28115:19;;86225:73:0;27732:408:1;86225:73:0;-1:-1:-1;86316:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;86316:24:0;;86132:216::o;85713:411::-;85793:13;85809:24;85825:7;85809:15;:24::i;:::-;85793:40;;85858:5;-1:-1:-1;;;;;85852:11:0;:2;-1:-1:-1;;;;;85852:11:0;;;85844:57;;;;-1:-1:-1;;;85844:57:0;;29823:2:1;85844:57:0;;;29805:21:1;29862:2;29842:18;;;29835:30;29901:34;29881:18;;;29874:62;-1:-1:-1;;;29952:18:1;;;29945:31;29993:19;;85844:57:0;29621:397:1;85844:57:0;31420:10;-1:-1:-1;;;;;85936:21:0;;;;:62;;-1:-1:-1;85961:37:0;85978:5;31420:10;86356:164;:::i;85961:37::-;85914:168;;;;-1:-1:-1;;;85914:168:0;;25179:2:1;85914:168:0;;;25161:21:1;25218:2;25198:18;;;25191:30;25257:34;25237:18;;;25230:62;25328:26;25308:18;;;25301:54;25372:19;;85914:168:0;24977:420:1;85914:168:0;86095:21;86104:2;86108:7;86095:8;:21::i;:::-;85782:342;85713:411;;:::o;92820:159::-;92911:4;92963:7;;92953;;:17;;;;:::i;:::-;92935:7;:14;:36;;;;:::i;:::-;92928:43;;92820:159;:::o;113137:117::-;45349:7;45376:6;-1:-1:-1;;;;;45376:6:0;31420:10;45523:23;45515:68;;;;-1:-1:-1;;;45515:68:0;;;;;;;:::i;:::-;113219:27:::1;113229:7;113238;113219:9;:27::i;:::-;113137:117:::0;;:::o;98125:930::-;-1:-1:-1;;;;;98201:16:0;;98220:1;98201:16;;;:7;:16;;;;;;98193:71;;;;-1:-1:-1;;;98193:71:0;;;;;;;:::i;:::-;98277:21;98325:14;;98301:21;:38;;;;:::i;:::-;-1:-1:-1;;;;;98420:18:0;;98350:15;98420:18;;;:9;:18;;;;;;;;;98405:12;;98385:7;:16;;;;;;;98277:62;;-1:-1:-1;98350:15:0;;98369:32;;98277:62;98369:32;:::i;:::-;98368:49;;;;:::i;:::-;:70;;;;:::i;:::-;98350:88;-1:-1:-1;98457:12:0;98449:68;;;;-1:-1:-1;;;98449:68:0;;;;;;;:::i;:::-;98543:12;;-1:-1:-1;;;;;98532:23:0;;;98543:12;;98532:23;98528:309;;;-1:-1:-1;;;;;98598:18:0;;98572:13;98598:18;;;:9;:18;;;;;;98588:28;;:7;:28;:::i;:::-;98572:44;;98646:11;;98635:8;:22;98631:195;;;-1:-1:-1;;;;;98702:18:0;;;;;;:9;:18;;;;;;98688:11;;:32;;98702:18;98688:32;:::i;:::-;98678:42;;98755:7;:16;98763:7;-1:-1:-1;;;;;98755:16:0;-1:-1:-1;;;;;98755:16:0;;;;;;;;;;;;;98739:12;;:32;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;98790:16:0;;98809:1;98790:16;;;:7;:16;;;;;:20;98631:195;98557:280;98528:309;-1:-1:-1;;;;;98870:18:0;;;;;;:9;:18;;;;;;:28;;98891:7;;98870:28;:::i;:::-;-1:-1:-1;;;;;98849:18:0;;;;;;:9;:18;;;;;:49;98926:14;;:24;;98943:7;;98926:24;:::i;:::-;98909:14;:41;98963:35;98981:7;98990;98963:17;:35::i;:::-;99014:33;;;-1:-1:-1;;;;;14475:32:1;;14457:51;;14539:2;14524:18;;14517:34;;;99014:33:0;;14430:18:1;99014:33:0;;;;;;;98182:873;;98125:930;:::o;111306:262::-;47038:10;47027:22;;;;:10;:22;;;;;;;;47019:52;;;;-1:-1:-1;;;47019:52:0;;;;;;;:::i;:::-;111394:10:::1;111381:9;;:23;;111373:57;;;;-1:-1:-1::0;;;111373:57:0::1;;;;;;;:::i;:::-;111463:13;:11;:13::i;:::-;111449:10;:27;;111441:86;;;::::0;-1:-1:-1;;;111441:86:0;;20949:2:1;111441:86:0::1;::::0;::::1;20931:21:1::0;20988:2;20968:18;;;20961:30;21027:34;21007:18;;;21000:62;-1:-1:-1;;;21078:18:1;;;21071:44;21132:19;;111441:86:0::1;20747:410:1::0;111441:86:0::1;111538:9;:22:::0;111306:262::o;86831:334::-;87023:41;31420:10;87056:7;87023:18;:41::i;:::-;87015:103;;;;-1:-1:-1;;;87015:103:0;;;;;;;:::i;:::-;87129:28;87139:4;87145:2;87149:7;87129:9;:28::i;102732:354::-;102829:10;;102824:40;;-1:-1:-1;;;102824:40:0;;-1:-1:-1;;;;;14231:32:1;;;102824:40:0;;;14213:51:1;102785:10:0;;;;102829;;;;;;;;102824:30;;14186:18:1;;102824:40:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;102824:40:0;;;;;;;;;;;;:::i;:::-;:47;102923:18;;102824:47;;-1:-1:-1;102895:1:0;;102911:30;;102907:148;;-1:-1:-1;102966:1:0;102907:148;;;103001:16;;102989:8;:28;102985:70;;-1:-1:-1;103042:1:0;102985:70;103073:5;102732:354;-1:-1:-1;;;102732:354:0:o;110654:180::-;47038:10;47027:22;;;;:10;:22;;;;;;;;47019:52;;;;-1:-1:-1;;;47019:52:0;;;;;;;:::i;:::-;110740:10:::1;::::0;-1:-1:-1;;;;;110740:25:0;;::::1;:10:::0;;;::::1;;:25;;110732:59;;;;-1:-1:-1::0;;;110732:59:0::1;;;;;;;:::i;:::-;110802:10;:24:::0;;-1:-1:-1;;;;;110802:24:0;;::::1;::::0;::::1;-1:-1:-1::0;;;;;;110802:24:0;;::::1;::::0;;;::::1;::::0;;110654:180::o;92173:431::-;92259:12;92284:10;92310:6;92305:226;92322:7;:14;92318:18;;92305:226;;;92371:7;92379:1;92371:10;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;92362:19:0;;;92371:10;;92362:19;92358:162;;;92415:5;92406;:14;92402:102;;;92451:1;-1:-1:-1;92444:8:0;;-1:-1:-1;92444:8:0;92402:102;92497:7;;;:::i;:::-;;;92402:102;92338:3;;;:::i;:::-;;;92305:226;;;-1:-1:-1;92543:53:0;;-1:-1:-1;;;92543:53:0;;18536:2:1;92543:53:0;;;18518:21:1;18575:2;18555:18;;;18548:30;18614:34;18594:18;;;18587:62;-1:-1:-1;;;18665:18:1;;;18658:41;18716:19;;92543:53:0;18334:407:1;103542:911:0;101702:10;101716:9;101702:23;101694:55;;;;-1:-1:-1;;;101694:55:0;;;;;;;:::i;:::-;103630:12:::1;::::0;::::1;;103622:44;;;;-1:-1:-1::0;;;103622:44:0::1;;;;;;;:::i;:::-;103698:10;::::0;103693:35:::1;::::0;-1:-1:-1;;;103693:35:0;;-1:-1:-1;;;;;14231:32:1;;;103693:35:0::1;::::0;::::1;14213:51:1::0;103677:13:0::1;::::0;103698:10;;::::1;;::::0;103693:30:::1;::::0;14186:18:1;;103693:35:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;::::0;;::::1;-1:-1:-1::0;;103693:35:0::1;::::0;::::1;;::::0;::::1;::::0;;;::::1;::::0;::::1;:::i;:::-;:42:::0;103760:5:::1;::::0;103792:18:::1;::::0;103693:42;;-1:-1:-1;103760:5:0;103780:30;::::1;103776:174;;-1:-1:-1::0;103836:14:0::1;::::0;103776:174:::1;;;103884:16;;103872:8;:28;103868:82;;-1:-1:-1::0;103926:12:0::1;::::0;103868:82:::1;103982:16;103991:7:::0;103982:6;:16:::1;:::i;:::-;103969:9;:29;;103961:68;;;::::0;-1:-1:-1;;;103961:68:0;;20187:2:1;103961:68:0::1;::::0;::::1;20169:21:1::0;20226:2;20206:18;;;20199:30;20265:28;20245:18;;;20238:56;20311:18;;103961:68:0::1;19985:350:1::0;103961:68:0::1;104040:12;104055:13;:11;:13::i;:::-;104108:9;::::0;104040:28;;-1:-1:-1;104087:17:0::1;104097:7:::0;104040:28;104087:17:::1;:::i;:::-;:30;;104079:63;;;;-1:-1:-1::0;;;104079:63:0::1;;;;;;;:::i;:::-;104191:16;;104180:7;104161:16;;:26;;;;:::i;:::-;:46;;104153:91;;;::::0;-1:-1:-1;;;104153:91:0;;33055:2:1;104153:91:0::1;::::0;::::1;33037:21:1::0;;;33074:18;;;33067:30;33133:34;33113:18;;;33106:62;33185:18;;104153:91:0::1;32853:356:1::0;104153:91:0::1;104259:6;104255:191;104271:7;104267:1;:11;104255:191;;;104299:16;:18:::0;;;:16:::1;:18;::::0;::::1;:::i;:::-;;;;;;104332:12;104347:9;;;;:::i;:::-;;;;104332:24;;104371:19;104377:3;104382:7;104371:5;:19::i;:::-;104421:3;-1:-1:-1::0;;;;;104410:24:0::1;;104426:7;104410:24;;;;16309:25:1::0;;16297:2;16282:18;;16163:177;104410:24:0::1;;;;;;;;-1:-1:-1::0;104280:3:0::1;::::0;::::1;:::i;:::-;;;104255:191;;;;103611:842;;;103542:911:::0;;:::o;87173:184::-;87310:39;87327:4;87333:2;87337:7;87310:39;;;;;;;;;;;;:16;:39::i;93240:346::-;93322:13;93348;93364:20;93375:7;93364:9;:20::i;:::-;93348:36;;93395:20;93430:8;-1:-1:-1;;;;;93418:22:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;93418:22:0;;93395:45;;93456:6;93451:104;93468:8;93464:1;:12;93451:104;;;93510:33;93531:7;93540:1;93510:19;:33::i;:::-;93498:6;93505:1;93498:9;;;;;;;;:::i;:::-;;;;;;;;;;:45;93478:3;;;:::i;:::-;;;93451:104;;;-1:-1:-1;93572:6:0;93240:346;-1:-1:-1;;;93240:346:0:o;47224:116::-;45349:7;45376:6;-1:-1:-1;;;;;45376:6:0;31420:10;45523:23;45515:68;;;;-1:-1:-1;;;45515:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;47304:16:0;;;::::1;;::::0;;;:10:::1;:16;::::0;;;;:30;;-1:-1:-1;;47304:30:0::1;::::0;::::1;;::::0;;;::::1;::::0;;47224:116::o;91646:286::-;91750:4;91771:6;91767:134;91779:19;;;91767:134;;;91850:7;-1:-1:-1;;;;;91824:33:0;:7;91833:8;;91842:1;91833:11;;;;;;;:::i;:::-;;;;;;;91824:22;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;91824:22:0;:33;91820:69;;91884:5;91877:12;;;;;91820:69;91800:3;;;:::i;:::-;;;91767:134;;;-1:-1:-1;91920:4:0;;91646:286;-1:-1:-1;;;;91646:286:0:o;92612:200::-;92686:4;92719:13;:11;:13::i;:::-;92711:5;:21;92703:78;;;;-1:-1:-1;;;92703:78:0;;31045:2:1;92703:78:0;;;31027:21:1;31084:2;31064:18;;;31057:30;31123:34;31103:18;;;31096:62;-1:-1:-1;;;31174:18:1;;;31167:42;31226:19;;92703:78:0;30843:408:1;92703:78:0;-1:-1:-1;92799:5:0;92612:200::o;84912:236::-;84981:7;85001:13;85017:7;85025;85017:16;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;85017:16:0;;-1:-1:-1;85052:19:0;85044:73;;;;-1:-1:-1;;;85044:73:0;;26015:2:1;85044:73:0;;;25997:21:1;26054:2;26034:18;;;26027:30;26093:34;26073:18;;;26066:62;-1:-1:-1;;;26144:18:1;;;26137:39;26193:19;;85044:73:0;25813:405:1;105531:1037:0;101702:10;101716:9;101702:23;101694:55;;;;-1:-1:-1;;;101694:55:0;;;;;;;:::i;:::-;105612:12:::1;::::0;::::1;;105604:44;;;;-1:-1:-1::0;;;105604:44:0::1;;;;;;;:::i;:::-;105668:19;::::0;::::1;::::0;::::1;;;105667:20;105659:59;;;::::0;-1:-1:-1;;;105659:59:0;;29468:2:1;105659:59:0::1;::::0;::::1;29450:21:1::0;29507:2;29487:18;;;29480:30;29546:28;29526:18;;;29519:56;29592:18;;105659:59:0::1;29266:350:1::0;105659:59:0::1;105734:6;105729:386;105746:19:::0;;::::1;105729:386;;;105810:4;105795:8;;105804:1;105795:11;;;;;;;:::i;:::-;;;;;;;:19;;105787:67;;;::::0;-1:-1:-1;;;105787:67:0;;26780:2:1;105787:67:0::1;::::0;::::1;26762:21:1::0;26819:2;26799:18;;;26792:30;26858:34;26838:18;;;26831:62;-1:-1:-1;;;26909:18:1;;;26902:33;26952:19;;105787:67:0::1;26578:399:1::0;105787:67:0::1;105882:10;::::0;105918::::1;::::0;105882;;::::1;-1:-1:-1::0;;;;;105882:10:0::1;105877:24;105902:8:::0;;105911:1;105902:11;;::::1;;;;;:::i;:::-;;;;;;;105877:37;;;;;;;;;;;;;16309:25:1::0;;16297:2;16282:18;;16163:177;105877:37:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;105877:51:0::1;;105869:97;;;::::0;-1:-1:-1;;;105869:97:0;;27184:2:1;105869:97:0::1;::::0;::::1;27166:21:1::0;27223:2;27203:18;;;27196:30;27262:34;27242:18;;;27235:62;-1:-1:-1;;;27313:18:1;;;27306:31;27354:19;;105869:97:0::1;26982:397:1::0;105869:97:0::1;105981:23;106007:7;:20;106015:8;;106024:1;106015:11;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;::::1;;106007:20:::0;;-1:-1:-1;106007:20:0;;::::1;::::0;;;;;;;;-1:-1:-1;106007:20:0;105981:46;;;;::::1;::::0;;;;::::1;;;::::0;::::1;::::0;;;;-1:-1:-1;106042:61:0::1;;;::::0;-1:-1:-1;;;106042:61:0;;18176:2:1;106042:61:0::1;::::0;::::1;18158:21:1::0;18215:2;18195:18;;;18188:30;18254:33;18234:18;;;18227:61;18305:18;;106042:61:0::1;17974:355:1::0;106042:61:0::1;-1:-1:-1::0;105767:3:0;::::1;::::0;::::1;:::i;:::-;;;;105729:386;;;;106125:12;106140:13;:11;:13::i;:::-;106201:9;::::0;106125:28;;-1:-1:-1;106172:25:0::1;106182:8:::0;106125:28;106172:25:::1;:::i;:::-;:38;;106164:71;;;;-1:-1:-1::0;;;106164:71:0::1;;;;;;;:::i;:::-;106250:6;106246:313;106258:19:::0;;::::1;106246:313;;;106298:13;:15:::0;;;:13:::1;:15;::::0;::::1;:::i;:::-;;;;;;106328:24;106355:7;:20;106363:8;;106372:1;106363:11;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;::::1;;106355:20:::0;;-1:-1:-1;106355:20:0;::::1;::::0;;;;;;-1:-1:-1;106355:20:0;;;106390:23;;-1:-1:-1;;106390:23:0::1;106409:4;106390:23;::::0;;106355:20;-1:-1:-1;106443:9:0::1;::::0;::::1;:::i;:::-;;;;106428:24;;106467:26;106473:10;106485:7;106467:5;:26::i;:::-;106513:27;::::0;16309:25:1;;;106520:10:0::1;::::0;106513:27:::1;::::0;16297:2:1;16282:18;106513:27:0::1;;;;;;;106283:276;;106279:3;;;;:::i;:::-;;;106246:313;;;;105593:975;105531:1037:::0;;:::o;102313:411::-;102443:26;;-1:-1:-1;;13059:2:1;13055:15;;;13051:53;102443:26:0;;;13039:66:1;102400:4:0;;;;13121:12:1;;102443:26:0;;;;;;;;;;;;102433:37;;;;;;102417:53;;102496:6;102491:189;102512:6;:13;102508:1;:17;102491:189;;;102563:6;102570:1;102563:9;;;;;;;;:::i;:::-;;;;;;;102555:5;:17;:113;;102650:6;102657:1;102650:9;;;;;;;;:::i;:::-;;;;;;;102661:5;102633:34;;;;;;;;13301:19:1;;;13345:2;13336:12;;13329:28;13382:2;13373:12;;13144:247;102633:34:0;;;;;;;;;;;;;102623:45;;;;;;102555:113;;;102602:5;102609:6;102616:1;102609:9;;;;;;;;:::i;:::-;;;;;;;102585:34;;;;;;;;13301:19:1;;;13345:2;13336:12;;13329:28;13382:2;13373:12;;13144:247;102585:34:0;;;;;;;;;;;;;102575:45;;;;;;102555:113;102547:121;-1:-1:-1;102527:3:0;;;;:::i;:::-;;;;102491:189;;;-1:-1:-1;102706:10:0;;102697:19;;102313:411;-1:-1:-1;;;102313:411:0:o;110969:181::-;47038:10;47027:22;;;;:10;:22;;;;;;;;47019:52;;;;-1:-1:-1;;;47019:52:0;;;;;;;:::i;:::-;111077:27:::1;:15;111095:9:::0;;111077:27:::1;:::i;:::-;-1:-1:-1::0;111115:27:0::1;:15;111133:9:::0;;111115:27:::1;:::i;:::-;;110969:181:::0;;;;:::o;84458:336::-;84530:4;-1:-1:-1;;;;;84555:19:0;;84547:74;;;;-1:-1:-1;;;84547:74:0;;25604:2:1;84547:74:0;;;25586:21:1;25643:2;25623:18;;;25616:30;25682:34;25662:18;;;25655:62;-1:-1:-1;;;25733:18:1;;;25726:40;25783:19;;84547:74:0;25402:406:1;84547:74:0;84634:10;84660:6;84655:109;84672:7;:14;84668:18;;84655:109;;;84719:7;84727:1;84719:10;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;84710:19:0;;;84719:10;;84710:19;84706:46;;;84745:7;;;:::i;:::-;;;84706:46;84688:3;;;:::i;:::-;;;84655:109;;;-1:-1:-1;84781:5:0;84458:336;-1:-1:-1;;84458:336:0:o;45954:103::-;45349:7;45376:6;-1:-1:-1;;;;;45376:6:0;31420:10;45523:23;45515:68;;;;-1:-1:-1;;;45515:68:0;;;;;;;:::i;:::-;46019:30:::1;46046:1;46019:18;:30::i;:::-;45954:103::o:0;112899:108::-;47038:10;47027:22;;;;:10;:22;;;;;;;;47019:52;;;;-1:-1:-1;;;47019:52:0;;;;;;;:::i;:::-;112975:10:::1;:24:::0;112899:108::o;110184:310::-;47038:10;47027:22;;;;:10;:22;;;;;;;;47019:52;;;;-1:-1:-1;;;47019:52:0;;;;;;;:::i;:::-;110292:12:::1;::::0;::::1;;:29;;::::0;::::1;;;;::::0;:76:::1;;-1:-1:-1::0;110325:19:0::1;::::0;::::1;;::::0;;::::1;;:43;;::::0;::::1;;;;110292:76;110284:110;;;;-1:-1:-1::0;;;110284:110:0::1;;;;;;;:::i;:::-;110405:12;:28:::0;;-1:-1:-1;;110444:42:0;110405:28;::::1;;-1:-1:-1::0;;110444:42:0;;;;;110405:28:::1;110444:42:::0;::::1;;::::0;;;::::1;;::::0;;110184:310::o;107634:342::-;47038:10;47027:22;;;;:10;:22;;;;;;;;47019:52;;;;-1:-1:-1;;;47019:52:0;;;;;;;:::i;:::-;107741:6:::1;107737:232;107749:20:::0;;::::1;107737:232;;;107798:21;107806:9;;107816:1;107806:12;;;;;;;:::i;:::-;;;;;;;107798:7;:21::i;:::-;107790:60;;;::::0;-1:-1:-1;;;107790:60:0;;26425:2:1;107790:60:0::1;::::0;::::1;26407:21:1::0;26464:2;26444:18;;;26437:30;26503:28;26483:18;;;26476:56;26549:18;;107790:60:0::1;26223:350:1::0;107790:60:0::1;107898:6;-1:-1:-1::0;;;;;107873:31:0::1;:7;107881:9;;107891:1;107881:12;;;;;;;:::i;:::-;;;;;;;107873:21;;;;;;;;:::i;:::-;;::::0;;;::::1;::::0;;;::::1;::::0;-1:-1:-1;;;;;107873:21:0::1;:31;107865:58;;;::::0;-1:-1:-1;;;107865:58:0;;22123:2:1;107865:58:0::1;::::0;::::1;22105:21:1::0;22162:2;22142:18;;;22135:30;-1:-1:-1;;;22181:18:1;;;22174:44;22235:18;;107865:58:0::1;21921:338:1::0;107865:58:0::1;107938:19;107944:9;;107954:1;107944:12;;;;;;;:::i;:::-;;;;;;;107938:5;:19::i;:::-;107771:3;::::0;::::1;:::i;:::-;;;107737:232;;97255:100:::0;97306:7;97333;97341:5;97333:14;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;97333:14:0;;97255:100;-1:-1:-1;;97255:100:0:o;111693:147::-;47038:10;47027:22;;;;:10;:22;;;;;;;;47019:52;;;;-1:-1:-1;;;47019:52:0;;;;;;;:::i;:::-;111775:6:::1;111766:5;;:15;;111758:49;;;;-1:-1:-1::0;;;111758:49:0::1;;;;;;;:::i;:::-;111818:5;:14:::0;111693:147::o;85469:106::-;85527:13;85560:7;85553:14;;;;;:::i;86528:295::-;-1:-1:-1;;;;;86633:24:0;;31420:10;86633:24;;86625:62;;;;-1:-1:-1;;;86625:62:0;;21769:2:1;86625:62:0;;;21751:21:1;21808:2;21788:18;;;21781:30;21847:27;21827:18;;;21820:55;21892:18;;86625:62:0;21567:349:1;86625:62:0;31420:10;86698:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;86698:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;86698:53:0;;;;;;;;;;86767:48;;16111:41:1;;;86698:42:0;;31420:10;86767:48;;16084:18:1;86767:48:0;;;;;;;86528:295;;:::o;92987:245::-;93117:6;93113:112;93125:19;;;93113:112;;;93166:47;93184:4;93190:2;93194:8;;93203:1;93194:11;;;;;;;:::i;:::-;;;;;;;93207:4;;93166:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;93166:16:0;;-1:-1:-1;;;93166:47:0:i;:::-;93146:3;;;:::i;:::-;;;93113:112;;;;92987:245;;;;;;:::o;87365:325::-;87537:41;31420:10;87570:7;87537:18;:41::i;:::-;87529:103;;;;-1:-1:-1;;;87529:103:0;;;;;;;:::i;:::-;87643:39;87657:4;87663:2;87667:7;87676:5;87643:13;:39::i;109123:753::-;47038:10;47027:22;;;;:10;:22;;;;;;;;47019:52;;;;-1:-1:-1;;;47019:52:0;;;;;;;:::i;:::-;109243:38;;::::1;109235:93;;;::::0;-1:-1:-1;;;109235:93:0;;32232:2:1;109235:93:0::1;::::0;::::1;32214:21:1::0;32271:2;32251:18;;;32244:30;32310:34;32290:18;;;32283:62;-1:-1:-1;;;32361:18:1;;;32354:40;32411:19;;109235:93:0::1;32030:406:1::0;109235:93:0::1;109341:10;109362:12:::0;109385::::1;109425:6:::0;109421:448:::1;109433:20:::0;;::::1;109421:448;;;109479:11;;109491:1;109479:14;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;109474:19:::0;-1:-1:-1;109542:1:0::1;109516:11:::0;;109528:1;109516:14;;::::1;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1::0;;;;;109516:28:0::1;;;109508:78;;;::::0;-1:-1:-1;;;109508:78:0;;23241:2:1;109508:78:0::1;::::0;::::1;23223:21:1::0;23280:2;23260:18;;;23253:30;23319:34;23299:18;;;23292:62;-1:-1:-1;;;23370:18:1;;;23363:35;23415:19;;109508:78:0::1;23039:401:1::0;109508:78:0::1;109613:9;;109623:1;109613:12;;;;;;;:::i;:::-;;;;;;;109603:22;;109649:16;109657:7;109649;:16::i;:::-;109648:17;109640:62;;;::::0;-1:-1:-1;;;109640:62:0;;31458:2:1;109640:62:0::1;::::0;::::1;31440:21:1::0;;;31477:18;;;31470:30;31536:34;31516:18;;;31509:62;31588:18;;109640:62:0::1;31256:356:1::0;109640:62:0::1;109738:2;109719:7;109727;109719:16;;;;;;;;:::i;:::-;;;;;;;;;:21;;;;;-1:-1:-1::0;;;;;109719:21:0::1;;;;;-1:-1:-1::0;;;;;109719:21:0::1;;;;;;109787:23;109796:4;109802:7;109787:8;:23::i;:::-;109849:7;109845:2;-1:-1:-1::0;;;;;109830:27:0::1;109839:4;-1:-1:-1::0;;;;;109830:27:0::1;-1:-1:-1::0;;;;;;;;;;;109830:27:0::1;;;;;;;;;109455:3;::::0;::::1;:::i;:::-;;;109421:448;;;;109224:652;;;109123:753:::0;;;;:::o;101965:249::-;102029:13;102063:16;102071:7;102063;:16::i;:::-;102055:55;;;;-1:-1:-1;;;102055:55:0;;16771:2:1;102055:55:0;;;16753:21:1;16810:2;16790:18;;;16783:30;16849:28;16829:18;;;16822:56;16895:18;;102055:55:0;16569:350:1;102055:55:0;102152:15;102169:18;:7;:16;:18::i;:::-;102189:15;102135:70;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;102121:85;;101965:249;;;:::o;112090:676::-;47038:10;47027:22;;;;:10;:22;;;;;;;;47019:52;;;;-1:-1:-1;;;47019:52:0;;;;;;;:::i;:::-;112262:17:::1;112242:16;;:37;;:70;;;;112299:13;112283:12;;:29;;112242:70;:115;;;;112338:19;112316:18;;:41;;112242:115;:152;;;;112379:15;112361:14;;:33;;112242:152;112234:186;;;;-1:-1:-1::0;;;112234:186:0::1;;;;;;;:::i;:::-;112460:19;112439:17;:40;;112431:73;;;::::0;-1:-1:-1;;;112431:73:0;;17482:2:1;112431:73:0::1;::::0;::::1;17464:21:1::0;17521:2;17501:18;;;17494:30;-1:-1:-1;;;17540:18:1;;;17533:50;17600:18;;112431:73:0::1;17280:344:1::0;112431:73:0::1;112539:14;;112523:12;;:30;;112515:63;;;::::0;-1:-1:-1;;;112515:63:0;;17482:2:1;112515:63:0::1;::::0;::::1;17464:21:1::0;17521:2;17501:18;;;17494:30;-1:-1:-1;;;17540:18:1;;;17533:50;17600:18;;112515:63:0::1;17280:344:1::0;112515:63:0::1;112589:16;:36:::0;;;;112636:12:::1;:28:::0;;;;112675:18:::1;:40:::0;112726:14:::1;:32:::0;112090:676::o;113373:139::-;45349:7;45376:6;-1:-1:-1;;;;;45376:6:0;31420:10;45523:23;45515:68;;;;-1:-1:-1;;;45515:68:0;;;;;;;:::i;:::-;113468:36:::1;113478:5;113485:7;113494:9;113468;:36::i;106728:686::-:0;101702:10;101716:9;101702:23;101694:55;;;;-1:-1:-1;;;101694:55:0;;;;;;;:::i;:::-;106828:12:::1;::::0;::::1;;106820:44;;;;-1:-1:-1::0;;;106820:44:0::1;;;;;;;:::i;:::-;106883:26;106897:3;106902:6;106883:13;:26::i;:::-;106875:68;;;::::0;-1:-1:-1;;;106875:68:0;;33760:2:1;106875:68:0::1;::::0;::::1;33742:21:1::0;33799:2;33779:18;;;33772:30;33838:31;33818:18;;;33811:59;33887:18;;106875:68:0::1;33558:353:1::0;106875:68:0::1;-1:-1:-1::0;;;;;106962:29:0;::::1;;::::0;;;:24:::1;:29;::::0;;;;;::::1;;:37;;:29:::0;:37:::1;;106954:65;;;::::0;-1:-1:-1;;;106954:65:0;;33416:2:1;106954:65:0::1;::::0;::::1;33398:21:1::0;33455:2;33435:18;;;33428:30;-1:-1:-1;;;33474:18:1;;;33467:45;33529:18;;106954:65:0::1;33214:339:1::0;106954:65:0::1;107030:12;107045:13;:11;:13::i;:::-;107092:9;::::0;107030:28;;-1:-1:-1;107077:11:0::1;107030:28:::0;107087:1:::1;107077:11;:::i;:::-;:24;;107069:57;;;;-1:-1:-1::0;;;107069:57:0::1;;;;;;;:::i;:::-;107169:16;::::0;107145::::1;::::0;:20:::1;::::0;107164:1:::1;107145:20;:::i;:::-;:40;;107137:85;;;::::0;-1:-1:-1;;;107137:85:0;;33055:2:1;107137:85:0::1;::::0;::::1;33037:21:1::0;;;33074:18;;;33067:30;33133:34;33113:18;;;33106:62;33185:18;;107137:85:0::1;32853:356:1::0;107137:85:0::1;-1:-1:-1::0;;;;;107233:29:0;::::1;;::::0;;;:24:::1;:29;::::0;;;;:36;;-1:-1:-1;;107233:36:0::1;107265:4;107233:36;::::0;;107280:16:::1;:18:::0;;;::::1;::::0;::::1;:::i;:::-;;;;;;107309:12;107324:9;;;;:::i;:::-;;;;107309:24;;107344:19;107350:3;107355:7;107344:5;:19::i;:::-;107393:3;-1:-1:-1::0;;;;;107379:27:0::1;;107398:7;107379:27;;;;16309:25:1::0;;16297:2;16282:18;;16163:177;107379:27:0::1;;;;;;;;106809:605;;106728:686:::0;;:::o;108171:739::-;47038:10;47027:22;;;;:10;:22;;;;;;;;47019:52;;;;-1:-1:-1;;;47019:52:0;;;;;;;:::i;:::-;108293:35;;::::1;108285:92;;;::::0;-1:-1:-1;;;108285:92:0;;31819:2:1;108285:92:0::1;::::0;::::1;31801:21:1::0;31858:2;31838:18;;;31831:30;31897:34;31877:18;;;31870:62;-1:-1:-1;;;31948:18:1;;;31941:42;32000:19;;108285:92:0::1;31617:408:1::0;108285:92:0::1;108390:19;108420:12:::0;108435:13:::1;:11;:13::i;:::-;108420:28;;108463:6;108459:91;108471:18:::0;;::::1;108459:91;;;108528:7;;108536:1;108528:10;;;;;;;:::i;:::-;;;;;;;108510:28;;;;;:::i;:::-;::::0;-1:-1:-1;108491:3:0::1;::::0;::::1;:::i;:::-;;;108459:91;;;-1:-1:-1::0;108596:9:0::1;::::0;108568:24:::1;108578:14:::0;108568:7;:24:::1;:::i;:::-;:37;;108560:70;;;;-1:-1:-1::0;;;108560:70:0::1;;;;;;;:::i;:::-;108647:6;108643:260;108655:21:::0;;::::1;108643:260;;;108701:6;108697:195;108713:7;;108721:1;108713:10;;;;;;;:::i;:::-;;;;;;;108709:1;:14;108697:195;;;108748:12;108763:9;::::0;::::1;:::i;:::-;;;;108748:24;;108791:29;108797:10;;108808:1;108797:13;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;108812:7;108791:5;:29::i;:::-;108844:32;::::0;16309:25:1;;;108856:10:0::1;::::0;108844:32:::1;::::0;16297:2:1;16282:18;108844:32:0::1;;;;;;;-1:-1:-1::0;108725:3:0::1;::::0;::::1;:::i;:::-;;;108697:195;;;-1:-1:-1::0;108678:3:0::1;::::0;::::1;:::i;:::-;;;108643:260;;47346:161:::0;45349:7;45376:6;-1:-1:-1;;;;;45376:6:0;31420:10;45523:23;45515:68;;;;-1:-1:-1;;;45515:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;47432:20:0;::::1;;::::0;;;47455:4:::1;47432:20;::::0;;;;;;;:27;;-1:-1:-1;;47432:27:0::1;::::0;;::::1;::::0;;47466:35:::1;47443:8:::0;47466:23:::1;:35::i;:::-;47346:161:::0;:::o;104643:642::-;101702:10;101716:9;101702:23;101694:55;;;;-1:-1:-1;;;101694:55:0;;;;;;;:::i;:::-;104725:19:::1;::::0;::::1;::::0;::::1;;;104717:59;;;::::0;-1:-1:-1;;;104717:59:0;;17126:2:1;104717:59:0::1;::::0;::::1;17108:21:1::0;17165:2;17145:18;;;17138:30;17204:29;17184:18;;;17177:57;17251:18;;104717:59:0::1;16924:351:1::0;104717:59:0::1;104816:7;104808:5;;:15;;;;:::i;:::-;104795:9;:28;;104787:67;;;::::0;-1:-1:-1;;;104787:67:0;;20187:2:1;104787:67:0::1;::::0;::::1;20169:21:1::0;20226:2;20206:18;;;20199:30;20265:28;20245:18;;;20238:56;20311:18;;104787:67:0::1;19985:350:1::0;104787:67:0::1;104865:12;104880:13;:11;:13::i;:::-;104933:9;::::0;104865:28;;-1:-1:-1;104912:17:0::1;104922:7:::0;104865:28;104912:17:::1;:::i;:::-;:30;;104904:63;;;;-1:-1:-1::0;;;104904:63:0::1;;;;;;;:::i;:::-;105013:13;;105002:7;104986:13;;:23;;;;:::i;:::-;:40;;104978:86;;;::::0;-1:-1:-1;;;104978:86:0;;30225:2:1;104978:86:0::1;::::0;::::1;30207:21:1::0;30264:2;30244:18;;;30237:30;30303:34;30283:18;;;30276:62;-1:-1:-1;;;30354:18:1;;;30347:31;30395:19;;104978:86:0::1;30023:397:1::0;104978:86:0::1;105079:6;105075:203;105091:7;105087:1;:11;105075:203;;;105119:13;:15:::0;;;:13:::1;:15;::::0;::::1;:::i;:::-;;;;;;105149:12;105164:9;;;;:::i;:::-;;;;105149:24;;105188:26;105194:10;105206:7;105188:5;:26::i;:::-;105234:32;::::0;16309:25:1;;;105246:10:0::1;::::0;105234:32:::1;::::0;16297:2:1;16282:18;105234:32:0::1;;;;;;;-1:-1:-1::0;105100:3:0::1;::::0;::::1;:::i;:::-;;;105075:203;;97486:439:::0;-1:-1:-1;;;;;97574:16:0;;97546:7;97574:16;;;:7;:16;;;;;;97566:71;;;;-1:-1:-1;;;97566:71:0;;;;;;;:::i;:::-;97650:21;97698:14;;97674:21;:38;;;;:::i;:::-;-1:-1:-1;;;;;97793:18:0;;97723:15;97793:18;;;:9;:18;;;;;;;;;97778:12;;97758:7;:16;;;;;;;97650:62;;-1:-1:-1;97723:15:0;;97742:32;;97650:62;97742:32;:::i;:::-;97741:49;;;;:::i;:::-;:70;;;;:::i;:::-;97723:88;-1:-1:-1;97830:12:0;97822:68;;;;-1:-1:-1;;;97822:68:0;;;;;;;:::i;85156:305::-;85258:4;-1:-1:-1;;;;;;85295:40:0;;-1:-1:-1;;;85295:40:0;;:105;;-1:-1:-1;;;;;;;85352:48:0;;-1:-1:-1;;;85352:48:0;85295:105;:158;;;-1:-1:-1;;;;;;;;;;23437:40:0;;;85417:36;23328:157;89169:152;89265:7;:14;89231:4;;89255:24;;:58;;;;;89311:1;-1:-1:-1;;;;;89283:30:0;:7;89291;89283:16;;;;;;;;:::i;:::-;;;;;;;;;;;-1:-1:-1;;;;;89283:16:0;:30;;89248:65;89169:152;-1:-1:-1;;89169:152:0:o;87716:172::-;87788:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;87788:29:0;-1:-1:-1;;;;;87788:29:0;;;;;;;;:24;;87842;87788;87842:15;:24::i;:::-;-1:-1:-1;;;;;87833:47:0;;;;;;;;;;;87716:172;;:::o;99247:474::-;-1:-1:-1;;;;;99328:21:0;;99320:78;;;;-1:-1:-1;;;99320:78:0;;19367:2:1;99320:78:0;;;19349:21:1;19406:2;19386:18;;;19379:30;19445:34;19425:18;;;19418:62;-1:-1:-1;;;19496:18:1;;;19489:42;19548:19;;99320:78:0;19165:408:1;99320:78:0;99427:1;99417:7;:11;99409:53;;;;-1:-1:-1;;;99409:53:0;;34118:2:1;99409:53:0;;;34100:21:1;34157:2;34137:18;;;34130:30;34196:31;34176:18;;;34169:59;34245:18;;99409:53:0;33916:353:1;99409:53:0;-1:-1:-1;;;;;99481:16:0;;;;;;:7;:16;;;;;;:21;99473:77;;;;-1:-1:-1;;;99473:77:0;;32643:2:1;99473:77:0;;;32625:21:1;32682:2;32662:18;;;32655:30;32721:34;32701:18;;;32694:62;-1:-1:-1;;;32772:18:1;;;32765:41;32823:19;;99473:77:0;32441:407:1;99473:77:0;99563:7;:21;;;;;;;;;;;;-1:-1:-1;;;;;;99563:21:0;-1:-1:-1;;;;;99563:21:0;;;;;;;;-1:-1:-1;99595:16:0;;;:7;99563:21;99595:16;;;;:26;;;99647:12;;:22;;99595:26;;99647:22;:::i;:::-;99632:12;:37;99685:28;;;-1:-1:-1;;;;;14475:32:1;;14457:51;;14539:2;14524:18;;14517:34;;;99685:28:0;;14430:18:1;99685:28:0;;;;;;;99247:474;;:::o;50006:317::-;50121:6;50096:21;:31;;50088:73;;;;-1:-1:-1;;;50088:73:0;;23996:2:1;50088:73:0;;;23978:21:1;24035:2;24015:18;;;24008:30;24074:31;24054:18;;;24047:59;24123:18;;50088:73:0;23794:353:1;50088:73:0;50175:12;50193:9;-1:-1:-1;;;;;50193:14:0;50215:6;50193:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;50174:52;;;50245:7;50237:78;;;;-1:-1:-1;;;50237:78:0;;22814:2:1;50237:78:0;;;22796:21:1;22853:2;22833:18;;;22826:30;22892:34;22872:18;;;22865:62;22963:28;22943:18;;;22936:56;23009:19;;50237:78:0;22612:422:1;89329:346:0;89419:4;89444:16;89452:7;89444;:16::i;:::-;89436:73;;;;-1:-1:-1;;;89436:73:0;;24354:2:1;89436:73:0;;;24336:21:1;24393:2;24373:18;;;24366:30;24432:34;24412:18;;;24405:62;-1:-1:-1;;;24483:18:1;;;24476:42;24535:19;;89436:73:0;24152:408:1;89436:73:0;89520:13;89536:24;89552:7;89536:15;:24::i;:::-;89520:40;;89590:5;-1:-1:-1;;;;;89579:16:0;:7;-1:-1:-1;;;;;89579:16:0;;:51;;;;89623:7;-1:-1:-1;;;;;89599:31:0;:20;89611:7;89599:11;:20::i;:::-;-1:-1:-1;;;;;89599:31:0;;89579:51;:87;;;-1:-1:-1;;;;;;86477:25:0;;;86453:4;86477:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;89634:32;89571:96;89329:346;-1:-1:-1;;;;89329:346:0:o;90897:514::-;91054:4;-1:-1:-1;;;;;91026:32:0;:24;91042:7;91026:15;:24::i;:::-;-1:-1:-1;;;;;91026:32:0;;91018:86;;;;-1:-1:-1;;;91018:86:0;;29058:2:1;91018:86:0;;;29040:21:1;29097:2;29077:18;;;29070:30;29136:34;29116:18;;;29109:62;-1:-1:-1;;;29187:18:1;;;29180:39;29236:19;;91018:86:0;28856:405:1;91018:86:0;-1:-1:-1;;;;;91123:16:0;;91115:65;;;;-1:-1:-1;;;91115:65:0;;21364:2:1;91115:65:0;;;21346:21:1;21403:2;21383:18;;;21376:30;21442:34;21422:18;;;21415:62;-1:-1:-1;;;21493:18:1;;;21486:34;21537:19;;91115:65:0;21162:400:1;91115:65:0;91297:29;91314:1;91318:7;91297:8;:29::i;:::-;91356:2;91337:7;91345;91337:16;;;;;;;;:::i;:::-;;;;;;;;;:21;;-1:-1:-1;;;;;;91337:21:0;-1:-1:-1;;;;;91337:21:0;;;;;;91376:27;;91395:7;;91376:27;;;;;;;;-1:-1:-1;;;;;;;;;;;91376:27:0;91337:16;91376:27;90897:514;;;:::o;113816:143::-;113886:7;:16;;;;;;;-1:-1:-1;113886:16:0;;;;;;;-1:-1:-1;;;;;;113886:16:0;-1:-1:-1;;;;;113886:16:0;;;;;;;;113918:33;;113943:7;;-1:-1:-1;;;;;;;;;;;;113918:33:0;-1:-1:-1;;113918:33:0;113816:143;;:::o;46573:191::-;46647:16;46666:6;;-1:-1:-1;;;;;46683:17:0;;;-1:-1:-1;;;;;;46683:17:0;;;;;;46716:40;;46666:6;;;;;;;46716:40;;46647:16;46716:40;46636:128;46573:191;:::o;113537:271::-;113595:16;113614:24;113630:7;113614:15;:24::i;:::-;113595:43;;113679:26;113688:7;45349;45376:6;-1:-1:-1;;;;;45376:6:0;;45303:87;113688:7;113697;113679:8;:26::i;:::-;113743:1;113716:7;113724;113716:16;;;;;;;;:::i;:::-;;;;;;;;;:29;;-1:-1:-1;;;;;;113716:29:0;-1:-1:-1;;;;;113716:29:0;;;;;;113761:39;;113792:7;;113761:39;;;-1:-1:-1;;;;;;;;;;;113761:39:0;113716:16;;113761:39;113584:224;113537:271;:::o;90577:312::-;90731:28;90741:4;90747:2;90751:7;90731:9;:28::i;:::-;90778:48;90801:4;90807:2;90811:7;90820:5;90778:22;:48::i;:::-;90770:111;;;;-1:-1:-1;;;90770:111:0;;;;;;;:::i;18733:723::-;18789:13;19010:10;19006:53;;-1:-1:-1;;19037:10:0;;;;;;;;;;;;-1:-1:-1;;;19037:10:0;;;;;18733:723::o;19006:53::-;19084:5;19069:12;19125:78;19132:9;;19125:78;;19158:8;;;;:::i;:::-;;-1:-1:-1;19181:10:0;;-1:-1:-1;19189:2:0;19181:10;;:::i;:::-;;;19125:78;;;19213:19;19245:6;-1:-1:-1;;;;;19235:17:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19235:17:0;;19213:39;;19263:154;19270:10;;19263:154;;19297:11;19307:1;19297:11;;:::i;:::-;;-1:-1:-1;19366:10:0;19374:2;19366:5;:10;:::i;:::-;19353:24;;:2;:24;:::i;:::-;19340:39;;19323:6;19330;19323:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;19323:56:0;;;;;;;;-1:-1:-1;19394:11:0;19403:2;19394:11;;:::i;:::-;;;19263:154;;99729:232;-1:-1:-1;;;;;99845:18:0;;;;;;:7;:18;;;;;;99830:12;;99866:9;;99830:33;;;:::i;:::-;:45;;;;:::i;:::-;99815:12;:60;-1:-1:-1;;;;;99886:18:0;;;;;;:7;:18;;;;;:30;;;99927:7;:16;;99895:7;;99927;99936:5;;99927:16;;;;;;:::i;:::-;;;;;;;;;:26;;;;;-1:-1:-1;;;;;99927:26:0;;;;;-1:-1:-1;;;;;99927:26:0;;;;;;99729:232;;;:::o;46212:201::-;45349:7;45376:6;-1:-1:-1;;;;;45376:6:0;31420:10;45523:23;45515:68;;;;-1:-1:-1;;;45515:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;46301:22:0;::::1;46293:73;;;::::0;-1:-1:-1;;;46293:73:0;;19780:2:1;46293:73:0::1;::::0;::::1;19762:21:1::0;19819:2;19799:18;;;19792:30;19858:34;19838:18;;;19831:62;-1:-1:-1;;;19909:18:1;;;19902:36;19955:19;;46293:73:0::1;19578:402:1::0;46293:73:0::1;46377:28;46396:8;46377:18;:28::i;88365:796::-:0;88517:4;-1:-1:-1;;;;;88538:13:0;;49040:19;:23;88534:620;;88574:72;;-1:-1:-1;;;88574:72:0;;-1:-1:-1;;;;;88574:36:0;;;;;:72;;31420:10;;88625:4;;88631:7;;88640:5;;88574:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;88574:72:0;;;;;;;;-1:-1:-1;;88574:72:0;;;;;;;;;;;;:::i;:::-;;;88570:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;88816:13:0;;88812:272;;88859:60;;-1:-1:-1;;;88859:60:0;;;;;;;:::i;88812:272::-;89034:6;89028:13;89019:6;89015:2;89011:15;89004:38;88570:529;-1:-1:-1;;;;;;88697:51:0;-1:-1:-1;;;88697:51:0;;-1:-1:-1;88690:58:0;;-1:-1:-1;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:367:1;77:8;87:6;141:3;134:4;126:6;122:17;118:27;108:55;;159:1;156;149:12;108:55;-1:-1:-1;182:20:1;;-1:-1:-1;;;;;214:30:1;;211:50;;;257:1;254;247:12;211:50;294:4;286:6;282:17;270:29;;354:3;347:4;337:6;334:1;330:14;322:6;318:27;314:38;311:47;308:67;;;371:1;368;361:12;308:67;14:367;;;;;:::o;386:160::-;451:20;;507:13;;500:21;490:32;;480:60;;536:1;533;526:12;551:347;602:8;612:6;666:3;659:4;651:6;647:17;643:27;633:55;;684:1;681;674:12;633:55;-1:-1:-1;707:20:1;;-1:-1:-1;;;;;739:30:1;;736:50;;;782:1;779;772:12;736:50;819:4;811:6;807:17;795:29;;871:3;864:4;855:6;847;843:19;839:30;836:39;833:59;;;888:1;885;878:12;903:247;962:6;1015:2;1003:9;994:7;990:23;986:32;983:52;;;1031:1;1028;1021:12;983:52;1070:9;1057:23;1089:31;1114:5;1089:31;:::i;1155:251::-;1225:6;1278:2;1266:9;1257:7;1253:23;1249:32;1246:52;;;1294:1;1291;1284:12;1246:52;1326:9;1320:16;1345:31;1370:5;1345:31;:::i;1671:388::-;1739:6;1747;1800:2;1788:9;1779:7;1775:23;1771:32;1768:52;;;1816:1;1813;1806:12;1768:52;1855:9;1842:23;1874:31;1899:5;1874:31;:::i;:::-;1924:5;-1:-1:-1;1981:2:1;1966:18;;1953:32;1994:33;1953:32;1994:33;:::i;:::-;2046:7;2036:17;;;1671:388;;;;;:::o;2064:1022::-;2188:6;2196;2204;2212;2220;2228;2281:3;2269:9;2260:7;2256:23;2252:33;2249:53;;;2298:1;2295;2288:12;2249:53;2337:9;2324:23;2356:31;2381:5;2356:31;:::i;:::-;2406:5;-1:-1:-1;2463:2:1;2448:18;;2435:32;2476:33;2435:32;2476:33;:::i;:::-;2528:7;-1:-1:-1;2586:2:1;2571:18;;2558:32;-1:-1:-1;;;;;2639:14:1;;;2636:34;;;2666:1;2663;2656:12;2636:34;2705:70;2767:7;2758:6;2747:9;2743:22;2705:70;:::i;:::-;2794:8;;-1:-1:-1;2679:96:1;-1:-1:-1;2882:2:1;2867:18;;2854:32;;-1:-1:-1;2898:16:1;;;2895:36;;;2927:1;2924;2917:12;2895:36;;2966:60;3018:7;3007:8;2996:9;2992:24;2966:60;:::i;:::-;2064:1022;;;;-1:-1:-1;2064:1022:1;;-1:-1:-1;2064:1022:1;;3045:8;;2064:1022;-1:-1:-1;;;2064:1022:1:o;3091:456::-;3168:6;3176;3184;3237:2;3225:9;3216:7;3212:23;3208:32;3205:52;;;3253:1;3250;3243:12;3205:52;3292:9;3279:23;3311:31;3336:5;3311:31;:::i;:::-;3361:5;-1:-1:-1;3418:2:1;3403:18;;3390:32;3431:33;3390:32;3431:33;:::i;:::-;3091:456;;3483:7;;-1:-1:-1;;;3537:2:1;3522:18;;;;3509:32;;3091:456::o;3552:1108::-;3647:6;3655;3663;3671;3724:3;3712:9;3703:7;3699:23;3695:33;3692:53;;;3741:1;3738;3731:12;3692:53;3780:9;3767:23;3799:31;3824:5;3799:31;:::i;:::-;3849:5;-1:-1:-1;3873:2:1;3912:18;;;3899:32;3940:33;3899:32;3940:33;:::i;:::-;3992:7;-1:-1:-1;4046:2:1;4031:18;;4018:32;;-1:-1:-1;4101:2:1;4086:18;;4073:32;-1:-1:-1;;;;;4154:14:1;;;4151:34;;;4181:1;4178;4171:12;4151:34;4219:6;4208:9;4204:22;4194:32;;4264:7;4257:4;4253:2;4249:13;4245:27;4235:55;;4286:1;4283;4276:12;4235:55;4322:2;4309:16;4344:2;4340;4337:10;4334:36;;;4350:18;;:::i;:::-;4392:53;4435:2;4416:13;;-1:-1:-1;;4412:27:1;4408:36;;4392:53;:::i;:::-;4379:66;;4468:2;4461:5;4454:17;4508:7;4503:2;4498;4494;4490:11;4486:20;4483:33;4480:53;;;4529:1;4526;4519:12;4480:53;4584:2;4579;4575;4571:11;4566:2;4559:5;4555:14;4542:45;4628:1;4623:2;4618;4611:5;4607:14;4603:23;4596:34;;4649:5;4639:15;;;;;3552:1108;;;;;;;:::o;4665:1037::-;4758:6;4766;4819:2;4807:9;4798:7;4794:23;4790:32;4787:52;;;4835:1;4832;4825:12;4787:52;4874:9;4861:23;4893:31;4918:5;4893:31;:::i;:::-;4943:5;-1:-1:-1;4967:2:1;5005:18;;;4992:32;-1:-1:-1;;;;;5036:30:1;;5033:50;;;5079:1;5076;5069:12;5033:50;5102:22;;5155:4;5147:13;;5143:27;-1:-1:-1;5133:55:1;;5184:1;5181;5174:12;5133:55;5220:2;5207:16;5243:60;5259:43;5299:2;5259:43;:::i;:::-;5243:60;:::i;:::-;5325:3;5349:2;5344:3;5337:15;5377:2;5372:3;5368:12;5361:19;;5408:2;5404;5400:11;5456:7;5451:2;5445;5442:1;5438:10;5434:2;5430:19;5426:28;5423:41;5420:61;;;5477:1;5474;5467:12;5420:61;5499:1;5490:10;;5509:163;5523:2;5520:1;5517:9;5509:163;;;5580:17;;5568:30;;5541:1;5534:9;;;;;5618:12;;;;5650;;5509:163;;;5513:3;5691:5;5681:15;;;;;;;4665:1037;;;;;:::o;5707:572::-;5802:6;5810;5818;5871:2;5859:9;5850:7;5846:23;5842:32;5839:52;;;5887:1;5884;5877:12;5839:52;5926:9;5913:23;5945:31;5970:5;5945:31;:::i;:::-;5995:5;-1:-1:-1;6051:2:1;6036:18;;6023:32;-1:-1:-1;;;;;6067:30:1;;6064:50;;;6110:1;6107;6100:12;6064:50;6149:70;6211:7;6202:6;6191:9;6187:22;6149:70;:::i;:::-;5707:572;;6238:8;;-1:-1:-1;6123:96:1;;-1:-1:-1;;;;5707:572:1:o;6284:315::-;6349:6;6357;6410:2;6398:9;6389:7;6385:23;6381:32;6378:52;;;6426:1;6423;6416:12;6378:52;6465:9;6452:23;6484:31;6509:5;6484:31;:::i;:::-;6534:5;-1:-1:-1;6558:35:1;6589:2;6574:18;;6558:35;:::i;:::-;6548:45;;6284:315;;;;;:::o;6604:::-;6672:6;6680;6733:2;6721:9;6712:7;6708:23;6704:32;6701:52;;;6749:1;6746;6739:12;6701:52;6788:9;6775:23;6807:31;6832:5;6807:31;:::i;:::-;6857:5;6909:2;6894:18;;;;6881:32;;-1:-1:-1;;;6604:315:1:o;6924:437::-;7010:6;7018;7071:2;7059:9;7050:7;7046:23;7042:32;7039:52;;;7087:1;7084;7077:12;7039:52;7127:9;7114:23;-1:-1:-1;;;;;7152:6:1;7149:30;7146:50;;;7192:1;7189;7182:12;7146:50;7231:70;7293:7;7284:6;7273:9;7269:22;7231:70;:::i;:::-;7320:8;;7205:96;;-1:-1:-1;6924:437:1;-1:-1:-1;;;;6924:437:1:o;7366:773::-;7488:6;7496;7504;7512;7565:2;7553:9;7544:7;7540:23;7536:32;7533:52;;;7581:1;7578;7571:12;7533:52;7621:9;7608:23;-1:-1:-1;;;;;7691:2:1;7683:6;7680:14;7677:34;;;7707:1;7704;7697:12;7677:34;7746:70;7808:7;7799:6;7788:9;7784:22;7746:70;:::i;:::-;7835:8;;-1:-1:-1;7720:96:1;-1:-1:-1;7923:2:1;7908:18;;7895:32;;-1:-1:-1;7939:16:1;;;7936:36;;;7968:1;7965;7958:12;7936:36;;8007:72;8071:7;8060:8;8049:9;8045:24;8007:72;:::i;:::-;7366:773;;;;-1:-1:-1;8098:8:1;-1:-1:-1;;;;7366:773:1:o;8144:892::-;8239:6;8270:2;8313;8301:9;8292:7;8288:23;8284:32;8281:52;;;8329:1;8326;8319:12;8281:52;8362:9;8356:16;-1:-1:-1;;;;;8387:6:1;8384:30;8381:50;;;8427:1;8424;8417:12;8381:50;8450:22;;8503:4;8495:13;;8491:27;-1:-1:-1;8481:55:1;;8532:1;8529;8522:12;8481:55;8561:2;8555:9;8584:60;8600:43;8640:2;8600:43;:::i;8584:60::-;8666:3;8690:2;8685:3;8678:15;8718:2;8713:3;8709:12;8702:19;;8749:2;8745;8741:11;8797:7;8792:2;8786;8783:1;8779:10;8775:2;8771:19;8767:28;8764:41;8761:61;;;8818:1;8815;8808:12;8761:61;8840:1;8831:10;;8850:156;8864:2;8861:1;8858:9;8850:156;;;8921:10;;8909:23;;8882:1;8875:9;;;;;8952:12;;;;8984;;8850:156;;;-1:-1:-1;9025:5:1;8144:892;-1:-1:-1;;;;;;;8144:892:1:o;9041:248::-;9103:6;9111;9164:2;9152:9;9143:7;9139:23;9135:32;9132:52;;;9180:1;9177;9170:12;9132:52;9203:26;9219:9;9203:26;:::i;9294:180::-;9353:6;9406:2;9394:9;9385:7;9381:23;9377:32;9374:52;;;9422:1;9419;9412:12;9374:52;-1:-1:-1;9445:23:1;;9294:180;-1:-1:-1;9294:180:1:o;9479:245::-;9537:6;9590:2;9578:9;9569:7;9565:23;9561:32;9558:52;;;9606:1;9603;9596:12;9558:52;9645:9;9632:23;9664:30;9688:5;9664:30;:::i;9729:249::-;9798:6;9851:2;9839:9;9830:7;9826:23;9822:32;9819:52;;;9867:1;9864;9857:12;9819:52;9899:9;9893:16;9918:30;9942:5;9918:30;:::i;9983:719::-;10075:6;10083;10091;10099;10152:2;10140:9;10131:7;10127:23;10123:32;10120:52;;;10168:1;10165;10158:12;10120:52;10208:9;10195:23;-1:-1:-1;;;;;10278:2:1;10270:6;10267:14;10264:34;;;10294:1;10291;10284:12;10264:34;10333:58;10383:7;10374:6;10363:9;10359:22;10333:58;:::i;:::-;10410:8;;-1:-1:-1;10307:84:1;-1:-1:-1;10498:2:1;10483:18;;10470:32;;-1:-1:-1;10514:16:1;;;10511:36;;;10543:1;10540;10533:12;10511:36;;10582:60;10634:7;10623:8;10612:9;10608:24;10582:60;:::i;10892:383::-;10969:6;10977;10985;11038:2;11026:9;11017:7;11013:23;11009:32;11006:52;;;11054:1;11051;11044:12;11006:52;11090:9;11077:23;11067:33;;11150:2;11139:9;11135:18;11122:32;11163:31;11188:5;11163:31;:::i;11280:385::-;11366:6;11374;11382;11390;11443:3;11431:9;11422:7;11418:23;11414:33;11411:53;;;11460:1;11457;11450:12;11411:53;-1:-1:-1;;11483:23:1;;;11553:2;11538:18;;11525:32;;-1:-1:-1;11604:2:1;11589:18;;11576:32;;11655:2;11640:18;11627:32;;-1:-1:-1;11280:385:1;-1:-1:-1;11280:385:1:o;11670:257::-;11711:3;11749:5;11743:12;11776:6;11771:3;11764:19;11792:63;11848:6;11841:4;11836:3;11832:14;11825:4;11818:5;11814:16;11792:63;:::i;:::-;11909:2;11888:15;-1:-1:-1;;11884:29:1;11875:39;;;;11916:4;11871:50;;11670:257;-1:-1:-1;;11670:257:1:o;11932:973::-;12017:12;;11982:3;;12072:1;12092:18;;;;12145;;;;12172:61;;12226:4;12218:6;12214:17;12204:27;;12172:61;12252:2;12300;12292:6;12289:14;12269:18;12266:38;12263:161;;;12346:10;12341:3;12337:20;12334:1;12327:31;12381:4;12378:1;12371:15;12409:4;12406:1;12399:15;12263:161;12440:18;12467:104;;;;12585:1;12580:319;;;;12433:466;;12467:104;-1:-1:-1;;12500:24:1;;12488:37;;12545:16;;;;-1:-1:-1;12467:104:1;;12580:319;34997:1;34990:14;;;35034:4;35021:18;;12674:1;12688:165;12702:6;12699:1;12696:13;12688:165;;;12780:14;;12767:11;;;12760:35;12823:16;;;;12717:10;;12688:165;;;12692:3;;12882:6;12877:3;12873:16;12866:23;;12433:466;;;;;;;11932:973;;;;:::o;13396:456::-;13617:3;13645:38;13679:3;13671:6;13645:38;:::i;:::-;13712:6;13706:13;13728:52;13773:6;13769:2;13762:4;13754:6;13750:17;13728:52;:::i;:::-;13796:50;13838:6;13834:2;13830:15;13822:6;13796:50;:::i;:::-;13789:57;13396:456;-1:-1:-1;;;;;;;13396:456:1:o;14562:488::-;-1:-1:-1;;;;;14831:15:1;;;14813:34;;14883:15;;14878:2;14863:18;;14856:43;14930:2;14915:18;;14908:34;;;14978:3;14973:2;14958:18;;14951:31;;;14756:4;;14999:45;;15024:19;;15016:6;14999:45;:::i;:::-;14991:53;14562:488;-1:-1:-1;;;;;;14562:488:1:o;15334:632::-;15505:2;15557:21;;;15627:13;;15530:18;;;15649:22;;;15476:4;;15505:2;15728:15;;;;15702:2;15687:18;;;15476:4;15771:169;15785:6;15782:1;15779:13;15771:169;;;15846:13;;15834:26;;15915:15;;;;15880:12;;;;15807:1;15800:9;15771:169;;;-1:-1:-1;15957:3:1;;15334:632;-1:-1:-1;;;;;;15334:632:1:o;16345:219::-;16494:2;16483:9;16476:21;16457:4;16514:44;16554:2;16543:9;16539:18;16531:6;16514:44;:::i;17629:340::-;17831:2;17813:21;;;17870:2;17850:18;;;17843:30;-1:-1:-1;;;17904:2:1;17889:18;;17882:46;17960:2;17945:18;;17629:340::o;18746:414::-;18948:2;18930:21;;;18987:2;18967:18;;;18960:30;19026:34;19021:2;19006:18;;18999:62;-1:-1:-1;;;19092:2:1;19077:18;;19070:48;19150:3;19135:19;;18746:414::o;20340:402::-;20542:2;20524:21;;;20581:2;20561:18;;;20554:30;20620:34;20615:2;20600:18;;20593:62;-1:-1:-1;;;20686:2:1;20671:18;;20664:36;20732:3;20717:19;;20340:402::o;22264:343::-;22466:2;22448:21;;;22505:2;22485:18;;;22478:30;-1:-1:-1;;;22539:2:1;22524:18;;22517:49;22598:2;22583:18;;22264:343::o;23445:344::-;23647:2;23629:21;;;23686:2;23666:18;;;23659:30;-1:-1:-1;;;23720:2:1;23705:18;;23698:50;23780:2;23765:18;;23445:344::o;24565:407::-;24767:2;24749:21;;;24806:2;24786:18;;;24779:30;24845:34;24840:2;24825:18;;24818:62;-1:-1:-1;;;24911:2:1;24896:18;;24889:41;24962:3;24947:19;;24565:407::o;27384:343::-;27586:2;27568:21;;;27625:2;27605:18;;;27598:30;-1:-1:-1;;;27659:2:1;27644:18;;27637:49;27718:2;27703:18;;27384:343::o;28145:356::-;28347:2;28329:21;;;28366:18;;;28359:30;28425:34;28420:2;28405:18;;28398:62;28492:2;28477:18;;28145:356::o;28506:345::-;28708:2;28690:21;;;28747:2;28727:18;;;28720:30;-1:-1:-1;;;28781:2:1;28766:18;;28759:51;28842:2;28827:18;;28506:345::o;30425:413::-;30627:2;30609:21;;;30666:2;30646:18;;;30639:30;30705:34;30700:2;30685:18;;30678:62;-1:-1:-1;;;30771:2:1;30756:18;;30749:47;30828:3;30813:19;;30425:413::o;34456:275::-;34527:2;34521:9;34592:2;34573:13;;-1:-1:-1;;34569:27:1;34557:40;;-1:-1:-1;;;;;34612:34:1;;34648:22;;;34609:62;34606:88;;;34674:18;;:::i;:::-;34710:2;34703:22;34456:275;;-1:-1:-1;34456:275:1:o;34736:183::-;34796:4;-1:-1:-1;;;;;34821:6:1;34818:30;34815:56;;;34851:18;;:::i;:::-;-1:-1:-1;34896:1:1;34892:14;34908:4;34888:25;;34736:183::o;35050:128::-;35090:3;35121:1;35117:6;35114:1;35111:13;35108:39;;;35127:18;;:::i;:::-;-1:-1:-1;35163:9:1;;35050:128::o;35183:120::-;35223:1;35249;35239:35;;35254:18;;:::i;:::-;-1:-1:-1;35288:9:1;;35183:120::o;35308:168::-;35348:7;35414:1;35410;35406:6;35402:14;35399:1;35396:21;35391:1;35384:9;35377:17;35373:45;35370:71;;;35421:18;;:::i;:::-;-1:-1:-1;35461:9:1;;35308:168::o;35481:125::-;35521:4;35549:1;35546;35543:8;35540:34;;;35554:18;;:::i;:::-;-1:-1:-1;35591:9:1;;35481:125::o;35611:258::-;35683:1;35693:113;35707:6;35704:1;35701:13;35693:113;;;35783:11;;;35777:18;35764:11;;;35757:39;35729:2;35722:10;35693:113;;;35824:6;35821:1;35818:13;35815:48;;;-1:-1:-1;;35859:1:1;35841:16;;35834:27;35611:258::o;35874:380::-;35953:1;35949:12;;;;35996;;;36017:61;;36071:4;36063:6;36059:17;36049:27;;36017:61;36124:2;36116:6;36113:14;36093:18;36090:38;36087:161;;;36170:10;36165:3;36161:20;36158:1;36151:31;36205:4;36202:1;36195:15;36233:4;36230:1;36223:15;36087:161;;35874:380;;;:::o;36259:135::-;36298:3;-1:-1:-1;;36319:17:1;;36316:43;;;36339:18;;:::i;:::-;-1:-1:-1;36386:1:1;36375:13;;36259:135::o;36399:112::-;36431:1;36457;36447:35;;36462:18;;:::i;:::-;-1:-1:-1;36496:9:1;;36399:112::o;36516:127::-;36577:10;36572:3;36568:20;36565:1;36558:31;36608:4;36605:1;36598:15;36632:4;36629:1;36622:15;36648:127;36709:10;36704:3;36700:20;36697:1;36690:31;36740:4;36737:1;36730:15;36764:4;36761:1;36754:15;36780:127;36841:10;36836:3;36832:20;36829:1;36822:31;36872:4;36869:1;36862:15;36896:4;36893:1;36886:15;36912:127;36973:10;36968:3;36964:20;36961:1;36954:31;37004:4;37001:1;36994:15;37028:4;37025:1;37018:15;37044:131;-1:-1:-1;;;;;37119:31:1;;37109:42;;37099:70;;37165:1;37162;37155:12;37180:131;-1:-1:-1;;;;;;37254:32:1;;37244:43;;37234:71;;37301:1;37298;37291:12

Swarm Source

ipfs://47d4a4e83b14dea2402c32d3633606f1169451edc2ae47c8eb3da218fdd3a8f9
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]

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