ETH Price: $2,776.29 (+5.79%)

Token

Jungle Bay Ape Club (JBAC)
 

Overview

Max Total Supply

66,877,639.162869791716665574 JBAC

Holders

329

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
5,928.940125 JBAC

Value
$0.00
0x8ed850278ba7944b89035ffab8dcc601bf42a593
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:
JBACCOIN

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, GNU GPLv3 license

Contract Source Code (Solidity)

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

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


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

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.0;

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

// File: @openzeppelin/contracts/utils/structs/EnumerableSet.sol


// OpenZeppelin Contracts v4.4.1 (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/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/token/ERC721/IERC721.sol


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

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.0;


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

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

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

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


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

pragma solidity ^0.8.0;


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

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

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

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


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

pragma solidity ^0.8.0;








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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId);
    }

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

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

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

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

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

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


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

pragma solidity ^0.8.0;





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

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

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

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

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

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

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

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

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

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

        _revokeRole(role, account);
    }

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

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

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

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

// File: @openzeppelin/contracts/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/token/ERC20/IERC20.sol


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

pragma solidity ^0.8.0;

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

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

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}

// File: @openzeppelin/contracts/token/ERC20/extensions/IERC20Metadata.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.0;


/**
 * @dev Interface for the optional metadata functions from the ERC20 standard.
 *
 * _Available since v4.1._
 */
interface IERC20Metadata is IERC20 {
    /**
     * @dev Returns the name of the token.
     */
    function name() external view returns (string memory);

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

    /**
     * @dev Returns the decimals places of the token.
     */
    function decimals() external view returns (uint8);
}

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


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

pragma solidity ^0.8.0;




/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 * For a generic mechanism see {ERC20PresetMinterPauser}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.zeppelin.solutions/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 *
 * Finally, the non-standard {decreaseAllowance} and {increaseAllowance}
 * functions have been added to mitigate the well-known issues around setting
 * allowances. See {IERC20-approve}.
 */
contract ERC20 is Context, IERC20, IERC20Metadata {
    mapping(address => uint256) private _balances;

    mapping(address => mapping(address => uint256)) private _allowances;

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * The default value of {decimals} is 18. To select a different value for
     * {decimals} you should overload it.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

    /**
     * @dev Returns the name of the token.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev Returns the symbol of the token, usually a shorter version of the
     * name.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the number of decimals used to get its user representation.
     * For example, if `decimals` equals `2`, a balance of `505` tokens should
     * be displayed to a user as `5.05` (`505 / 10 ** 2`).
     *
     * Tokens usually opt for a value of 18, imitating the relationship between
     * Ether and Wei. This is the value {ERC20} uses, unless this function is
     * overridden;
     *
     * NOTE: This information is only used for _display_ purposes: it in
     * no way affects any of the arithmetic of the contract, including
     * {IERC20-balanceOf} and {IERC20-transfer}.
     */
    function decimals() public view virtual override returns (uint8) {
        return 18;
    }

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

    /**
     * @dev See {IERC20-balanceOf}.
     */
    function balanceOf(address account) public view virtual override returns (uint256) {
        return _balances[account];
    }

    /**
     * @dev See {IERC20-transfer}.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - the caller must have a balance of at least `amount`.
     */
    function transfer(address to, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _transfer(owner, to, amount);
        return true;
    }

    /**
     * @dev See {IERC20-allowance}.
     */
    function allowance(address owner, address spender) public view virtual override returns (uint256) {
        return _allowances[owner][spender];
    }

    /**
     * @dev See {IERC20-approve}.
     *
     * NOTE: If `amount` is the maximum `uint256`, the allowance is not updated on
     * `transferFrom`. This is semantically equivalent to an infinite approval.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function approve(address spender, uint256 amount) public virtual override returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, amount);
        return true;
    }

    /**
     * @dev See {IERC20-transferFrom}.
     *
     * Emits an {Approval} event indicating the updated allowance. This is not
     * required by the EIP. See the note at the beginning of {ERC20}.
     *
     * NOTE: Does not update the allowance if the current allowance
     * is the maximum `uint256`.
     *
     * Requirements:
     *
     * - `from` and `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     * - the caller must have allowance for ``from``'s tokens of at least
     * `amount`.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) public virtual override returns (bool) {
        address spender = _msgSender();
        _spendAllowance(from, spender, amount);
        _transfer(from, to, amount);
        return true;
    }

    /**
     * @dev Atomically increases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     */
    function increaseAllowance(address spender, uint256 addedValue) public virtual returns (bool) {
        address owner = _msgSender();
        _approve(owner, spender, _allowances[owner][spender] + addedValue);
        return true;
    }

    /**
     * @dev Atomically decreases the allowance granted to `spender` by the caller.
     *
     * This is an alternative to {approve} that can be used as a mitigation for
     * problems described in {IERC20-approve}.
     *
     * Emits an {Approval} event indicating the updated allowance.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `spender` must have allowance for the caller of at least
     * `subtractedValue`.
     */
    function decreaseAllowance(address spender, uint256 subtractedValue) public virtual returns (bool) {
        address owner = _msgSender();
        uint256 currentAllowance = _allowances[owner][spender];
        require(currentAllowance >= subtractedValue, "ERC20: decreased allowance below zero");
        unchecked {
            _approve(owner, spender, currentAllowance - subtractedValue);
        }

        return true;
    }

    /**
     * @dev Moves `amount` of tokens from `sender` to `recipient`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `from` must have a balance of at least `amount`.
     */
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC20: transfer from the zero address");
        require(to != address(0), "ERC20: transfer to the zero address");

        _beforeTokenTransfer(from, to, amount);

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

        emit Transfer(from, to, amount);

        _afterTokenTransfer(from, to, amount);
    }

    /** @dev Creates `amount` tokens and assigns them to `account`, increasing
     * the total supply.
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function _mint(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: mint to the zero address");

        _beforeTokenTransfer(address(0), account, amount);

        _totalSupply += amount;
        _balances[account] += amount;
        emit Transfer(address(0), account, amount);

        _afterTokenTransfer(address(0), account, amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, reducing the
     * total supply.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     * - `account` must have at least `amount` tokens.
     */
    function _burn(address account, uint256 amount) internal virtual {
        require(account != address(0), "ERC20: burn from the zero address");

        _beforeTokenTransfer(account, address(0), amount);

        uint256 accountBalance = _balances[account];
        require(accountBalance >= amount, "ERC20: burn amount exceeds balance");
        unchecked {
            _balances[account] = accountBalance - amount;
        }
        _totalSupply -= amount;

        emit Transfer(account, address(0), amount);

        _afterTokenTransfer(account, address(0), amount);
    }

    /**
     * @dev Sets `amount` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     */
    function _approve(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        require(owner != address(0), "ERC20: approve from the zero address");
        require(spender != address(0), "ERC20: approve to the zero address");

        _allowances[owner][spender] = amount;
        emit Approval(owner, spender, amount);
    }

    /**
     * @dev Spend `amount` form the allowance of `owner` toward `spender`.
     *
     * Does not update the allowance amount in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Might emit an {Approval} event.
     */
    function _spendAllowance(
        address owner,
        address spender,
        uint256 amount
    ) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            require(currentAllowance >= amount, "ERC20: insufficient allowance");
            unchecked {
                _approve(owner, spender, currentAllowance - amount);
            }
        }
    }

    /**
     * @dev Hook that is called before any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * will be transferred to `to`.
     * - when `from` is zero, `amount` tokens will be minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens 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 amount
    ) 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, `amount` of ``from``'s tokens
     * has been transferred to `to`.
     * - when `from` is zero, `amount` tokens have been minted for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens have been 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 _afterTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual {}
}

// File: @openzeppelin/contracts/token/ERC20/extensions/ERC20Pausable.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC20/extensions/ERC20Pausable.sol)

pragma solidity ^0.8.0;



/**
 * @dev ERC20 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 ERC20Pausable is ERC20, Pausable {
    /**
     * @dev See {ERC20-_beforeTokenTransfer}.
     *
     * Requirements:
     *
     * - the contract must not be paused.
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, amount);

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

// File: @openzeppelin/contracts/token/ERC20/extensions/ERC20Burnable.sol


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

pragma solidity ^0.8.0;



/**
 * @dev Extension of {ERC20} that allows token holders to destroy both their own
 * tokens and those that they have an allowance for, in a way that can be
 * recognized off-chain (via event analysis).
 */
abstract contract ERC20Burnable is Context, ERC20 {
    /**
     * @dev Destroys `amount` tokens from the caller.
     *
     * See {ERC20-_burn}.
     */
    function burn(uint256 amount) public virtual {
        _burn(_msgSender(), amount);
    }

    /**
     * @dev Destroys `amount` tokens from `account`, deducting from the caller's
     * allowance.
     *
     * See {ERC20-_burn} and {ERC20-allowance}.
     *
     * Requirements:
     *
     * - the caller must have allowance for ``accounts``'s tokens of at least
     * `amount`.
     */
    function burnFrom(address account, uint256 amount) public virtual {
        _spendAllowance(account, _msgSender(), amount);
        _burn(account, amount);
    }
}

// File: @openzeppelin/contracts/token/ERC20/presets/ERC20PresetMinterPauser.sol


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

pragma solidity ^0.8.0;






/**
 * @dev {ERC20} 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
 *
 * 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 ERC20PresetMinterPauser is Context, AccessControlEnumerable, ERC20Burnable, ERC20Pausable {
    bytes32 public constant MINTER_ROLE = keccak256("MINTER_ROLE");
    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");

    /**
     * @dev Grants `DEFAULT_ADMIN_ROLE`, `MINTER_ROLE` and `PAUSER_ROLE` to the
     * account that deploys the contract.
     *
     * See {ERC20-constructor}.
     */
    constructor(string memory name, string memory symbol) ERC20(name, symbol) {
        _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());

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

    /**
     * @dev Creates `amount` new tokens for `to`.
     *
     * See {ERC20-_mint}.
     *
     * Requirements:
     *
     * - the caller must have the `MINTER_ROLE`.
     */
    function mint(address to, uint256 amount) public virtual {
        require(hasRole(MINTER_ROLE, _msgSender()), "ERC20PresetMinterPauser: must have minter role to mint");
        _mint(to, amount);
    }

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

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

    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 amount
    ) internal virtual override(ERC20, ERC20Pausable) {
        super._beforeTokenTransfer(from, to, amount);
    }
}

// File: JBACCOIN.sol

pragma solidity ^0.8.0;



/**
 * @title JBAC Token (The native ecosystem token of Jungle Bay Ape Club)
 * @dev Extends standard ERC20 contract from OpenZeppelin
 */
contract JBACCOIN is ERC20PresetMinterPauser("Jungle Bay Ape Club", "JBAC") {
    /// @notice JBAC tokens claimable per day for each Jungle Bay NFT holder
    uint256 public constant EMISSION_PER_DAY = 33.30000e18; // ~33.3 JBAC

    /// @notice Start timestamp from contract deployment
    uint256 public immutable emissionStart;

    /// @notice End date for JBAC emissions to Jungle Bay NFT holders
    uint256 public immutable emissionEnd;

    /// @dev A record of last claimed timestamp for Jungle Bay NFTs
    mapping(uint256 => uint256) private _lastClaim;

    /// @dev Contract address for Jungle Bay NFT
    address private _nftAddress;

    /// @dev Contract address for Gold Card NFT
    address private _nftGoldAddress;

    /**
     * @notice Construct the JBAC token
     * @param emissionStartTimestamp Timestamp of deployment
     */
    constructor(uint256 emissionStartTimestamp) {
        emissionStart = emissionStartTimestamp;
        emissionEnd = emissionStartTimestamp + (1 days * 365 * 3);
    }

    // External functions

    /**
     * @notice Sets the contract address to jungle bay GOLDCARDs upon deployment
     * @param nftGoldAddress Address of verified jungle bay GOLDCARD contract
     * @dev Only callable once
     */
    function setNFTGoldAddress(address nftGoldAddress) external onlyRole(DEFAULT_ADMIN_ROLE) {
        require(_nftGoldAddress == address(0), "Already set");
        _nftGoldAddress = nftGoldAddress;
    }

    /**
     * @notice Sets the contract address to jungle bay NFTs upon deployment
     * @param nftAddress Address of verified jungle bay NFT contract
     * @dev Only callable once
     */
    function setNFTAddress(address nftAddress) external onlyRole(DEFAULT_ADMIN_ROLE) {
        require(_nftAddress == address(0), "Already set");
        _nftAddress = nftAddress;
    }

    // Public functions

    /**
     * @notice Check last claim timestamp of accumulated JBAC for given Jungle Bay NFT
     * @param tokenIndex Index of Jungle Bay NFT to check
     * @return Last claim timestamp
     */
    function getLastClaim(uint256 tokenIndex) public view returns (uint256) {
        require(tokenIndex <= ERC721Enumerable(_nftAddress).totalSupply(), "NFT at index not been minted");
        require(ERC721Enumerable(_nftAddress).ownerOf(tokenIndex) != address(0), "Owner cannot be 0 address");
        uint256 lastClaimed = uint256(_lastClaim[tokenIndex]) != 0 ? uint256(_lastClaim[tokenIndex]) : emissionStart;
        return lastClaimed;
    }

    /**
     * @notice Check accumulated JBAC tokens for a Jungle Bay NFT
     * @param tokenIndex Index of Jungle Bay NFT to check balance
     * @return Total JBAC accumulated and ready to claim
     */
    function accumulated(uint256 tokenIndex, uint256 multiplier) public view returns (uint256) {
        require(block.timestamp > emissionStart, "Emission has not started yet");

        uint256 lastClaimed = getLastClaim(tokenIndex);
        // Sanity check if last claim was on or after emission end
        if (lastClaimed >= emissionEnd) return 0;

        uint256 accumulationPeriod = block.timestamp < emissionEnd ? block.timestamp : emissionEnd; // Getting the min value of both
        uint256 totalAccumulated = ((accumulationPeriod - lastClaimed) * EMISSION_PER_DAY) / 1 days;

        return totalAccumulated * multiplier / 100;
    }

    /**
     * @notice Check total accumulated JBAC tokens for all Jungle Bay NFTs
     * @param tokenIndices Indexes of NFTs to check balance
     * @return Total JBAC accumulated and ready to claim
     */
    function accumulatedMultiCheck(uint256[] memory tokenIndices, uint256 multiplier) public view returns (uint256) {
        require(block.timestamp > emissionStart, "Emission has not started yet");
        uint256 totalClaimableQty = 0;
        for (uint256 i = 0; i < tokenIndices.length; i++) {
            uint256 tokenIndex = tokenIndices[i];
            // Sanity check for non-minted index
            require(tokenIndex <= ERC721Enumerable(_nftAddress).totalSupply(), "NFT at index not been minted");
            uint256 claimableQty = accumulated(tokenIndex, multiplier);
            totalClaimableQty = totalClaimableQty + claimableQty;
        }
        return totalClaimableQty;
    }

    /**
     * @notice Mint and claim available JBAC for each Jungle Bay NFT
     * @param tokenIndices Indexes of NFTs to claim for
     * @return Total JBAC claimed
     */
    function claim(uint256[] memory tokenIndices, uint256[] memory goldTokens) public returns (uint256) {
        require(block.timestamp > emissionStart, "Emission has not started yet");

        //we need to calculate the multiplier
        uint256 multiplier = 100;
        for (uint256 i = 0; i < goldTokens.length; i++) {
            // Sanity check for non-minted index
            require(goldTokens[i] <= ERC721Enumerable(_nftGoldAddress).totalSupply(), "GoldToken at index not been minted");

            // Duplicate token index check
            for (uint256 j = i + 1; j < goldTokens.length; j++) {
                require(goldTokens[i] != goldTokens[j], "Duplicate goldtoken index");
            }

            uint256 goldIndex = goldTokens[i];

            require(ERC721Enumerable(_nftGoldAddress).ownerOf(goldIndex) == _msgSender(), "Sender is not the owner of goldtoken");
            multiplier = multiplier + 50;
        }

        uint256 totalClaimQty = 0;
        for (uint256 i = 0; i < tokenIndices.length; i++) {
            // Sanity check for non-minted index
            require(tokenIndices[i] <= ERC721Enumerable(_nftAddress).totalSupply(), "NFT at index not been minted");
            // Duplicate token index check
            for (uint256 j = i + 1; j < tokenIndices.length; j++) {
                require(tokenIndices[i] != tokenIndices[j], "Duplicate token index");
            }

            uint256 tokenIndex = tokenIndices[i];
            require(ERC721Enumerable(_nftAddress).ownerOf(tokenIndex) == _msgSender(), "Sender is not the owner of nft");

            uint256 claimQty = accumulated(tokenIndex, multiplier);
            if (claimQty != 0) {
                totalClaimQty = totalClaimQty + claimQty;
                _lastClaim[tokenIndex] = block.timestamp;
            }
        }

        require(totalClaimQty != 0, "No accumulated JBAC");
        _mint(_msgSender(), totalClaimQty);
        return totalClaimQty;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"uint256","name":"emissionStartTimestamp","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"previousAdminRole","type":"bytes32"},{"indexed":true,"internalType":"bytes32","name":"newAdminRole","type":"bytes32"}],"name":"RoleAdminChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleGranted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"bytes32","name":"role","type":"bytes32"},{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"sender","type":"address"}],"name":"RoleRevoked","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"EMISSION_PER_DAY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenIndex","type":"uint256"},{"internalType":"uint256","name":"multiplier","type":"uint256"}],"name":"accumulated","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIndices","type":"uint256[]"},{"internalType":"uint256","name":"multiplier","type":"uint256"}],"name":"accumulatedMultiCheck","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"burnFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIndices","type":"uint256[]"},{"internalType":"uint256[]","name":"goldTokens","type":"uint256[]"}],"name":"claim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"subtractedValue","type":"uint256"}],"name":"decreaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"emissionEnd","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"emissionStart","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenIndex","type":"uint256"}],"name":"getLastClaim","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleAdmin","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"getRoleMember","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"}],"name":"getRoleMemberCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"grantRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"hasRole","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"addedValue","type":"uint256"}],"name":"increaseAllowance","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"nftAddress","type":"address"}],"name":"setNFTAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"nftGoldAddress","type":"address"}],"name":"setNFTGoldAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60c06040523480156200001157600080fd5b50604051620050fd380380620050fd833981810160405281019062000037919062000521565b6040518060400160405280601381526020017f4a756e676c65204261792041706520436c7562000000000000000000000000008152506040518060400160405280600481526020017f4a4241430000000000000000000000000000000000000000000000000000000081525081818160059080519060200190620000bd9291906200045a565b508060069080519060200190620000d69291906200045a565b5050506000600760006101000a81548160ff021916908315150217905550620001186000801b6200010c620001c460201b60201c565b620001cc60201b60201c565b620001597f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a66200014d620001c460201b60201c565b620001cc60201b60201c565b6200019a7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a6200018e620001c460201b60201c565b620001cc60201b60201c565b505080608081815250506305a39a8081620001b6919062000553565b60a08181525050506200066d565b600033905090565b620001de8282620001e260201b60201c565b5050565b620001f982826200022a60201b62001e501760201c565b6200022581600160008581526020019081526020016000206200031b60201b62001f301790919060201c565b505050565b6200023c82826200035360201b60201c565b6200031757600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550620002bc620001c460201b60201c565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b60006200034b836000018373ffffffffffffffffffffffffffffffffffffffff1660001b620003bd60201b60201c565b905092915050565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000620003d183836200043760201b60201c565b6200042c57826000018290806001815401808255809150506001900390600052602060002001600090919091909150558260000180549050836001016000848152602001908152602001600020819055506001905062000431565b600090505b92915050565b600080836001016000848152602001908152602001600020541415905092915050565b8280546200046890620005ba565b90600052602060002090601f0160209004810192826200048c5760008555620004d8565b82601f10620004a757805160ff1916838001178555620004d8565b82800160010185558215620004d8579182015b82811115620004d7578251825591602001919060010190620004ba565b5b509050620004e79190620004eb565b5090565b5b8082111562000506576000816000905550600101620004ec565b5090565b6000815190506200051b8162000653565b92915050565b6000602082840312156200053a57620005396200064e565b5b60006200054a848285016200050a565b91505092915050565b60006200056082620005b0565b91506200056d83620005b0565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115620005a557620005a4620005f0565b5b828201905092915050565b6000819050919050565b60006002820490506001821680620005d357607f821691505b60208210811415620005ea57620005e96200061f565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600080fd5b6200065e81620005b0565b81146200066a57600080fd5b50565b60805160a051614a39620006c460003960008181611030015281816110630152818161108a015261155f01526000818161089d01528181610fc1015281816113c3015281816118470152611bae0152614a396000f3fe608060405234801561001057600080fd5b50600436106102275760003560e01c806369d0373811610130578063a217fddf116100b8578063d252f6481161007c578063d252f648146106b2578063d5391393146106e2578063d547741f14610700578063dd62ed3e1461071c578063e63ab1e91461074c57610227565b8063a217fddf146105e8578063a457c2d714610606578063a9059cbb14610636578063c033ab7314610666578063ca15c8731461068257610227565b80638456cb59116100ff5780638456cb59146105305780639010d07c1461053a57806391716d051461056a57806391d148541461059a57806395d89b41146105ca57610227565b806369d03738146104aa57806370a08231146104c657806379cc6790146104f65780638368909c1461051257610227565b8063313ce567116101b357806340c10f191161018257806340c10f191461041857806342966c6814610434578063513da948146104505780635c975abb1461046e5780636397f7a21461048c57610227565b8063313ce567146103a457806336568abe146103c257806339509351146103de5780633f4ba83a1461040e57610227565b806318160ddd116101fa57806318160ddd146102da5780631ef42789146102f857806323b872dd14610328578063248a9ca3146103585780632f2ff15d1461038857610227565b806301ffc9a71461022c57806306fdde031461025c578063095ea7b31461027a5780631397e91c146102aa575b600080fd5b61024660048036038101906102419190613446565b61076a565b6040516102539190613a31565b60405180910390f35b6102646107e4565b6040516102719190613a67565b60405180910390f35b610294600480360381019061028f9190613285565b610876565b6040516102a19190613a31565b60405180910390f35b6102c460048036038101906102bf91906132c5565b610899565b6040516102d19190613e09565b60405180910390f35b6102e2610fb3565b6040516102ef9190613e09565b60405180910390f35b610312600480360381019061030d91906134cd565b610fbd565b60405161031f9190613e09565b60405180910390f35b610342600480360381019061033d9190613232565b611108565b60405161034f9190613a31565b60405180910390f35b610372600480360381019061036d9190613399565b611137565b60405161037f9190613a4c565b60405180910390f35b6103a2600480360381019061039d91906133c6565b611156565b005b6103ac61117f565b6040516103b99190613e24565b60405180910390f35b6103dc60048036038101906103d791906133c6565b611188565b005b6103f860048036038101906103f39190613285565b61120b565b6040516104059190613a31565b60405180910390f35b6104166112b5565b005b610432600480360381019061042d9190613285565b61132f565b005b61044e60048036038101906104499190613473565b6113ad565b005b6104586113c1565b6040516104659190613e09565b60405180910390f35b6104766113e5565b6040516104839190613a31565b60405180910390f35b6104946113fc565b6040516104a19190613e09565b60405180910390f35b6104c460048036038101906104bf9190613198565b611409565b005b6104e060048036038101906104db9190613198565b6114f4565b6040516104ed9190613e09565b60405180910390f35b610510600480360381019061050b9190613285565b61153d565b005b61051a61155d565b6040516105279190613e09565b60405180910390f35b610538611581565b005b610554600480360381019061054f9190613406565b6115fb565b6040516105619190613a16565b60405180910390f35b610584600480360381019061057f9190613473565b61162a565b6040516105919190613e09565b60405180910390f35b6105b460048036038101906105af91906133c6565b61188b565b6040516105c19190613a31565b60405180910390f35b6105d26118f5565b6040516105df9190613a67565b60405180910390f35b6105f0611987565b6040516105fd9190613a4c565b60405180910390f35b610620600480360381019061061b9190613285565b61198e565b60405161062d9190613a31565b60405180910390f35b610650600480360381019061064b9190613285565b611a78565b60405161065d9190613a31565b60405180910390f35b610680600480360381019061067b9190613198565b611a9b565b005b61069c60048036038101906106979190613399565b611b86565b6040516106a99190613e09565b60405180910390f35b6106cc60048036038101906106c7919061333d565b611baa565b6040516106d99190613e09565b60405180910390f35b6106ea611d58565b6040516106f79190613a4c565b60405180910390f35b61071a600480360381019061071591906133c6565b611d7c565b005b610736600480360381019061073191906131f2565b611da5565b6040516107439190613e09565b60405180910390f35b610754611e2c565b6040516107619190613a4c565b60405180910390f35b60007f5a05180f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806107dd57506107dc82611f60565b5b9050919050565b6060600580546107f3906140b4565b80601f016020809104026020016040519081016040528092919081815260200182805461081f906140b4565b801561086c5780601f106108415761010080835404028352916020019161086c565b820191906000526020600020905b81548152906001019060200180831161084f57829003601f168201915b5050505050905090565b600080610881611fda565b905061088e818585611fe2565b600191505092915050565b60007f000000000000000000000000000000000000000000000000000000000000000042116108fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108f490613d09565b60405180910390fd5b60006064905060005b8351811015610c1257600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561097757600080fd5b505afa15801561098b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109af91906134a0565b8482815181106109c2576109c161421c565b5b60200260200101511115610a0b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a0290613bc9565b60405180910390fd5b6000600182610a1a9190613eb7565b90505b8451811015610ab057848181518110610a3957610a3861421c565b5b6020026020010151858381518110610a5457610a5361421c565b5b60200260200101511415610a9d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9490613c49565b60405180910390fd5b8080610aa890614117565b915050610a1d565b506000848281518110610ac657610ac561421c565b5b60200260200101519050610ad8611fda565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610b499190613e09565b60206040518083038186803b158015610b6157600080fd5b505afa158015610b75573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9991906131c5565b73ffffffffffffffffffffffffffffffffffffffff1614610bef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610be690613a89565b60405180910390fd5b603283610bfc9190613eb7565b9250508080610c0a90614117565b915050610906565b506000805b8551811015610f5257600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610c8857600080fd5b505afa158015610c9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc091906134a0565b868281518110610cd357610cd261421c565b5b60200260200101511115610d1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d1390613c29565b60405180910390fd5b6000600182610d2b9190613eb7565b90505b8651811015610dc157868181518110610d4a57610d4961421c565b5b6020026020010151878381518110610d6557610d6461421c565b5b60200260200101511415610dae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610da590613ca9565b60405180910390fd5b8080610db990614117565b915050610d2e565b506000868281518110610dd757610dd661421c565b5b60200260200101519050610de9611fda565b73ffffffffffffffffffffffffffffffffffffffff16600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610e5a9190613e09565b60206040518083038186803b158015610e7257600080fd5b505afa158015610e86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eaa91906131c5565b73ffffffffffffffffffffffffffffffffffffffff1614610f00576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ef790613c09565b60405180910390fd5b6000610f0c8286610fbd565b905060008114610f3d578084610f229190613eb7565b93504260086000848152602001908152602001600020819055505b50508080610f4a90614117565b915050610c17565b506000811415610f97576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8e90613b09565b60405180910390fd5b610fa8610fa2611fda565b826121ad565b809250505092915050565b6000600454905090565b60007f00000000000000000000000000000000000000000000000000000000000000004211611021576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161101890613d09565b60405180910390fd5b600061102c8461162a565b90507f0000000000000000000000000000000000000000000000000000000000000000811061105f576000915050611102565b60007f000000000000000000000000000000000000000000000000000000000000000042106110ae577f00000000000000000000000000000000000000000000000000000000000000006110b0565b425b90506000620151806801ce215d91ac82000084846110ce9190613f98565b6110d89190613f3e565b6110e29190613f0d565b9050606485826110f29190613f3e565b6110fc9190613f0d565b93505050505b92915050565b600080611113611fda565b905061112085828561230e565b61112b85858561239a565b60019150509392505050565b6000806000838152602001908152602001600020600101549050919050565b61115f82611137565b6111708161116b611fda565b61261e565b61117a83836126bb565b505050565b60006012905090565b611190611fda565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146111fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111f490613da9565b60405180910390fd5b61120782826126ef565b5050565b600080611216611fda565b90506112aa818585600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546112a59190613eb7565b611fe2565b600191505092915050565b6112e67f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a6112e1611fda565b61188b565b611325576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161131c90613b49565b60405180910390fd5b61132d612723565b565b6113607f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a661135b611fda565b61188b565b61139f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139690613cc9565b60405180910390fd5b6113a982826121ad565b5050565b6113be6113b8611fda565b826127c5565b50565b7f000000000000000000000000000000000000000000000000000000000000000081565b6000600760009054906101000a900460ff16905090565b6801ce215d91ac82000081565b6000801b61141e81611419611fda565b61261e565b600073ffffffffffffffffffffffffffffffffffffffff16600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146114af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a690613c69565b60405180910390fd5b81600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b61154f82611549611fda565b8361230e565b61155982826127c5565b5050565b7f000000000000000000000000000000000000000000000000000000000000000081565b6115b27f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a6115ad611fda565b61188b565b6115f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115e890613d69565b60405180910390fd5b6115f961299e565b565b60006116228260016000868152602001908152602001600020612a4190919063ffffffff16565b905092915050565b6000600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561169457600080fd5b505afa1580156116a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116cc91906134a0565b82111561170e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161170590613c29565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e846040518263ffffffff1660e01b81526004016117819190613e09565b60206040518083038186803b15801561179957600080fd5b505afa1580156117ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117d191906131c5565b73ffffffffffffffffffffffffffffffffffffffff161415611828576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161181f90613c89565b60405180910390fd5b6000806008600085815260200190815260200160002054141561186b577f0000000000000000000000000000000000000000000000000000000000000000611880565b60086000848152602001908152602001600020545b905080915050919050565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060068054611904906140b4565b80601f0160208091040260200160405190810160405280929190818152602001828054611930906140b4565b801561197d5780601f106119525761010080835404028352916020019161197d565b820191906000526020600020905b81548152906001019060200180831161196057829003601f168201915b5050505050905090565b6000801b81565b600080611999611fda565b90506000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905083811015611a5f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a5690613d89565b60405180910390fd5b611a6c8286868403611fe2565b60019250505092915050565b600080611a83611fda565b9050611a9081858561239a565b600191505092915050565b6000801b611ab081611aab611fda565b61261e565b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611b41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3890613c69565b60405180910390fd5b81600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000611ba360016000848152602001908152602001600020612a5b565b9050919050565b60007f00000000000000000000000000000000000000000000000000000000000000004211611c0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c0590613d09565b60405180910390fd5b6000805b8451811015611d4d576000858281518110611c3057611c2f61421c565b5b60200260200101519050600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611ca257600080fd5b505afa158015611cb6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cda91906134a0565b811115611d1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d1390613c29565b60405180910390fd5b6000611d288287610fbd565b90508084611d369190613eb7565b935050508080611d4590614117565b915050611c12565b508091505092915050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b611d8582611137565b611d9681611d91611fda565b61261e565b611da083836126ef565b505050565b6000600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b611e5a828261188b565b611f2c57600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611ed1611fda565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b6000611f58836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612a70565b905092915050565b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611fd35750611fd282612ae0565b5b9050919050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415612052576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161204990613d49565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156120c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120b990613b69565b60405180910390fd5b80600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516121a09190613e09565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561221d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161221490613dc9565b60405180910390fd5b61222960008383612b4a565b806004600082825461223b9190613eb7565b9250508190555080600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546122919190613eb7565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516122f69190613e09565b60405180910390a361230a60008383612b5a565b5050565b600061231a8484611da5565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146123945781811015612386576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161237d90613b89565b60405180910390fd5b6123938484848403611fe2565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561240a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161240190613d29565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561247a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161247190613ac9565b60405180910390fd5b612485838383612b4a565b6000600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181101561250c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161250390613ba9565b60405180910390fd5b818103600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546125a19190613eb7565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516126059190613e09565b60405180910390a3612618848484612b5a565b50505050565b612628828261188b565b6126b75761264d8173ffffffffffffffffffffffffffffffffffffffff166014612b5f565b61265b8360001c6020612b5f565b60405160200161266c9291906139dc565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126ae9190613a67565b60405180910390fd5b5050565b6126c58282611e50565b6126ea8160016000858152602001908152602001600020611f3090919063ffffffff16565b505050565b6126f98282612d9b565b61271e8160016000858152602001908152602001600020612e7c90919063ffffffff16565b505050565b61272b6113e5565b61276a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161276190613ae9565b60405180910390fd5b6000600760006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6127ae611fda565b6040516127bb9190613a16565b60405180910390a1565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612835576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161282c90613ce9565b60405180910390fd5b61284182600083612b4a565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050818110156128c8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128bf90613b29565b60405180910390fd5b818103600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600460008282546129209190613f98565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516129859190613e09565b60405180910390a361299983600084612b5a565b505050565b6129a66113e5565b156129e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129dd90613be9565b60405180910390fd5b6001600760006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258612a2a611fda565b604051612a379190613a16565b60405180910390a1565b6000612a508360000183612eac565b60001c905092915050565b6000612a6982600001612ed7565b9050919050565b6000612a7c8383612ee8565b612ad5578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612ada565b600090505b92915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b612b55838383612f0b565b505050565b505050565b606060006002836002612b729190613f3e565b612b7c9190613eb7565b67ffffffffffffffff811115612b9557612b9461424b565b5b6040519080825280601f01601f191660200182016040528015612bc75781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110612bff57612bfe61421c565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110612c6357612c6261421c565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006001846002612ca39190613f3e565b612cad9190613eb7565b90505b6001811115612d4d577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110612cef57612cee61421c565b5b1a60f81b828281518110612d0657612d0561421c565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c945080612d469061408a565b9050612cb0565b5060008414612d91576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d8890613aa9565b60405180910390fd5b8091505092915050565b612da5828261188b565b15612e7857600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550612e1d611fda565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b6000612ea4836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612f63565b905092915050565b6000826000018281548110612ec457612ec361421c565b5b9060005260206000200154905092915050565b600081600001805490509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b612f16838383613077565b612f1e6113e5565b15612f5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f5590613de9565b60405180910390fd5b505050565b6000808360010160008481526020019081526020016000205490506000811461306b576000600182612f959190613f98565b9050600060018660000180549050612fad9190613f98565b905081811461301c576000866000018281548110612fce57612fcd61421c565b5b9060005260206000200154905080876000018481548110612ff257612ff161421c565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b856000018054806130305761302f6141ed565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050613071565b60009150505b92915050565b505050565b600061308f61308a84613e64565b613e3f565b905080838252602082019050828560208602820111156130b2576130b161427f565b5b60005b858110156130e257816130c8888261316e565b8452602084019350602083019250506001810190506130b5565b5050509392505050565b6000813590506130fb816149a7565b92915050565b600081519050613110816149a7565b92915050565b600082601f83011261312b5761312a61427a565b5b813561313b84826020860161307c565b91505092915050565b600081359050613153816149be565b92915050565b600081359050613168816149d5565b92915050565b60008135905061317d816149ec565b92915050565b600081519050613192816149ec565b92915050565b6000602082840312156131ae576131ad614289565b5b60006131bc848285016130ec565b91505092915050565b6000602082840312156131db576131da614289565b5b60006131e984828501613101565b91505092915050565b6000806040838503121561320957613208614289565b5b6000613217858286016130ec565b9250506020613228858286016130ec565b9150509250929050565b60008060006060848603121561324b5761324a614289565b5b6000613259868287016130ec565b935050602061326a868287016130ec565b925050604061327b8682870161316e565b9150509250925092565b6000806040838503121561329c5761329b614289565b5b60006132aa858286016130ec565b92505060206132bb8582860161316e565b9150509250929050565b600080604083850312156132dc576132db614289565b5b600083013567ffffffffffffffff8111156132fa576132f9614284565b5b61330685828601613116565b925050602083013567ffffffffffffffff81111561332757613326614284565b5b61333385828601613116565b9150509250929050565b6000806040838503121561335457613353614289565b5b600083013567ffffffffffffffff81111561337257613371614284565b5b61337e85828601613116565b925050602061338f8582860161316e565b9150509250929050565b6000602082840312156133af576133ae614289565b5b60006133bd84828501613144565b91505092915050565b600080604083850312156133dd576133dc614289565b5b60006133eb85828601613144565b92505060206133fc858286016130ec565b9150509250929050565b6000806040838503121561341d5761341c614289565b5b600061342b85828601613144565b925050602061343c8582860161316e565b9150509250929050565b60006020828403121561345c5761345b614289565b5b600061346a84828501613159565b91505092915050565b60006020828403121561348957613488614289565b5b60006134978482850161316e565b91505092915050565b6000602082840312156134b6576134b5614289565b5b60006134c484828501613183565b91505092915050565b600080604083850312156134e4576134e3614289565b5b60006134f28582860161316e565b92505060206135038582860161316e565b9150509250929050565b61351681613fcc565b82525050565b61352581613fde565b82525050565b61353481613fea565b82525050565b600061354582613e90565b61354f8185613e9b565b935061355f818560208601614057565b6135688161428e565b840191505092915050565b600061357e82613e90565b6135888185613eac565b9350613598818560208601614057565b80840191505092915050565b60006135b1602483613e9b565b91506135bc8261429f565b604082019050919050565b60006135d4602083613e9b565b91506135df826142ee565b602082019050919050565b60006135f7602383613e9b565b915061360282614317565b604082019050919050565b600061361a601483613e9b565b915061362582614366565b602082019050919050565b600061363d601383613e9b565b91506136488261438f565b602082019050919050565b6000613660602283613e9b565b915061366b826143b8565b604082019050919050565b6000613683603983613e9b565b915061368e82614407565b604082019050919050565b60006136a6602283613e9b565b91506136b182614456565b604082019050919050565b60006136c9601d83613e9b565b91506136d4826144a5565b602082019050919050565b60006136ec602683613e9b565b91506136f7826144ce565b604082019050919050565b600061370f602283613e9b565b915061371a8261451d565b604082019050919050565b6000613732601083613e9b565b915061373d8261456c565b602082019050919050565b6000613755601e83613e9b565b915061376082614595565b602082019050919050565b6000613778601c83613e9b565b9150613783826145be565b602082019050919050565b600061379b601983613e9b565b91506137a6826145e7565b602082019050919050565b60006137be600b83613e9b565b91506137c982614610565b602082019050919050565b60006137e1601983613e9b565b91506137ec82614639565b602082019050919050565b6000613804601583613e9b565b915061380f82614662565b602082019050919050565b6000613827603683613e9b565b91506138328261468b565b604082019050919050565b600061384a602183613e9b565b9150613855826146da565b604082019050919050565b600061386d601c83613e9b565b915061387882614729565b602082019050919050565b6000613890602583613e9b565b915061389b82614752565b604082019050919050565b60006138b3602483613e9b565b91506138be826147a1565b604082019050919050565b60006138d6603783613e9b565b91506138e1826147f0565b604082019050919050565b60006138f9601783613eac565b91506139048261483f565b601782019050919050565b600061391c602583613e9b565b915061392782614868565b604082019050919050565b600061393f601183613eac565b915061394a826148b7565b601182019050919050565b6000613962602f83613e9b565b915061396d826148e0565b604082019050919050565b6000613985601f83613e9b565b91506139908261492f565b602082019050919050565b60006139a8602a83613e9b565b91506139b382614958565b604082019050919050565b6139c781614040565b82525050565b6139d68161404a565b82525050565b60006139e7826138ec565b91506139f38285613573565b91506139fe82613932565b9150613a0a8284613573565b91508190509392505050565b6000602082019050613a2b600083018461350d565b92915050565b6000602082019050613a46600083018461351c565b92915050565b6000602082019050613a61600083018461352b565b92915050565b60006020820190508181036000830152613a81818461353a565b905092915050565b60006020820190508181036000830152613aa2816135a4565b9050919050565b60006020820190508181036000830152613ac2816135c7565b9050919050565b60006020820190508181036000830152613ae2816135ea565b9050919050565b60006020820190508181036000830152613b028161360d565b9050919050565b60006020820190508181036000830152613b2281613630565b9050919050565b60006020820190508181036000830152613b4281613653565b9050919050565b60006020820190508181036000830152613b6281613676565b9050919050565b60006020820190508181036000830152613b8281613699565b9050919050565b60006020820190508181036000830152613ba2816136bc565b9050919050565b60006020820190508181036000830152613bc2816136df565b9050919050565b60006020820190508181036000830152613be281613702565b9050919050565b60006020820190508181036000830152613c0281613725565b9050919050565b60006020820190508181036000830152613c2281613748565b9050919050565b60006020820190508181036000830152613c428161376b565b9050919050565b60006020820190508181036000830152613c628161378e565b9050919050565b60006020820190508181036000830152613c82816137b1565b9050919050565b60006020820190508181036000830152613ca2816137d4565b9050919050565b60006020820190508181036000830152613cc2816137f7565b9050919050565b60006020820190508181036000830152613ce28161381a565b9050919050565b60006020820190508181036000830152613d028161383d565b9050919050565b60006020820190508181036000830152613d2281613860565b9050919050565b60006020820190508181036000830152613d4281613883565b9050919050565b60006020820190508181036000830152613d62816138a6565b9050919050565b60006020820190508181036000830152613d82816138c9565b9050919050565b60006020820190508181036000830152613da28161390f565b9050919050565b60006020820190508181036000830152613dc281613955565b9050919050565b60006020820190508181036000830152613de281613978565b9050919050565b60006020820190508181036000830152613e028161399b565b9050919050565b6000602082019050613e1e60008301846139be565b92915050565b6000602082019050613e3960008301846139cd565b92915050565b6000613e49613e5a565b9050613e5582826140e6565b919050565b6000604051905090565b600067ffffffffffffffff821115613e7f57613e7e61424b565b5b602082029050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b6000613ec282614040565b9150613ecd83614040565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613f0257613f01614160565b5b828201905092915050565b6000613f1882614040565b9150613f2383614040565b925082613f3357613f3261418f565b5b828204905092915050565b6000613f4982614040565b9150613f5483614040565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613f8d57613f8c614160565b5b828202905092915050565b6000613fa382614040565b9150613fae83614040565b925082821015613fc157613fc0614160565b5b828203905092915050565b6000613fd782614020565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60005b8381101561407557808201518184015260208101905061405a565b83811115614084576000848401525b50505050565b600061409582614040565b915060008214156140a9576140a8614160565b5b600182039050919050565b600060028204905060018216806140cc57607f821691505b602082108114156140e0576140df6141be565b5b50919050565b6140ef8261428e565b810181811067ffffffffffffffff8211171561410e5761410d61424b565b5b80604052505050565b600061412282614040565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561415557614154614160565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f53656e646572206973206e6f7420746865206f776e6572206f6620676f6c647460008201527f6f6b656e00000000000000000000000000000000000000000000000000000000602082015250565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b7f4e6f20616363756d756c61746564204a42414300000000000000000000000000600082015250565b7f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60008201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b7f45524332305072657365744d696e7465725061757365723a206d75737420686160008201527f76652070617573657220726f6c6520746f20756e706175736500000000000000602082015250565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000600082015250565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b7f476f6c64546f6b656e20617420696e646578206e6f74206265656e206d696e7460008201527f6564000000000000000000000000000000000000000000000000000000000000602082015250565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b7f53656e646572206973206e6f7420746865206f776e6572206f66206e66740000600082015250565b7f4e465420617420696e646578206e6f74206265656e206d696e74656400000000600082015250565b7f4475706c696361746520676f6c64746f6b656e20696e64657800000000000000600082015250565b7f416c726561647920736574000000000000000000000000000000000000000000600082015250565b7f4f776e65722063616e6e6f742062652030206164647265737300000000000000600082015250565b7f4475706c696361746520746f6b656e20696e6465780000000000000000000000600082015250565b7f45524332305072657365744d696e7465725061757365723a206d75737420686160008201527f7665206d696e74657220726f6c6520746f206d696e7400000000000000000000602082015250565b7f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b7f456d697373696f6e20686173206e6f7420737461727465642079657400000000600082015250565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f45524332305072657365744d696e7465725061757365723a206d75737420686160008201527f76652070617573657220726f6c6520746f207061757365000000000000000000602082015250565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b7f45524332305061757361626c653a20746f6b656e207472616e7366657220776860008201527f696c652070617573656400000000000000000000000000000000000000000000602082015250565b6149b081613fcc565b81146149bb57600080fd5b50565b6149c781613fea565b81146149d257600080fd5b50565b6149de81613ff4565b81146149e957600080fd5b50565b6149f581614040565b8114614a0057600080fd5b5056fea26469706673582212204fa7b9a38bbac0da91979aeacb2779ce46fcaee6808687a8736274201e56336c64736f6c634300080700330000000000000000000000000000000000000000000000000000000061f2cf90

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102275760003560e01c806369d0373811610130578063a217fddf116100b8578063d252f6481161007c578063d252f648146106b2578063d5391393146106e2578063d547741f14610700578063dd62ed3e1461071c578063e63ab1e91461074c57610227565b8063a217fddf146105e8578063a457c2d714610606578063a9059cbb14610636578063c033ab7314610666578063ca15c8731461068257610227565b80638456cb59116100ff5780638456cb59146105305780639010d07c1461053a57806391716d051461056a57806391d148541461059a57806395d89b41146105ca57610227565b806369d03738146104aa57806370a08231146104c657806379cc6790146104f65780638368909c1461051257610227565b8063313ce567116101b357806340c10f191161018257806340c10f191461041857806342966c6814610434578063513da948146104505780635c975abb1461046e5780636397f7a21461048c57610227565b8063313ce567146103a457806336568abe146103c257806339509351146103de5780633f4ba83a1461040e57610227565b806318160ddd116101fa57806318160ddd146102da5780631ef42789146102f857806323b872dd14610328578063248a9ca3146103585780632f2ff15d1461038857610227565b806301ffc9a71461022c57806306fdde031461025c578063095ea7b31461027a5780631397e91c146102aa575b600080fd5b61024660048036038101906102419190613446565b61076a565b6040516102539190613a31565b60405180910390f35b6102646107e4565b6040516102719190613a67565b60405180910390f35b610294600480360381019061028f9190613285565b610876565b6040516102a19190613a31565b60405180910390f35b6102c460048036038101906102bf91906132c5565b610899565b6040516102d19190613e09565b60405180910390f35b6102e2610fb3565b6040516102ef9190613e09565b60405180910390f35b610312600480360381019061030d91906134cd565b610fbd565b60405161031f9190613e09565b60405180910390f35b610342600480360381019061033d9190613232565b611108565b60405161034f9190613a31565b60405180910390f35b610372600480360381019061036d9190613399565b611137565b60405161037f9190613a4c565b60405180910390f35b6103a2600480360381019061039d91906133c6565b611156565b005b6103ac61117f565b6040516103b99190613e24565b60405180910390f35b6103dc60048036038101906103d791906133c6565b611188565b005b6103f860048036038101906103f39190613285565b61120b565b6040516104059190613a31565b60405180910390f35b6104166112b5565b005b610432600480360381019061042d9190613285565b61132f565b005b61044e60048036038101906104499190613473565b6113ad565b005b6104586113c1565b6040516104659190613e09565b60405180910390f35b6104766113e5565b6040516104839190613a31565b60405180910390f35b6104946113fc565b6040516104a19190613e09565b60405180910390f35b6104c460048036038101906104bf9190613198565b611409565b005b6104e060048036038101906104db9190613198565b6114f4565b6040516104ed9190613e09565b60405180910390f35b610510600480360381019061050b9190613285565b61153d565b005b61051a61155d565b6040516105279190613e09565b60405180910390f35b610538611581565b005b610554600480360381019061054f9190613406565b6115fb565b6040516105619190613a16565b60405180910390f35b610584600480360381019061057f9190613473565b61162a565b6040516105919190613e09565b60405180910390f35b6105b460048036038101906105af91906133c6565b61188b565b6040516105c19190613a31565b60405180910390f35b6105d26118f5565b6040516105df9190613a67565b60405180910390f35b6105f0611987565b6040516105fd9190613a4c565b60405180910390f35b610620600480360381019061061b9190613285565b61198e565b60405161062d9190613a31565b60405180910390f35b610650600480360381019061064b9190613285565b611a78565b60405161065d9190613a31565b60405180910390f35b610680600480360381019061067b9190613198565b611a9b565b005b61069c60048036038101906106979190613399565b611b86565b6040516106a99190613e09565b60405180910390f35b6106cc60048036038101906106c7919061333d565b611baa565b6040516106d99190613e09565b60405180910390f35b6106ea611d58565b6040516106f79190613a4c565b60405180910390f35b61071a600480360381019061071591906133c6565b611d7c565b005b610736600480360381019061073191906131f2565b611da5565b6040516107439190613e09565b60405180910390f35b610754611e2c565b6040516107619190613a4c565b60405180910390f35b60007f5a05180f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806107dd57506107dc82611f60565b5b9050919050565b6060600580546107f3906140b4565b80601f016020809104026020016040519081016040528092919081815260200182805461081f906140b4565b801561086c5780601f106108415761010080835404028352916020019161086c565b820191906000526020600020905b81548152906001019060200180831161084f57829003601f168201915b5050505050905090565b600080610881611fda565b905061088e818585611fe2565b600191505092915050565b60007f0000000000000000000000000000000000000000000000000000000061f2cf9042116108fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108f490613d09565b60405180910390fd5b60006064905060005b8351811015610c1257600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561097757600080fd5b505afa15801561098b573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906109af91906134a0565b8482815181106109c2576109c161421c565b5b60200260200101511115610a0b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a0290613bc9565b60405180910390fd5b6000600182610a1a9190613eb7565b90505b8451811015610ab057848181518110610a3957610a3861421c565b5b6020026020010151858381518110610a5457610a5361421c565b5b60200260200101511415610a9d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a9490613c49565b60405180910390fd5b8080610aa890614117565b915050610a1d565b506000848281518110610ac657610ac561421c565b5b60200260200101519050610ad8611fda565b73ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610b499190613e09565b60206040518083038186803b158015610b6157600080fd5b505afa158015610b75573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610b9991906131c5565b73ffffffffffffffffffffffffffffffffffffffff1614610bef576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610be690613a89565b60405180910390fd5b603283610bfc9190613eb7565b9250508080610c0a90614117565b915050610906565b506000805b8551811015610f5257600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015610c8857600080fd5b505afa158015610c9c573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610cc091906134a0565b868281518110610cd357610cd261421c565b5b60200260200101511115610d1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d1390613c29565b60405180910390fd5b6000600182610d2b9190613eb7565b90505b8651811015610dc157868181518110610d4a57610d4961421c565b5b6020026020010151878381518110610d6557610d6461421c565b5b60200260200101511415610dae576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610da590613ca9565b60405180910390fd5b8080610db990614117565b915050610d2e565b506000868281518110610dd757610dd661421c565b5b60200260200101519050610de9611fda565b73ffffffffffffffffffffffffffffffffffffffff16600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e836040518263ffffffff1660e01b8152600401610e5a9190613e09565b60206040518083038186803b158015610e7257600080fd5b505afa158015610e86573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610eaa91906131c5565b73ffffffffffffffffffffffffffffffffffffffff1614610f00576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ef790613c09565b60405180910390fd5b6000610f0c8286610fbd565b905060008114610f3d578084610f229190613eb7565b93504260086000848152602001908152602001600020819055505b50508080610f4a90614117565b915050610c17565b506000811415610f97576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f8e90613b09565b60405180910390fd5b610fa8610fa2611fda565b826121ad565b809250505092915050565b6000600454905090565b60007f0000000000000000000000000000000000000000000000000000000061f2cf904211611021576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161101890613d09565b60405180910390fd5b600061102c8461162a565b90507f0000000000000000000000000000000000000000000000000000000067966a10811061105f576000915050611102565b60007f0000000000000000000000000000000000000000000000000000000067966a1042106110ae577f0000000000000000000000000000000000000000000000000000000067966a106110b0565b425b90506000620151806801ce215d91ac82000084846110ce9190613f98565b6110d89190613f3e565b6110e29190613f0d565b9050606485826110f29190613f3e565b6110fc9190613f0d565b93505050505b92915050565b600080611113611fda565b905061112085828561230e565b61112b85858561239a565b60019150509392505050565b6000806000838152602001908152602001600020600101549050919050565b61115f82611137565b6111708161116b611fda565b61261e565b61117a83836126bb565b505050565b60006012905090565b611190611fda565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146111fd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111f490613da9565b60405180910390fd5b61120782826126ef565b5050565b600080611216611fda565b90506112aa818585600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020546112a59190613eb7565b611fe2565b600191505092915050565b6112e67f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a6112e1611fda565b61188b565b611325576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161131c90613b49565b60405180910390fd5b61132d612723565b565b6113607f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a661135b611fda565b61188b565b61139f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161139690613cc9565b60405180910390fd5b6113a982826121ad565b5050565b6113be6113b8611fda565b826127c5565b50565b7f0000000000000000000000000000000000000000000000000000000061f2cf9081565b6000600760009054906101000a900460ff16905090565b6801ce215d91ac82000081565b6000801b61141e81611419611fda565b61261e565b600073ffffffffffffffffffffffffffffffffffffffff16600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16146114af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114a690613c69565b60405180910390fd5b81600960006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000600260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b61154f82611549611fda565b8361230e565b61155982826127c5565b5050565b7f0000000000000000000000000000000000000000000000000000000067966a1081565b6115b27f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a6115ad611fda565b61188b565b6115f1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115e890613d69565b60405180910390fd5b6115f961299e565b565b60006116228260016000868152602001908152602001600020612a4190919063ffffffff16565b905092915050565b6000600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b15801561169457600080fd5b505afa1580156116a8573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116cc91906134a0565b82111561170e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161170590613c29565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16636352211e846040518263ffffffff1660e01b81526004016117819190613e09565b60206040518083038186803b15801561179957600080fd5b505afa1580156117ad573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117d191906131c5565b73ffffffffffffffffffffffffffffffffffffffff161415611828576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161181f90613c89565b60405180910390fd5b6000806008600085815260200190815260200160002054141561186b577f0000000000000000000000000000000000000000000000000000000061f2cf90611880565b60086000848152602001908152602001600020545b905080915050919050565b600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b606060068054611904906140b4565b80601f0160208091040260200160405190810160405280929190818152602001828054611930906140b4565b801561197d5780601f106119525761010080835404028352916020019161197d565b820191906000526020600020905b81548152906001019060200180831161196057829003601f168201915b5050505050905090565b6000801b81565b600080611999611fda565b90506000600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905083811015611a5f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a5690613d89565b60405180910390fd5b611a6c8286868403611fe2565b60019250505092915050565b600080611a83611fda565b9050611a9081858561239a565b600191505092915050565b6000801b611ab081611aab611fda565b61261e565b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614611b41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b3890613c69565b60405180910390fd5b81600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055505050565b6000611ba360016000848152602001908152602001600020612a5b565b9050919050565b60007f0000000000000000000000000000000000000000000000000000000061f2cf904211611c0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c0590613d09565b60405180910390fd5b6000805b8451811015611d4d576000858281518110611c3057611c2f61421c565b5b60200260200101519050600960009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166318160ddd6040518163ffffffff1660e01b815260040160206040518083038186803b158015611ca257600080fd5b505afa158015611cb6573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611cda91906134a0565b811115611d1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d1390613c29565b60405180910390fd5b6000611d288287610fbd565b90508084611d369190613eb7565b935050508080611d4590614117565b915050611c12565b508091505092915050565b7f9f2df0fed2c77648de5860a4cc508cd0818c85b8b8a1ab4ceeef8d981c8956a681565b611d8582611137565b611d9681611d91611fda565b61261e565b611da083836126ef565b505050565b6000600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b611e5a828261188b565b611f2c57600160008084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550611ed1611fda565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45b5050565b6000611f58836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612a70565b905092915050565b60007f7965db0b000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611fd35750611fd282612ae0565b5b9050919050565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415612052576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161204990613d49565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156120c2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120b990613b69565b60405180910390fd5b80600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b925836040516121a09190613e09565b60405180910390a3505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561221d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161221490613dc9565b60405180910390fd5b61222960008383612b4a565b806004600082825461223b9190613eb7565b9250508190555080600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546122919190613eb7565b925050819055508173ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516122f69190613e09565b60405180910390a361230a60008383612b5a565b5050565b600061231a8484611da5565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff81146123945781811015612386576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161237d90613b89565b60405180910390fd5b6123938484848403611fe2565b5b50505050565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561240a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161240190613d29565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561247a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161247190613ac9565b60405180910390fd5b612485838383612b4a565b6000600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000205490508181101561250c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161250390613ba9565b60405180910390fd5b818103600260008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546125a19190613eb7565b925050819055508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516126059190613e09565b60405180910390a3612618848484612b5a565b50505050565b612628828261188b565b6126b75761264d8173ffffffffffffffffffffffffffffffffffffffff166014612b5f565b61265b8360001c6020612b5f565b60405160200161266c9291906139dc565b6040516020818303038152906040526040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126ae9190613a67565b60405180910390fd5b5050565b6126c58282611e50565b6126ea8160016000858152602001908152602001600020611f3090919063ffffffff16565b505050565b6126f98282612d9b565b61271e8160016000858152602001908152602001600020612e7c90919063ffffffff16565b505050565b61272b6113e5565b61276a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161276190613ae9565b60405180910390fd5b6000600760006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa6127ae611fda565b6040516127bb9190613a16565b60405180910390a1565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612835576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161282c90613ce9565b60405180910390fd5b61284182600083612b4a565b6000600260008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050818110156128c8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128bf90613b29565b60405180910390fd5b818103600260008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081600460008282546129209190613f98565b92505081905550600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef846040516129859190613e09565b60405180910390a361299983600084612b5a565b505050565b6129a66113e5565b156129e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129dd90613be9565b60405180910390fd5b6001600760006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258612a2a611fda565b604051612a379190613a16565b60405180910390a1565b6000612a508360000183612eac565b60001c905092915050565b6000612a6982600001612ed7565b9050919050565b6000612a7c8383612ee8565b612ad5578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612ada565b600090505b92915050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b612b55838383612f0b565b505050565b505050565b606060006002836002612b729190613f3e565b612b7c9190613eb7565b67ffffffffffffffff811115612b9557612b9461424b565b5b6040519080825280601f01601f191660200182016040528015612bc75781602001600182028036833780820191505090505b5090507f300000000000000000000000000000000000000000000000000000000000000081600081518110612bff57612bfe61421c565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f780000000000000000000000000000000000000000000000000000000000000081600181518110612c6357612c6261421c565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006001846002612ca39190613f3e565b612cad9190613eb7565b90505b6001811115612d4d577f3031323334353637383961626364656600000000000000000000000000000000600f861660108110612cef57612cee61421c565b5b1a60f81b828281518110612d0657612d0561421c565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600485901c945080612d469061408a565b9050612cb0565b5060008414612d91576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d8890613aa9565b60405180910390fd5b8091505092915050565b612da5828261188b565b15612e7857600080600084815260200190815260200160002060000160008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff021916908315150217905550612e1d611fda565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b60405160405180910390a45b5050565b6000612ea4836000018373ffffffffffffffffffffffffffffffffffffffff1660001b612f63565b905092915050565b6000826000018281548110612ec457612ec361421c565b5b9060005260206000200154905092915050565b600081600001805490509050919050565b600080836001016000848152602001908152602001600020541415905092915050565b612f16838383613077565b612f1e6113e5565b15612f5e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612f5590613de9565b60405180910390fd5b505050565b6000808360010160008481526020019081526020016000205490506000811461306b576000600182612f959190613f98565b9050600060018660000180549050612fad9190613f98565b905081811461301c576000866000018281548110612fce57612fcd61421c565b5b9060005260206000200154905080876000018481548110612ff257612ff161421c565b5b90600052602060002001819055508387600101600083815260200190815260200160002081905550505b856000018054806130305761302f6141ed565b5b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050613071565b60009150505b92915050565b505050565b600061308f61308a84613e64565b613e3f565b905080838252602082019050828560208602820111156130b2576130b161427f565b5b60005b858110156130e257816130c8888261316e565b8452602084019350602083019250506001810190506130b5565b5050509392505050565b6000813590506130fb816149a7565b92915050565b600081519050613110816149a7565b92915050565b600082601f83011261312b5761312a61427a565b5b813561313b84826020860161307c565b91505092915050565b600081359050613153816149be565b92915050565b600081359050613168816149d5565b92915050565b60008135905061317d816149ec565b92915050565b600081519050613192816149ec565b92915050565b6000602082840312156131ae576131ad614289565b5b60006131bc848285016130ec565b91505092915050565b6000602082840312156131db576131da614289565b5b60006131e984828501613101565b91505092915050565b6000806040838503121561320957613208614289565b5b6000613217858286016130ec565b9250506020613228858286016130ec565b9150509250929050565b60008060006060848603121561324b5761324a614289565b5b6000613259868287016130ec565b935050602061326a868287016130ec565b925050604061327b8682870161316e565b9150509250925092565b6000806040838503121561329c5761329b614289565b5b60006132aa858286016130ec565b92505060206132bb8582860161316e565b9150509250929050565b600080604083850312156132dc576132db614289565b5b600083013567ffffffffffffffff8111156132fa576132f9614284565b5b61330685828601613116565b925050602083013567ffffffffffffffff81111561332757613326614284565b5b61333385828601613116565b9150509250929050565b6000806040838503121561335457613353614289565b5b600083013567ffffffffffffffff81111561337257613371614284565b5b61337e85828601613116565b925050602061338f8582860161316e565b9150509250929050565b6000602082840312156133af576133ae614289565b5b60006133bd84828501613144565b91505092915050565b600080604083850312156133dd576133dc614289565b5b60006133eb85828601613144565b92505060206133fc858286016130ec565b9150509250929050565b6000806040838503121561341d5761341c614289565b5b600061342b85828601613144565b925050602061343c8582860161316e565b9150509250929050565b60006020828403121561345c5761345b614289565b5b600061346a84828501613159565b91505092915050565b60006020828403121561348957613488614289565b5b60006134978482850161316e565b91505092915050565b6000602082840312156134b6576134b5614289565b5b60006134c484828501613183565b91505092915050565b600080604083850312156134e4576134e3614289565b5b60006134f28582860161316e565b92505060206135038582860161316e565b9150509250929050565b61351681613fcc565b82525050565b61352581613fde565b82525050565b61353481613fea565b82525050565b600061354582613e90565b61354f8185613e9b565b935061355f818560208601614057565b6135688161428e565b840191505092915050565b600061357e82613e90565b6135888185613eac565b9350613598818560208601614057565b80840191505092915050565b60006135b1602483613e9b565b91506135bc8261429f565b604082019050919050565b60006135d4602083613e9b565b91506135df826142ee565b602082019050919050565b60006135f7602383613e9b565b915061360282614317565b604082019050919050565b600061361a601483613e9b565b915061362582614366565b602082019050919050565b600061363d601383613e9b565b91506136488261438f565b602082019050919050565b6000613660602283613e9b565b915061366b826143b8565b604082019050919050565b6000613683603983613e9b565b915061368e82614407565b604082019050919050565b60006136a6602283613e9b565b91506136b182614456565b604082019050919050565b60006136c9601d83613e9b565b91506136d4826144a5565b602082019050919050565b60006136ec602683613e9b565b91506136f7826144ce565b604082019050919050565b600061370f602283613e9b565b915061371a8261451d565b604082019050919050565b6000613732601083613e9b565b915061373d8261456c565b602082019050919050565b6000613755601e83613e9b565b915061376082614595565b602082019050919050565b6000613778601c83613e9b565b9150613783826145be565b602082019050919050565b600061379b601983613e9b565b91506137a6826145e7565b602082019050919050565b60006137be600b83613e9b565b91506137c982614610565b602082019050919050565b60006137e1601983613e9b565b91506137ec82614639565b602082019050919050565b6000613804601583613e9b565b915061380f82614662565b602082019050919050565b6000613827603683613e9b565b91506138328261468b565b604082019050919050565b600061384a602183613e9b565b9150613855826146da565b604082019050919050565b600061386d601c83613e9b565b915061387882614729565b602082019050919050565b6000613890602583613e9b565b915061389b82614752565b604082019050919050565b60006138b3602483613e9b565b91506138be826147a1565b604082019050919050565b60006138d6603783613e9b565b91506138e1826147f0565b604082019050919050565b60006138f9601783613eac565b91506139048261483f565b601782019050919050565b600061391c602583613e9b565b915061392782614868565b604082019050919050565b600061393f601183613eac565b915061394a826148b7565b601182019050919050565b6000613962602f83613e9b565b915061396d826148e0565b604082019050919050565b6000613985601f83613e9b565b91506139908261492f565b602082019050919050565b60006139a8602a83613e9b565b91506139b382614958565b604082019050919050565b6139c781614040565b82525050565b6139d68161404a565b82525050565b60006139e7826138ec565b91506139f38285613573565b91506139fe82613932565b9150613a0a8284613573565b91508190509392505050565b6000602082019050613a2b600083018461350d565b92915050565b6000602082019050613a46600083018461351c565b92915050565b6000602082019050613a61600083018461352b565b92915050565b60006020820190508181036000830152613a81818461353a565b905092915050565b60006020820190508181036000830152613aa2816135a4565b9050919050565b60006020820190508181036000830152613ac2816135c7565b9050919050565b60006020820190508181036000830152613ae2816135ea565b9050919050565b60006020820190508181036000830152613b028161360d565b9050919050565b60006020820190508181036000830152613b2281613630565b9050919050565b60006020820190508181036000830152613b4281613653565b9050919050565b60006020820190508181036000830152613b6281613676565b9050919050565b60006020820190508181036000830152613b8281613699565b9050919050565b60006020820190508181036000830152613ba2816136bc565b9050919050565b60006020820190508181036000830152613bc2816136df565b9050919050565b60006020820190508181036000830152613be281613702565b9050919050565b60006020820190508181036000830152613c0281613725565b9050919050565b60006020820190508181036000830152613c2281613748565b9050919050565b60006020820190508181036000830152613c428161376b565b9050919050565b60006020820190508181036000830152613c628161378e565b9050919050565b60006020820190508181036000830152613c82816137b1565b9050919050565b60006020820190508181036000830152613ca2816137d4565b9050919050565b60006020820190508181036000830152613cc2816137f7565b9050919050565b60006020820190508181036000830152613ce28161381a565b9050919050565b60006020820190508181036000830152613d028161383d565b9050919050565b60006020820190508181036000830152613d2281613860565b9050919050565b60006020820190508181036000830152613d4281613883565b9050919050565b60006020820190508181036000830152613d62816138a6565b9050919050565b60006020820190508181036000830152613d82816138c9565b9050919050565b60006020820190508181036000830152613da28161390f565b9050919050565b60006020820190508181036000830152613dc281613955565b9050919050565b60006020820190508181036000830152613de281613978565b9050919050565b60006020820190508181036000830152613e028161399b565b9050919050565b6000602082019050613e1e60008301846139be565b92915050565b6000602082019050613e3960008301846139cd565b92915050565b6000613e49613e5a565b9050613e5582826140e6565b919050565b6000604051905090565b600067ffffffffffffffff821115613e7f57613e7e61424b565b5b602082029050602081019050919050565b600081519050919050565b600082825260208201905092915050565b600081905092915050565b6000613ec282614040565b9150613ecd83614040565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613f0257613f01614160565b5b828201905092915050565b6000613f1882614040565b9150613f2383614040565b925082613f3357613f3261418f565b5b828204905092915050565b6000613f4982614040565b9150613f5483614040565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615613f8d57613f8c614160565b5b828202905092915050565b6000613fa382614040565b9150613fae83614040565b925082821015613fc157613fc0614160565b5b828203905092915050565b6000613fd782614020565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b60005b8381101561407557808201518184015260208101905061405a565b83811115614084576000848401525b50505050565b600061409582614040565b915060008214156140a9576140a8614160565b5b600182039050919050565b600060028204905060018216806140cc57607f821691505b602082108114156140e0576140df6141be565b5b50919050565b6140ef8261428e565b810181811067ffffffffffffffff8211171561410e5761410d61424b565b5b80604052505050565b600061412282614040565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82141561415557614154614160565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b7f53656e646572206973206e6f7420746865206f776e6572206f6620676f6c647460008201527f6f6b656e00000000000000000000000000000000000000000000000000000000602082015250565b7f537472696e67733a20686578206c656e67746820696e73756666696369656e74600082015250565b7f45524332303a207472616e7366657220746f20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b7f4e6f20616363756d756c61746564204a42414300000000000000000000000000600082015250565b7f45524332303a206275726e20616d6f756e7420657863656564732062616c616e60008201527f6365000000000000000000000000000000000000000000000000000000000000602082015250565b7f45524332305072657365744d696e7465725061757365723a206d75737420686160008201527f76652070617573657220726f6c6520746f20756e706175736500000000000000602082015250565b7f45524332303a20617070726f766520746f20746865207a65726f20616464726560008201527f7373000000000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a20696e73756666696369656e7420616c6c6f77616e6365000000600082015250565b7f45524332303a207472616e7366657220616d6f756e742065786365656473206260008201527f616c616e63650000000000000000000000000000000000000000000000000000602082015250565b7f476f6c64546f6b656e20617420696e646578206e6f74206265656e206d696e7460008201527f6564000000000000000000000000000000000000000000000000000000000000602082015250565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b7f53656e646572206973206e6f7420746865206f776e6572206f66206e66740000600082015250565b7f4e465420617420696e646578206e6f74206265656e206d696e74656400000000600082015250565b7f4475706c696361746520676f6c64746f6b656e20696e64657800000000000000600082015250565b7f416c726561647920736574000000000000000000000000000000000000000000600082015250565b7f4f776e65722063616e6e6f742062652030206164647265737300000000000000600082015250565b7f4475706c696361746520746f6b656e20696e6465780000000000000000000000600082015250565b7f45524332305072657365744d696e7465725061757365723a206d75737420686160008201527f7665206d696e74657220726f6c6520746f206d696e7400000000000000000000602082015250565b7f45524332303a206275726e2066726f6d20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b7f456d697373696f6e20686173206e6f7420737461727465642079657400000000600082015250565b7f45524332303a207472616e736665722066726f6d20746865207a65726f20616460008201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b7f45524332303a20617070726f76652066726f6d20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f45524332305072657365744d696e7465725061757365723a206d75737420686160008201527f76652070617573657220726f6c6520746f207061757365000000000000000000602082015250565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000600082015250565b7f45524332303a2064656372656173656420616c6c6f77616e63652062656c6f7760008201527f207a65726f000000000000000000000000000000000000000000000000000000602082015250565b7f206973206d697373696e6720726f6c6520000000000000000000000000000000600082015250565b7f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560008201527f20726f6c657320666f722073656c660000000000000000000000000000000000602082015250565b7f45524332303a206d696e7420746f20746865207a65726f206164647265737300600082015250565b7f45524332305061757361626c653a20746f6b656e207472616e7366657220776860008201527f696c652070617573656400000000000000000000000000000000000000000000602082015250565b6149b081613fcc565b81146149bb57600080fd5b50565b6149c781613fea565b81146149d257600080fd5b50565b6149de81613ff4565b81146149e957600080fd5b50565b6149f581614040565b8114614a0057600080fd5b5056fea26469706673582212204fa7b9a38bbac0da91979aeacb2779ce46fcaee6808687a8736274201e56336c64736f6c63430008070033

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

0000000000000000000000000000000000000000000000000000000061f2cf90

-----Decoded View---------------
Arg [0] : emissionStartTimestamp (uint256): 1643302800

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000061f2cf90


Deployed Bytecode Sourcemap

93952:6571:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67975:214;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;77872:100;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80223:201;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;98511:2009;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;78992:108;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96745:653;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;81004:295;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;63838:131;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64231:147;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;78834:93;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;65279:218;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;81708:240;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;93343:178;;;:::i;:::-;;92534:205;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;90199:91;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;94248:38;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70926:86;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;94113:54;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95657:184;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;79163:127;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;90609:164;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;94366:36;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;92953:172;;;:::i;:::-;;68788:153;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;96078:449;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;62707:147;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;78091:104;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;61798:49;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;82451:438;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;79496:193;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95248:204;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;69115:142;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;97619:704;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91776:62;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64623:149;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;79752:151;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;91845:62;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67975:214;68060:4;68099:42;68084:57;;;:11;:57;;;;:97;;;;68145:36;68169:11;68145:23;:36::i;:::-;68084:97;68077:104;;67975:214;;;:::o;77872:100::-;77926:13;77959:5;77952:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77872:100;:::o;80223:201::-;80306:4;80323:13;80339:12;:10;:12::i;:::-;80323:28;;80362:32;80371:5;80378:7;80387:6;80362:8;:32::i;:::-;80412:4;80405:11;;;80223:201;;;;:::o;98511:2009::-;98602:7;98648:13;98630:15;:31;98622:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;98754:18;98775:3;98754:24;;98794:9;98789:678;98813:10;:17;98809:1;:21;98789:678;;;98944:15;;;;;;;;;;;98927:45;;;:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;98910:10;98921:1;98910:13;;;;;;;;:::i;:::-;;;;;;;;:64;;98902:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;99079:9;99095:1;99091;:5;;;;:::i;:::-;99079:17;;99074:155;99102:10;:17;99098:1;:21;99074:155;;;99170:10;99181:1;99170:13;;;;;;;;:::i;:::-;;;;;;;;99153:10;99164:1;99153:13;;;;;;;;:::i;:::-;;;;;;;;:30;;99145:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;99121:3;;;;;:::i;:::-;;;;99074:155;;;;99245:17;99265:10;99276:1;99265:13;;;;;;;;:::i;:::-;;;;;;;;99245:33;;99359:12;:10;:12::i;:::-;99303:68;;99320:15;;;;;;;;;;;99303:41;;;99345:9;99303:52;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:68;;;99295:117;;;;;;;;;;;;:::i;:::-;;;;;;;;;99453:2;99440:10;:15;;;;:::i;:::-;99427:28;;98837:630;98832:3;;;;;:::i;:::-;;;;98789:678;;;;99479:21;99520:9;99515:859;99539:12;:19;99535:1;:23;99515:859;;;99674:11;;;;;;;;;;;99657:41;;;:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;99638:12;99651:1;99638:15;;;;;;;;:::i;:::-;;;;;;;;:62;;99630:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;99797:9;99813:1;99809;:5;;;;:::i;:::-;99797:17;;99792:157;99820:12;:19;99816:1;:23;99792:157;;;99892:12;99905:1;99892:15;;;;;;;;:::i;:::-;;;;;;;;99873:12;99886:1;99873:15;;;;;;;;:::i;:::-;;;;;;;;:34;;99865:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;99841:3;;;;;:::i;:::-;;;;99792:157;;;;99965:18;99986:12;99999:1;99986:15;;;;;;;;:::i;:::-;;;;;;;;99965:36;;100077:12;:10;:12::i;:::-;100024:65;;100041:11;;;;;;;;;;;100024:37;;;100062:10;100024:49;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:65;;;100016:108;;;;;;;;;;;;:::i;:::-;;;;;;;;;100141:16;100160:35;100172:10;100184;100160:11;:35::i;:::-;100141:54;;100226:1;100214:8;:13;100210:153;;100280:8;100264:13;:24;;;;:::i;:::-;100248:40;;100332:15;100307:10;:22;100318:10;100307:22;;;;;;;;;;;:40;;;;100210:153;99565:809;;99560:3;;;;;:::i;:::-;;;;99515:859;;;;100411:1;100394:13;:18;;100386:50;;;;;;;;;;;;:::i;:::-;;;;;;;;;100447:34;100453:12;:10;:12::i;:::-;100467:13;100447:5;:34::i;:::-;100499:13;100492:20;;;;98511:2009;;;;:::o;78992:108::-;79053:7;79080:12;;79073:19;;78992:108;:::o;96745:653::-;96827:7;96873:13;96855:15;:31;96847:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;96932:19;96954:24;96967:10;96954:12;:24::i;:::-;96932:46;;97076:11;97061;:26;97057:40;;97096:1;97089:8;;;;;97057:40;97110:26;97157:11;97139:15;:29;:61;;97189:11;97139:61;;;97171:15;97139:61;97110:90;;97244:24;97329:6;94156:11;97294;97273:18;:32;;;;:::i;:::-;97272:53;;;;:::i;:::-;97271:64;;;;:::i;:::-;97244:91;;97387:3;97374:10;97355:16;:29;;;;:::i;:::-;:35;;;;:::i;:::-;97348:42;;;;;96745:653;;;;;:::o;81004:295::-;81135:4;81152:15;81170:12;:10;:12::i;:::-;81152:30;;81193:38;81209:4;81215:7;81224:6;81193:15;:38::i;:::-;81242:27;81252:4;81258:2;81262:6;81242:9;:27::i;:::-;81287:4;81280:11;;;81004:295;;;;;:::o;63838:131::-;63912:7;63939:6;:12;63946:4;63939:12;;;;;;;;;;;:22;;;63932:29;;63838:131;;;:::o;64231:147::-;64314:18;64327:4;64314:12;:18::i;:::-;62289:30;62300:4;62306:12;:10;:12::i;:::-;62289:10;:30::i;:::-;64345:25:::1;64356:4;64362:7;64345:10;:25::i;:::-;64231:147:::0;;;:::o;78834:93::-;78892:5;78917:2;78910:9;;78834:93;:::o;65279:218::-;65386:12;:10;:12::i;:::-;65375:23;;:7;:23;;;65367:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;65463:26;65475:4;65481:7;65463:11;:26::i;:::-;65279:218;;:::o;81708:240::-;81796:4;81813:13;81829:12;:10;:12::i;:::-;81813:28;;81852:66;81861:5;81868:7;81907:10;81877:11;:18;81889:5;81877:18;;;;;;;;;;;;;;;:27;81896:7;81877:27;;;;;;;;;;;;;;;;:40;;;;:::i;:::-;81852:8;:66::i;:::-;81936:4;81929:11;;;81708:240;;;;:::o;93343:178::-;93396:34;91883:24;93417:12;:10;:12::i;:::-;93396:7;:34::i;:::-;93388:104;;;;;;;;;;;;:::i;:::-;;;;;;;;;93503:10;:8;:10::i;:::-;93343:178::o;92534:205::-;92610:34;91814:24;92631:12;:10;:12::i;:::-;92610:7;:34::i;:::-;92602:101;;;;;;;;;;;;:::i;:::-;;;;;;;;;92714:17;92720:2;92724:6;92714:5;:17::i;:::-;92534:205;;:::o;90199:91::-;90255:27;90261:12;:10;:12::i;:::-;90275:6;90255:5;:27::i;:::-;90199:91;:::o;94248:38::-;;;:::o;70926:86::-;70973:4;70997:7;;;;;;;;;;;70990:14;;70926:86;:::o;94113:54::-;94156:11;94113:54;:::o;95657:184::-;61843:4;95718:18;;62289:30;62300:4;62306:12;:10;:12::i;:::-;62289:10;:30::i;:::-;95780:1:::1;95757:25;;:11;;;;;;;;;;;:25;;;95749:49;;;;;;;;;;;;:::i;:::-;;;;;;;;;95823:10;95809:11;;:24;;;;;;;;;;;;;;;;;;95657:184:::0;;:::o;79163:127::-;79237:7;79264:9;:18;79274:7;79264:18;;;;;;;;;;;;;;;;79257:25;;79163:127;;;:::o;90609:164::-;90686:46;90702:7;90711:12;:10;:12::i;:::-;90725:6;90686:15;:46::i;:::-;90743:22;90749:7;90758:6;90743:5;:22::i;:::-;90609:164;;:::o;94366:36::-;;;:::o;92953:172::-;93004:34;91883:24;93025:12;:10;:12::i;:::-;93004:7;:34::i;:::-;92996:102;;;;;;;;;;;;:::i;:::-;;;;;;;;;93109:8;:6;:8::i;:::-;92953:172::o;68788:153::-;68878:7;68905:28;68927:5;68905:12;:18;68918:4;68905:18;;;;;;;;;;;:21;;:28;;;;:::i;:::-;68898:35;;68788:153;;;;:::o;96078:449::-;96141:7;96200:11;;;;;;;;;;;96183:41;;;:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;96169:10;:57;;96161:98;;;;;;;;;;;;:::i;:::-;;;;;;;;;96339:1;96278:63;;96295:11;;;;;;;;;;;96278:37;;;96316:10;96278:49;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:63;;;;96270:101;;;;;;;;;;;;:::i;:::-;;;;;;;;;96382:19;96439:1;96412:10;:22;96423:10;96412:22;;;;;;;;;;;;96404:36;;:86;;96477:13;96404:86;;;96451:10;:22;96462:10;96451:22;;;;;;;;;;;;96404:86;96382:108;;96508:11;96501:18;;;96078:449;;;:::o;62707:147::-;62793:4;62817:6;:12;62824:4;62817:12;;;;;;;;;;;:20;;:29;62838:7;62817:29;;;;;;;;;;;;;;;;;;;;;;;;;62810:36;;62707:147;;;;:::o;78091:104::-;78147:13;78180:7;78173:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;78091:104;:::o;61798:49::-;61843:4;61798:49;;;:::o;82451:438::-;82544:4;82561:13;82577:12;:10;:12::i;:::-;82561:28;;82600:24;82627:11;:18;82639:5;82627:18;;;;;;;;;;;;;;;:27;82646:7;82627:27;;;;;;;;;;;;;;;;82600:54;;82693:15;82673:16;:35;;82665:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;82786:60;82795:5;82802:7;82830:15;82811:16;:34;82786:8;:60::i;:::-;82877:4;82870:11;;;;82451:438;;;;:::o;79496:193::-;79575:4;79592:13;79608:12;:10;:12::i;:::-;79592:28;;79631;79641:5;79648:2;79652:6;79631:9;:28::i;:::-;79677:4;79670:11;;;79496:193;;;;:::o;95248:204::-;61843:4;95317:18;;62289:30;62300:4;62306:12;:10;:12::i;:::-;62289:10;:30::i;:::-;95383:1:::1;95356:29;;:15;;;;;;;;;;;:29;;;95348:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;95430:14;95412:15;;:32;;;;;;;;;;;;;;;;;;95248:204:::0;;:::o;69115:142::-;69195:7;69222:27;:12;:18;69235:4;69222:18;;;;;;;;;;;:25;:27::i;:::-;69215:34;;69115:142;;;:::o;97619:704::-;97722:7;97768:13;97750:15;:31;97742:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;97825:25;97870:9;97865:416;97889:12;:19;97885:1;:23;97865:416;;;97930:18;97951:12;97964:1;97951:15;;;;;;;;:::i;:::-;;;;;;;;97930:36;;98070:11;;;;;;;;;;;98053:41;;;:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;98039:10;:57;;98031:98;;;;;;;;;;;;:::i;:::-;;;;;;;;;98144:20;98167:35;98179:10;98191;98167:11;:35::i;:::-;98144:58;;98257:12;98237:17;:32;;;;:::i;:::-;98217:52;;97915:366;;97910:3;;;;;:::i;:::-;;;;97865:416;;;;98298:17;98291:24;;;97619:704;;;;:::o;91776:62::-;91814:24;91776:62;:::o;64623:149::-;64707:18;64720:4;64707:12;:18::i;:::-;62289:30;62300:4;62306:12;:10;:12::i;:::-;62289:10;:30::i;:::-;64738:26:::1;64750:4;64756:7;64738:11;:26::i;:::-;64623:149:::0;;;:::o;79752:151::-;79841:7;79868:11;:18;79880:5;79868:18;;;;;;;;;;;;;;;:27;79887:7;79868:27;;;;;;;;;;;;;;;;79861:34;;79752:151;;;;:::o;91845:62::-;91883:24;91845:62;:::o;66780:238::-;66864:22;66872:4;66878:7;66864;:22::i;:::-;66859:152;;66935:4;66903:6;:12;66910:4;66903:12;;;;;;;;;;;:20;;:29;66924:7;66903:29;;;;;;;;;;;;;;;;:36;;;;;;;;;;;;;;;;;;66986:12;:10;:12::i;:::-;66959:40;;66977:7;66959:40;;66971:4;66959:40;;;;;;;;;;66859:152;66780:238;;:::o;17406:152::-;17476:4;17500:50;17505:3;:10;;17541:5;17525:23;;17517:32;;17500:4;:50::i;:::-;17493:57;;17406:152;;;;:::o;62411:204::-;62496:4;62535:32;62520:47;;;:11;:47;;;;:87;;;;62571:36;62595:11;62571:23;:36::i;:::-;62520:87;62513:94;;62411:204;;;:::o;37926:98::-;37979:7;38006:10;37999:17;;37926:98;:::o;86087:380::-;86240:1;86223:19;;:5;:19;;;;86215:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;86321:1;86302:21;;:7;:21;;;;86294:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;86405:6;86375:11;:18;86387:5;86375:18;;;;;;;;;;;;;;;:27;86394:7;86375:27;;;;;;;;;;;;;;;:36;;;;86443:7;86427:32;;86436:5;86427:32;;;86452:6;86427:32;;;;;;:::i;:::-;;;;;;;;86087:380;;;:::o;84326:399::-;84429:1;84410:21;;:7;:21;;;;84402:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;84480:49;84509:1;84513:7;84522:6;84480:20;:49::i;:::-;84558:6;84542:12;;:22;;;;;;;:::i;:::-;;;;;;;;84597:6;84575:9;:18;84585:7;84575:18;;;;;;;;;;;;;;;;:28;;;;;;;:::i;:::-;;;;;;;;84640:7;84619:37;;84636:1;84619:37;;;84649:6;84619:37;;;;;;:::i;:::-;;;;;;;;84669:48;84697:1;84701:7;84710:6;84669:19;:48::i;:::-;84326:399;;:::o;86754:453::-;86889:24;86916:25;86926:5;86933:7;86916:9;:25::i;:::-;86889:52;;86976:17;86956:16;:37;86952:248;;87038:6;87018:16;:26;;87010:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;87122:51;87131:5;87138:7;87166:6;87147:16;:25;87122:8;:51::i;:::-;86952:248;86878:329;86754:453;;;:::o;83368:671::-;83515:1;83499:18;;:4;:18;;;;83491:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;83592:1;83578:16;;:2;:16;;;;83570:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;83647:38;83668:4;83674:2;83678:6;83647:20;:38::i;:::-;83698:19;83720:9;:15;83730:4;83720:15;;;;;;;;;;;;;;;;83698:37;;83769:6;83754:11;:21;;83746:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;83886:6;83872:11;:20;83854:9;:15;83864:4;83854:15;;;;;;;;;;;;;;;:38;;;;83931:6;83914:9;:13;83924:2;83914:13;;;;;;;;;;;;;;;;:23;;;;;;;:::i;:::-;;;;;;;;83970:2;83955:26;;83964:4;83955:26;;;83974:6;83955:26;;;;;;:::i;:::-;;;;;;;;83994:37;84014:4;84020:2;84024:6;83994:19;:37::i;:::-;83480:559;83368:671;;;:::o;63144:505::-;63233:22;63241:4;63247:7;63233;:22::i;:::-;63228:414;;63421:41;63449:7;63421:41;;63459:2;63421:19;:41::i;:::-;63535:38;63563:4;63555:13;;63570:2;63535:19;:38::i;:::-;63326:270;;;;;;;;;:::i;:::-;;;;;;;;;;;;;63272:358;;;;;;;;;;;:::i;:::-;;;;;;;;63228:414;63144:505;;:::o;69350:169::-;69438:31;69455:4;69461:7;69438:16;:31::i;:::-;69480;69503:7;69480:12;:18;69493:4;69480:18;;;;;;;;;;;:22;;:31;;;;:::i;:::-;;69350:169;;:::o;69613:174::-;69702:32;69720:4;69726:7;69702:17;:32::i;:::-;69745:34;69771:7;69745:12;:18;69758:4;69745:18;;;;;;;;;;;:25;;:34;;;;:::i;:::-;;69613:174;;:::o;71985:120::-;71529:8;:6;:8::i;:::-;71521:41;;;;;;;;;;;;:::i;:::-;;;;;;;;;72054:5:::1;72044:7;;:15;;;;;;;;;;;;;;;;;;72075:22;72084:12;:10;:12::i;:::-;72075:22;;;;;;:::i;:::-;;;;;;;;71985:120::o:0;85058:591::-;85161:1;85142:21;;:7;:21;;;;85134:67;;;;;;;;;;;;:::i;:::-;;;;;;;;;85214:49;85235:7;85252:1;85256:6;85214:20;:49::i;:::-;85276:22;85301:9;:18;85311:7;85301:18;;;;;;;;;;;;;;;;85276:43;;85356:6;85338:14;:24;;85330:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;85475:6;85458:14;:23;85437:9;:18;85447:7;85437:18;;;;;;;;;;;;;;;:44;;;;85519:6;85503:12;;:22;;;;;;;:::i;:::-;;;;;;;;85569:1;85543:37;;85552:7;85543:37;;;85573:6;85543:37;;;;;;:::i;:::-;;;;;;;;85593:48;85613:7;85630:1;85634:6;85593:19;:48::i;:::-;85123:526;85058:591;;:::o;71726:118::-;71252:8;:6;:8::i;:::-;71251:9;71243:38;;;;;;;;;;;;:::i;:::-;;;;;;;;;71796:4:::1;71786:7;;:14;;;;;;;;;;;;;;;;;;71816:20;71823:12;:10;:12::i;:::-;71816:20;;;;;;:::i;:::-;;;;;;;;71726:118::o:0;18702:158::-;18776:7;18827:22;18831:3;:10;;18843:5;18827:3;:22::i;:::-;18819:31;;18796:56;;18702:158;;;;:::o;18231:117::-;18294:7;18321:19;18329:3;:10;;18321:7;:19::i;:::-;18314:26;;18231:117;;;:::o;11321:414::-;11384:4;11406:21;11416:3;11421:5;11406:9;:21::i;:::-;11401:327;;11444:3;:11;;11461:5;11444:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11627:3;:11;;:18;;;;11605:3;:12;;:19;11618:5;11605:19;;;;;;;;;;;:40;;;;11667:4;11660:11;;;;11401:327;11711:5;11704:12;;11321:414;;;;;:::o;30648:157::-;30733:4;30772:25;30757:40;;;:11;:40;;;;30750:47;;30648:157;;;:::o;93529:217::-;93694:44;93721:4;93727:2;93731:6;93694:26;:44::i;:::-;93529:217;;;:::o;88536:124::-;;;;:::o;32478:451::-;32553:13;32579:19;32624:1;32615:6;32611:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;32601:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32579:47;;32637:15;:6;32644:1;32637:9;;;;;;;;:::i;:::-;;;;;:15;;;;;;;;;;;32663;:6;32670:1;32663:9;;;;;;;;:::i;:::-;;;;;:15;;;;;;;;;;;32694:9;32719:1;32710:6;32706:1;:10;;;;:::i;:::-;:14;;;;:::i;:::-;32694:26;;32689:135;32726:1;32722;:5;32689:135;;;32761:12;32782:3;32774:5;:11;32761:25;;;;;;;:::i;:::-;;;;;32749:6;32756:1;32749:9;;;;;;;;:::i;:::-;;;;;:37;;;;;;;;;;;32811:1;32801:11;;;;;32729:3;;;;:::i;:::-;;;32689:135;;;;32851:1;32842:5;:10;32834:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;32914:6;32900:21;;;32478:451;;;;:::o;67150:239::-;67234:22;67242:4;67248:7;67234;:22::i;:::-;67230:152;;;67305:5;67273:6;:12;67280:4;67273:12;;;;;;;;;;;:20;;:29;67294:7;67273:29;;;;;;;;;;;;;;;;:37;;;;;;;;;;;;;;;;;;67357:12;:10;:12::i;:::-;67330:40;;67348:7;67330:40;;67342:4;67330:40;;;;;;;;;;67230:152;67150:239;;:::o;17734:158::-;17807:4;17831:53;17839:3;:10;;17875:5;17859:23;;17851:32;;17831:7;:53::i;:::-;17824:60;;17734:158;;;;:::o;14095:120::-;14162:7;14189:3;:11;;14201:5;14189:18;;;;;;;;:::i;:::-;;;;;;;;;;14182:25;;14095:120;;;;:::o;13632:109::-;13688:7;13715:3;:11;;:18;;;;13708:25;;13632:109;;;:::o;13417:129::-;13490:4;13537:1;13514:3;:12;;:19;13527:5;13514:19;;;;;;;;;;;;:24;;13507:31;;13417:129;;;;:::o;89337:272::-;89480:44;89507:4;89513:2;89517:6;89480:26;:44::i;:::-;89546:8;:6;:8::i;:::-;89545:9;89537:64;;;;;;;;;;;;:::i;:::-;;;;;;;;;89337:272;;;:::o;11911:1420::-;11977:4;12095:18;12116:3;:12;;:19;12129:5;12116:19;;;;;;;;;;;;12095:40;;12166:1;12152:10;:15;12148:1176;;12527:21;12564:1;12551:10;:14;;;;:::i;:::-;12527:38;;12580:17;12621:1;12600:3;:11;;:18;;;;:22;;;;:::i;:::-;12580:42;;12656:13;12643:9;:26;12639:405;;12690:17;12710:3;:11;;12722:9;12710:22;;;;;;;;:::i;:::-;;;;;;;;;;12690:42;;12864:9;12835:3;:11;;12847:13;12835:26;;;;;;;;:::i;:::-;;;;;;;;;:38;;;;12975:10;12949:3;:12;;:23;12962:9;12949:23;;;;;;;;;;;:36;;;;12671:373;12639:405;13125:3;:11;;:17;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;13220:3;:12;;:19;13233:5;13220:19;;;;;;;;;;;13213:26;;;13263:4;13256:11;;;;;;;12148:1176;13307:5;13300:12;;;11911:1420;;;;;:::o;87807:125::-;;;;:::o;24:722:1:-;120:5;145:81;161:64;218:6;161:64;:::i;:::-;145:81;:::i;:::-;136:90;;246:5;275:6;268:5;261:21;309:4;302:5;298:16;291:23;;335:6;385:3;377:4;369:6;365:17;360:3;356:27;353:36;350:143;;;404:79;;:::i;:::-;350:143;517:1;502:238;527:6;524:1;521:13;502:238;;;595:3;624:37;657:3;645:10;624:37;:::i;:::-;619:3;612:50;691:4;686:3;682:14;675:21;;725:4;720:3;716:14;709:21;;562:178;549:1;546;542:9;537:14;;502:238;;;506:14;126:620;;24:722;;;;;:::o;752:139::-;798:5;836:6;823:20;814:29;;852:33;879:5;852:33;:::i;:::-;752:139;;;;:::o;897:143::-;954:5;985:6;979:13;970:22;;1001:33;1028:5;1001:33;:::i;:::-;897:143;;;;:::o;1063:370::-;1134:5;1183:3;1176:4;1168:6;1164:17;1160:27;1150:122;;1191:79;;:::i;:::-;1150:122;1308:6;1295:20;1333:94;1423:3;1415:6;1408:4;1400:6;1396:17;1333:94;:::i;:::-;1324:103;;1140:293;1063:370;;;;:::o;1439:139::-;1485:5;1523:6;1510:20;1501:29;;1539:33;1566:5;1539:33;:::i;:::-;1439:139;;;;:::o;1584:137::-;1629:5;1667:6;1654:20;1645:29;;1683:32;1709:5;1683:32;:::i;:::-;1584:137;;;;:::o;1727:139::-;1773:5;1811:6;1798:20;1789:29;;1827:33;1854:5;1827:33;:::i;:::-;1727:139;;;;:::o;1872:143::-;1929:5;1960:6;1954:13;1945:22;;1976:33;2003:5;1976:33;:::i;:::-;1872:143;;;;:::o;2021:329::-;2080:6;2129:2;2117:9;2108:7;2104:23;2100:32;2097:119;;;2135:79;;:::i;:::-;2097:119;2255:1;2280:53;2325:7;2316:6;2305:9;2301:22;2280:53;:::i;:::-;2270:63;;2226:117;2021:329;;;;:::o;2356:351::-;2426:6;2475:2;2463:9;2454:7;2450:23;2446:32;2443:119;;;2481:79;;:::i;:::-;2443:119;2601:1;2626:64;2682:7;2673:6;2662:9;2658:22;2626:64;:::i;:::-;2616:74;;2572:128;2356:351;;;;:::o;2713:474::-;2781:6;2789;2838:2;2826:9;2817:7;2813:23;2809:32;2806:119;;;2844:79;;:::i;:::-;2806:119;2964:1;2989:53;3034:7;3025:6;3014:9;3010:22;2989:53;:::i;:::-;2979:63;;2935:117;3091:2;3117:53;3162:7;3153:6;3142:9;3138:22;3117:53;:::i;:::-;3107:63;;3062:118;2713:474;;;;;:::o;3193:619::-;3270:6;3278;3286;3335:2;3323:9;3314:7;3310:23;3306:32;3303:119;;;3341:79;;:::i;:::-;3303:119;3461:1;3486:53;3531:7;3522:6;3511:9;3507:22;3486:53;:::i;:::-;3476:63;;3432:117;3588:2;3614:53;3659:7;3650:6;3639:9;3635:22;3614:53;:::i;:::-;3604:63;;3559:118;3716:2;3742:53;3787:7;3778:6;3767:9;3763:22;3742:53;:::i;:::-;3732:63;;3687:118;3193:619;;;;;:::o;3818:474::-;3886:6;3894;3943:2;3931:9;3922:7;3918:23;3914:32;3911:119;;;3949:79;;:::i;:::-;3911:119;4069:1;4094:53;4139:7;4130:6;4119:9;4115:22;4094:53;:::i;:::-;4084:63;;4040:117;4196:2;4222:53;4267:7;4258:6;4247:9;4243:22;4222:53;:::i;:::-;4212:63;;4167:118;3818:474;;;;;:::o;4298:894::-;4416:6;4424;4473:2;4461:9;4452:7;4448:23;4444:32;4441:119;;;4479:79;;:::i;:::-;4441:119;4627:1;4616:9;4612:17;4599:31;4657:18;4649:6;4646:30;4643:117;;;4679:79;;:::i;:::-;4643:117;4784:78;4854:7;4845:6;4834:9;4830:22;4784:78;:::i;:::-;4774:88;;4570:302;4939:2;4928:9;4924:18;4911:32;4970:18;4962:6;4959:30;4956:117;;;4992:79;;:::i;:::-;4956:117;5097:78;5167:7;5158:6;5147:9;5143:22;5097:78;:::i;:::-;5087:88;;4882:303;4298:894;;;;;:::o;5198:684::-;5291:6;5299;5348:2;5336:9;5327:7;5323:23;5319:32;5316:119;;;5354:79;;:::i;:::-;5316:119;5502:1;5491:9;5487:17;5474:31;5532:18;5524:6;5521:30;5518:117;;;5554:79;;:::i;:::-;5518:117;5659:78;5729:7;5720:6;5709:9;5705:22;5659:78;:::i;:::-;5649:88;;5445:302;5786:2;5812:53;5857:7;5848:6;5837:9;5833:22;5812:53;:::i;:::-;5802:63;;5757:118;5198:684;;;;;:::o;5888:329::-;5947:6;5996:2;5984:9;5975:7;5971:23;5967:32;5964:119;;;6002:79;;:::i;:::-;5964:119;6122:1;6147:53;6192:7;6183:6;6172:9;6168:22;6147:53;:::i;:::-;6137:63;;6093:117;5888:329;;;;:::o;6223:474::-;6291:6;6299;6348:2;6336:9;6327:7;6323:23;6319:32;6316:119;;;6354:79;;:::i;:::-;6316:119;6474:1;6499:53;6544:7;6535:6;6524:9;6520:22;6499:53;:::i;:::-;6489:63;;6445:117;6601:2;6627:53;6672:7;6663:6;6652:9;6648:22;6627:53;:::i;:::-;6617:63;;6572:118;6223:474;;;;;:::o;6703:::-;6771:6;6779;6828:2;6816:9;6807:7;6803:23;6799:32;6796:119;;;6834:79;;:::i;:::-;6796:119;6954:1;6979:53;7024:7;7015:6;7004:9;7000:22;6979:53;:::i;:::-;6969:63;;6925:117;7081:2;7107:53;7152:7;7143:6;7132:9;7128:22;7107:53;:::i;:::-;7097:63;;7052:118;6703:474;;;;;:::o;7183:327::-;7241:6;7290:2;7278:9;7269:7;7265:23;7261:32;7258:119;;;7296:79;;:::i;:::-;7258:119;7416:1;7441:52;7485:7;7476:6;7465:9;7461:22;7441:52;:::i;:::-;7431:62;;7387:116;7183:327;;;;:::o;7516:329::-;7575:6;7624:2;7612:9;7603:7;7599:23;7595:32;7592:119;;;7630:79;;:::i;:::-;7592:119;7750:1;7775:53;7820:7;7811:6;7800:9;7796:22;7775:53;:::i;:::-;7765:63;;7721:117;7516:329;;;;:::o;7851:351::-;7921:6;7970:2;7958:9;7949:7;7945:23;7941:32;7938:119;;;7976:79;;:::i;:::-;7938:119;8096:1;8121:64;8177:7;8168:6;8157:9;8153:22;8121:64;:::i;:::-;8111:74;;8067:128;7851:351;;;;:::o;8208:474::-;8276:6;8284;8333:2;8321:9;8312:7;8308:23;8304:32;8301:119;;;8339:79;;:::i;:::-;8301:119;8459:1;8484:53;8529:7;8520:6;8509:9;8505:22;8484:53;:::i;:::-;8474:63;;8430:117;8586:2;8612:53;8657:7;8648:6;8637:9;8633:22;8612:53;:::i;:::-;8602:63;;8557:118;8208:474;;;;;:::o;8688:118::-;8775:24;8793:5;8775:24;:::i;:::-;8770:3;8763:37;8688:118;;:::o;8812:109::-;8893:21;8908:5;8893:21;:::i;:::-;8888:3;8881:34;8812:109;;:::o;8927:118::-;9014:24;9032:5;9014:24;:::i;:::-;9009:3;9002:37;8927:118;;:::o;9051:364::-;9139:3;9167:39;9200:5;9167:39;:::i;:::-;9222:71;9286:6;9281:3;9222:71;:::i;:::-;9215:78;;9302:52;9347:6;9342:3;9335:4;9328:5;9324:16;9302:52;:::i;:::-;9379:29;9401:6;9379:29;:::i;:::-;9374:3;9370:39;9363:46;;9143:272;9051:364;;;;:::o;9421:377::-;9527:3;9555:39;9588:5;9555:39;:::i;:::-;9610:89;9692:6;9687:3;9610:89;:::i;:::-;9603:96;;9708:52;9753:6;9748:3;9741:4;9734:5;9730:16;9708:52;:::i;:::-;9785:6;9780:3;9776:16;9769:23;;9531:267;9421:377;;;;:::o;9804:366::-;9946:3;9967:67;10031:2;10026:3;9967:67;:::i;:::-;9960:74;;10043:93;10132:3;10043:93;:::i;:::-;10161:2;10156:3;10152:12;10145:19;;9804:366;;;:::o;10176:::-;10318:3;10339:67;10403:2;10398:3;10339:67;:::i;:::-;10332:74;;10415:93;10504:3;10415:93;:::i;:::-;10533:2;10528:3;10524:12;10517:19;;10176:366;;;:::o;10548:::-;10690:3;10711:67;10775:2;10770:3;10711:67;:::i;:::-;10704:74;;10787:93;10876:3;10787:93;:::i;:::-;10905:2;10900:3;10896:12;10889:19;;10548:366;;;:::o;10920:::-;11062:3;11083:67;11147:2;11142:3;11083:67;:::i;:::-;11076:74;;11159:93;11248:3;11159:93;:::i;:::-;11277:2;11272:3;11268:12;11261:19;;10920:366;;;:::o;11292:::-;11434:3;11455:67;11519:2;11514:3;11455:67;:::i;:::-;11448:74;;11531:93;11620:3;11531:93;:::i;:::-;11649:2;11644:3;11640:12;11633:19;;11292:366;;;:::o;11664:::-;11806:3;11827:67;11891:2;11886:3;11827:67;:::i;:::-;11820:74;;11903:93;11992:3;11903:93;:::i;:::-;12021:2;12016:3;12012:12;12005:19;;11664:366;;;:::o;12036:::-;12178:3;12199:67;12263:2;12258:3;12199:67;:::i;:::-;12192:74;;12275:93;12364:3;12275:93;:::i;:::-;12393:2;12388:3;12384:12;12377:19;;12036:366;;;:::o;12408:::-;12550:3;12571:67;12635:2;12630:3;12571:67;:::i;:::-;12564:74;;12647:93;12736:3;12647:93;:::i;:::-;12765:2;12760:3;12756:12;12749:19;;12408:366;;;:::o;12780:::-;12922:3;12943:67;13007:2;13002:3;12943:67;:::i;:::-;12936:74;;13019:93;13108:3;13019:93;:::i;:::-;13137:2;13132:3;13128:12;13121:19;;12780:366;;;:::o;13152:::-;13294:3;13315:67;13379:2;13374:3;13315:67;:::i;:::-;13308:74;;13391:93;13480:3;13391:93;:::i;:::-;13509:2;13504:3;13500:12;13493:19;;13152:366;;;:::o;13524:::-;13666:3;13687:67;13751:2;13746:3;13687:67;:::i;:::-;13680:74;;13763:93;13852:3;13763:93;:::i;:::-;13881:2;13876:3;13872:12;13865:19;;13524:366;;;:::o;13896:::-;14038:3;14059:67;14123:2;14118:3;14059:67;:::i;:::-;14052:74;;14135:93;14224:3;14135:93;:::i;:::-;14253:2;14248:3;14244:12;14237:19;;13896:366;;;:::o;14268:::-;14410:3;14431:67;14495:2;14490:3;14431:67;:::i;:::-;14424:74;;14507:93;14596:3;14507:93;:::i;:::-;14625:2;14620:3;14616:12;14609:19;;14268:366;;;:::o;14640:::-;14782:3;14803:67;14867:2;14862:3;14803:67;:::i;:::-;14796:74;;14879:93;14968:3;14879:93;:::i;:::-;14997:2;14992:3;14988:12;14981:19;;14640:366;;;:::o;15012:::-;15154:3;15175:67;15239:2;15234:3;15175:67;:::i;:::-;15168:74;;15251:93;15340:3;15251:93;:::i;:::-;15369:2;15364:3;15360:12;15353:19;;15012:366;;;:::o;15384:::-;15526:3;15547:67;15611:2;15606:3;15547:67;:::i;:::-;15540:74;;15623:93;15712:3;15623:93;:::i;:::-;15741:2;15736:3;15732:12;15725:19;;15384:366;;;:::o;15756:::-;15898:3;15919:67;15983:2;15978:3;15919:67;:::i;:::-;15912:74;;15995:93;16084:3;15995:93;:::i;:::-;16113:2;16108:3;16104:12;16097:19;;15756:366;;;:::o;16128:::-;16270:3;16291:67;16355:2;16350:3;16291:67;:::i;:::-;16284:74;;16367:93;16456:3;16367:93;:::i;:::-;16485:2;16480:3;16476:12;16469:19;;16128:366;;;:::o;16500:::-;16642:3;16663:67;16727:2;16722:3;16663:67;:::i;:::-;16656:74;;16739:93;16828:3;16739:93;:::i;:::-;16857:2;16852:3;16848:12;16841:19;;16500:366;;;:::o;16872:::-;17014:3;17035:67;17099:2;17094:3;17035:67;:::i;:::-;17028:74;;17111:93;17200:3;17111:93;:::i;:::-;17229:2;17224:3;17220:12;17213:19;;16872:366;;;:::o;17244:::-;17386:3;17407:67;17471:2;17466:3;17407:67;:::i;:::-;17400:74;;17483:93;17572:3;17483:93;:::i;:::-;17601:2;17596:3;17592:12;17585:19;;17244:366;;;:::o;17616:::-;17758:3;17779:67;17843:2;17838:3;17779:67;:::i;:::-;17772:74;;17855:93;17944:3;17855:93;:::i;:::-;17973:2;17968:3;17964:12;17957:19;;17616:366;;;:::o;17988:::-;18130:3;18151:67;18215:2;18210:3;18151:67;:::i;:::-;18144:74;;18227:93;18316:3;18227:93;:::i;:::-;18345:2;18340:3;18336:12;18329:19;;17988:366;;;:::o;18360:::-;18502:3;18523:67;18587:2;18582:3;18523:67;:::i;:::-;18516:74;;18599:93;18688:3;18599:93;:::i;:::-;18717:2;18712:3;18708:12;18701:19;;18360:366;;;:::o;18732:402::-;18892:3;18913:85;18995:2;18990:3;18913:85;:::i;:::-;18906:92;;19007:93;19096:3;19007:93;:::i;:::-;19125:2;19120:3;19116:12;19109:19;;18732:402;;;:::o;19140:366::-;19282:3;19303:67;19367:2;19362:3;19303:67;:::i;:::-;19296:74;;19379:93;19468:3;19379:93;:::i;:::-;19497:2;19492:3;19488:12;19481:19;;19140:366;;;:::o;19512:402::-;19672:3;19693:85;19775:2;19770:3;19693:85;:::i;:::-;19686:92;;19787:93;19876:3;19787:93;:::i;:::-;19905:2;19900:3;19896:12;19889:19;;19512:402;;;:::o;19920:366::-;20062:3;20083:67;20147:2;20142:3;20083:67;:::i;:::-;20076:74;;20159:93;20248:3;20159:93;:::i;:::-;20277:2;20272:3;20268:12;20261:19;;19920:366;;;:::o;20292:::-;20434:3;20455:67;20519:2;20514:3;20455:67;:::i;:::-;20448:74;;20531:93;20620:3;20531:93;:::i;:::-;20649:2;20644:3;20640:12;20633:19;;20292:366;;;:::o;20664:::-;20806:3;20827:67;20891:2;20886:3;20827:67;:::i;:::-;20820:74;;20903:93;20992:3;20903:93;:::i;:::-;21021:2;21016:3;21012:12;21005:19;;20664:366;;;:::o;21036:118::-;21123:24;21141:5;21123:24;:::i;:::-;21118:3;21111:37;21036:118;;:::o;21160:112::-;21243:22;21259:5;21243:22;:::i;:::-;21238:3;21231:35;21160:112;;:::o;21278:967::-;21660:3;21682:148;21826:3;21682:148;:::i;:::-;21675:155;;21847:95;21938:3;21929:6;21847:95;:::i;:::-;21840:102;;21959:148;22103:3;21959:148;:::i;:::-;21952:155;;22124:95;22215:3;22206:6;22124:95;:::i;:::-;22117:102;;22236:3;22229:10;;21278:967;;;;;:::o;22251:222::-;22344:4;22382:2;22371:9;22367:18;22359:26;;22395:71;22463:1;22452:9;22448:17;22439:6;22395:71;:::i;:::-;22251:222;;;;:::o;22479:210::-;22566:4;22604:2;22593:9;22589:18;22581:26;;22617:65;22679:1;22668:9;22664:17;22655:6;22617:65;:::i;:::-;22479:210;;;;:::o;22695:222::-;22788:4;22826:2;22815:9;22811:18;22803:26;;22839:71;22907:1;22896:9;22892:17;22883:6;22839:71;:::i;:::-;22695:222;;;;:::o;22923:313::-;23036:4;23074:2;23063:9;23059:18;23051:26;;23123:9;23117:4;23113:20;23109:1;23098:9;23094:17;23087:47;23151:78;23224:4;23215:6;23151:78;:::i;:::-;23143:86;;22923:313;;;;:::o;23242:419::-;23408:4;23446:2;23435:9;23431:18;23423:26;;23495:9;23489:4;23485:20;23481:1;23470:9;23466:17;23459:47;23523:131;23649:4;23523:131;:::i;:::-;23515:139;;23242:419;;;:::o;23667:::-;23833:4;23871:2;23860:9;23856:18;23848:26;;23920:9;23914:4;23910:20;23906:1;23895:9;23891:17;23884:47;23948:131;24074:4;23948:131;:::i;:::-;23940:139;;23667:419;;;:::o;24092:::-;24258:4;24296:2;24285:9;24281:18;24273:26;;24345:9;24339:4;24335:20;24331:1;24320:9;24316:17;24309:47;24373:131;24499:4;24373:131;:::i;:::-;24365:139;;24092:419;;;:::o;24517:::-;24683:4;24721:2;24710:9;24706:18;24698:26;;24770:9;24764:4;24760:20;24756:1;24745:9;24741:17;24734:47;24798:131;24924:4;24798:131;:::i;:::-;24790:139;;24517:419;;;:::o;24942:::-;25108:4;25146:2;25135:9;25131:18;25123:26;;25195:9;25189:4;25185:20;25181:1;25170:9;25166:17;25159:47;25223:131;25349:4;25223:131;:::i;:::-;25215:139;;24942:419;;;:::o;25367:::-;25533:4;25571:2;25560:9;25556:18;25548:26;;25620:9;25614:4;25610:20;25606:1;25595:9;25591:17;25584:47;25648:131;25774:4;25648:131;:::i;:::-;25640:139;;25367:419;;;:::o;25792:::-;25958:4;25996:2;25985:9;25981:18;25973:26;;26045:9;26039:4;26035:20;26031:1;26020:9;26016:17;26009:47;26073:131;26199:4;26073:131;:::i;:::-;26065:139;;25792:419;;;:::o;26217:::-;26383:4;26421:2;26410:9;26406:18;26398:26;;26470:9;26464:4;26460:20;26456:1;26445:9;26441:17;26434:47;26498:131;26624:4;26498:131;:::i;:::-;26490:139;;26217:419;;;:::o;26642:::-;26808:4;26846:2;26835:9;26831:18;26823:26;;26895:9;26889:4;26885:20;26881:1;26870:9;26866:17;26859:47;26923:131;27049:4;26923:131;:::i;:::-;26915:139;;26642:419;;;:::o;27067:::-;27233:4;27271:2;27260:9;27256:18;27248:26;;27320:9;27314:4;27310:20;27306:1;27295:9;27291:17;27284:47;27348:131;27474:4;27348:131;:::i;:::-;27340:139;;27067:419;;;:::o;27492:::-;27658:4;27696:2;27685:9;27681:18;27673:26;;27745:9;27739:4;27735:20;27731:1;27720:9;27716:17;27709:47;27773:131;27899:4;27773:131;:::i;:::-;27765:139;;27492:419;;;:::o;27917:::-;28083:4;28121:2;28110:9;28106:18;28098:26;;28170:9;28164:4;28160:20;28156:1;28145:9;28141:17;28134:47;28198:131;28324:4;28198:131;:::i;:::-;28190:139;;27917:419;;;:::o;28342:::-;28508:4;28546:2;28535:9;28531:18;28523:26;;28595:9;28589:4;28585:20;28581:1;28570:9;28566:17;28559:47;28623:131;28749:4;28623:131;:::i;:::-;28615:139;;28342:419;;;:::o;28767:::-;28933:4;28971:2;28960:9;28956:18;28948:26;;29020:9;29014:4;29010:20;29006:1;28995:9;28991:17;28984:47;29048:131;29174:4;29048:131;:::i;:::-;29040:139;;28767:419;;;:::o;29192:::-;29358:4;29396:2;29385:9;29381:18;29373:26;;29445:9;29439:4;29435:20;29431:1;29420:9;29416:17;29409:47;29473:131;29599:4;29473:131;:::i;:::-;29465:139;;29192:419;;;:::o;29617:::-;29783:4;29821:2;29810:9;29806:18;29798:26;;29870:9;29864:4;29860:20;29856:1;29845:9;29841:17;29834:47;29898:131;30024:4;29898:131;:::i;:::-;29890:139;;29617:419;;;:::o;30042:::-;30208:4;30246:2;30235:9;30231:18;30223:26;;30295:9;30289:4;30285:20;30281:1;30270:9;30266:17;30259:47;30323:131;30449:4;30323:131;:::i;:::-;30315:139;;30042:419;;;:::o;30467:::-;30633:4;30671:2;30660:9;30656:18;30648:26;;30720:9;30714:4;30710:20;30706:1;30695:9;30691:17;30684:47;30748:131;30874:4;30748:131;:::i;:::-;30740:139;;30467:419;;;:::o;30892:::-;31058:4;31096:2;31085:9;31081:18;31073:26;;31145:9;31139:4;31135:20;31131:1;31120:9;31116:17;31109:47;31173:131;31299:4;31173:131;:::i;:::-;31165:139;;30892:419;;;:::o;31317:::-;31483:4;31521:2;31510:9;31506:18;31498:26;;31570:9;31564:4;31560:20;31556:1;31545:9;31541:17;31534:47;31598:131;31724:4;31598:131;:::i;:::-;31590:139;;31317:419;;;:::o;31742:::-;31908:4;31946:2;31935:9;31931:18;31923:26;;31995:9;31989:4;31985:20;31981:1;31970:9;31966:17;31959:47;32023:131;32149:4;32023:131;:::i;:::-;32015:139;;31742:419;;;:::o;32167:::-;32333:4;32371:2;32360:9;32356:18;32348:26;;32420:9;32414:4;32410:20;32406:1;32395:9;32391:17;32384:47;32448:131;32574:4;32448:131;:::i;:::-;32440:139;;32167:419;;;:::o;32592:::-;32758:4;32796:2;32785:9;32781:18;32773:26;;32845:9;32839:4;32835:20;32831:1;32820:9;32816:17;32809:47;32873:131;32999:4;32873:131;:::i;:::-;32865:139;;32592:419;;;:::o;33017:::-;33183:4;33221:2;33210:9;33206:18;33198:26;;33270:9;33264:4;33260:20;33256:1;33245:9;33241:17;33234:47;33298:131;33424:4;33298:131;:::i;:::-;33290:139;;33017:419;;;:::o;33442:::-;33608:4;33646:2;33635:9;33631:18;33623:26;;33695:9;33689:4;33685:20;33681:1;33670:9;33666:17;33659:47;33723:131;33849:4;33723:131;:::i;:::-;33715:139;;33442:419;;;:::o;33867:::-;34033:4;34071:2;34060:9;34056:18;34048:26;;34120:9;34114:4;34110:20;34106:1;34095:9;34091:17;34084:47;34148:131;34274:4;34148:131;:::i;:::-;34140:139;;33867:419;;;:::o;34292:::-;34458:4;34496:2;34485:9;34481:18;34473:26;;34545:9;34539:4;34535:20;34531:1;34520:9;34516:17;34509:47;34573:131;34699:4;34573:131;:::i;:::-;34565:139;;34292:419;;;:::o;34717:::-;34883:4;34921:2;34910:9;34906:18;34898:26;;34970:9;34964:4;34960:20;34956:1;34945:9;34941:17;34934:47;34998:131;35124:4;34998:131;:::i;:::-;34990:139;;34717:419;;;:::o;35142:222::-;35235:4;35273:2;35262:9;35258:18;35250:26;;35286:71;35354:1;35343:9;35339:17;35330:6;35286:71;:::i;:::-;35142:222;;;;:::o;35370:214::-;35459:4;35497:2;35486:9;35482:18;35474:26;;35510:67;35574:1;35563:9;35559:17;35550:6;35510:67;:::i;:::-;35370:214;;;;:::o;35590:129::-;35624:6;35651:20;;:::i;:::-;35641:30;;35680:33;35708:4;35700:6;35680:33;:::i;:::-;35590:129;;;:::o;35725:75::-;35758:6;35791:2;35785:9;35775:19;;35725:75;:::o;35806:311::-;35883:4;35973:18;35965:6;35962:30;35959:56;;;35995:18;;:::i;:::-;35959:56;36045:4;36037:6;36033:17;36025:25;;36105:4;36099;36095:15;36087:23;;35806:311;;;:::o;36123:99::-;36175:6;36209:5;36203:12;36193:22;;36123:99;;;:::o;36228:169::-;36312:11;36346:6;36341:3;36334:19;36386:4;36381:3;36377:14;36362:29;;36228:169;;;;:::o;36403:148::-;36505:11;36542:3;36527:18;;36403:148;;;;:::o;36557:305::-;36597:3;36616:20;36634:1;36616:20;:::i;:::-;36611:25;;36650:20;36668:1;36650:20;:::i;:::-;36645:25;;36804:1;36736:66;36732:74;36729:1;36726:81;36723:107;;;36810:18;;:::i;:::-;36723:107;36854:1;36851;36847:9;36840:16;;36557:305;;;;:::o;36868:185::-;36908:1;36925:20;36943:1;36925:20;:::i;:::-;36920:25;;36959:20;36977:1;36959:20;:::i;:::-;36954:25;;36998:1;36988:35;;37003:18;;:::i;:::-;36988:35;37045:1;37042;37038:9;37033:14;;36868:185;;;;:::o;37059:348::-;37099:7;37122:20;37140:1;37122:20;:::i;:::-;37117:25;;37156:20;37174:1;37156:20;:::i;:::-;37151:25;;37344:1;37276:66;37272:74;37269:1;37266:81;37261:1;37254:9;37247:17;37243:105;37240:131;;;37351:18;;:::i;:::-;37240:131;37399:1;37396;37392:9;37381:20;;37059:348;;;;:::o;37413:191::-;37453:4;37473:20;37491:1;37473:20;:::i;:::-;37468:25;;37507:20;37525:1;37507:20;:::i;:::-;37502:25;;37546:1;37543;37540:8;37537:34;;;37551:18;;:::i;:::-;37537:34;37596:1;37593;37589:9;37581:17;;37413:191;;;;:::o;37610:96::-;37647:7;37676:24;37694:5;37676:24;:::i;:::-;37665:35;;37610:96;;;:::o;37712:90::-;37746:7;37789:5;37782:13;37775:21;37764:32;;37712:90;;;:::o;37808:77::-;37845:7;37874:5;37863:16;;37808:77;;;:::o;37891:149::-;37927:7;37967:66;37960:5;37956:78;37945:89;;37891:149;;;:::o;38046:126::-;38083:7;38123:42;38116:5;38112:54;38101:65;;38046:126;;;:::o;38178:77::-;38215:7;38244:5;38233:16;;38178:77;;;:::o;38261:86::-;38296:7;38336:4;38329:5;38325:16;38314:27;;38261:86;;;:::o;38353:307::-;38421:1;38431:113;38445:6;38442:1;38439:13;38431:113;;;38530:1;38525:3;38521:11;38515:18;38511:1;38506:3;38502:11;38495:39;38467:2;38464:1;38460:10;38455:15;;38431:113;;;38562:6;38559:1;38556:13;38553:101;;;38642:1;38633:6;38628:3;38624:16;38617:27;38553:101;38402:258;38353:307;;;:::o;38666:171::-;38705:3;38728:24;38746:5;38728:24;:::i;:::-;38719:33;;38774:4;38767:5;38764:15;38761:41;;;38782:18;;:::i;:::-;38761:41;38829:1;38822:5;38818:13;38811:20;;38666:171;;;:::o;38843:320::-;38887:6;38924:1;38918:4;38914:12;38904:22;;38971:1;38965:4;38961:12;38992:18;38982:81;;39048:4;39040:6;39036:17;39026:27;;38982:81;39110:2;39102:6;39099:14;39079:18;39076:38;39073:84;;;39129:18;;:::i;:::-;39073:84;38894:269;38843:320;;;:::o;39169:281::-;39252:27;39274:4;39252:27;:::i;:::-;39244:6;39240:40;39382:6;39370:10;39367:22;39346:18;39334:10;39331:34;39328:62;39325:88;;;39393:18;;:::i;:::-;39325:88;39433:10;39429:2;39422:22;39212:238;39169:281;;:::o;39456:233::-;39495:3;39518:24;39536:5;39518:24;:::i;:::-;39509:33;;39564:66;39557:5;39554:77;39551:103;;;39634:18;;:::i;:::-;39551:103;39681:1;39674:5;39670:13;39663:20;;39456:233;;;:::o;39695:180::-;39743:77;39740:1;39733:88;39840:4;39837:1;39830:15;39864:4;39861:1;39854:15;39881:180;39929:77;39926:1;39919:88;40026:4;40023:1;40016:15;40050:4;40047:1;40040:15;40067:180;40115:77;40112:1;40105:88;40212:4;40209:1;40202:15;40236:4;40233:1;40226:15;40253:180;40301:77;40298:1;40291:88;40398:4;40395:1;40388:15;40422:4;40419:1;40412:15;40439:180;40487:77;40484:1;40477:88;40584:4;40581:1;40574:15;40608:4;40605:1;40598:15;40625:180;40673:77;40670:1;40663:88;40770:4;40767:1;40760:15;40794:4;40791:1;40784:15;40811:117;40920:1;40917;40910:12;40934:117;41043:1;41040;41033:12;41057:117;41166:1;41163;41156:12;41180:117;41289:1;41286;41279:12;41303:102;41344:6;41395:2;41391:7;41386:2;41379:5;41375:14;41371:28;41361:38;;41303:102;;;:::o;41411:223::-;41551:34;41547:1;41539:6;41535:14;41528:58;41620:6;41615:2;41607:6;41603:15;41596:31;41411:223;:::o;41640:182::-;41780:34;41776:1;41768:6;41764:14;41757:58;41640:182;:::o;41828:222::-;41968:34;41964:1;41956:6;41952:14;41945:58;42037:5;42032:2;42024:6;42020:15;42013:30;41828:222;:::o;42056:170::-;42196:22;42192:1;42184:6;42180:14;42173:46;42056:170;:::o;42232:169::-;42372:21;42368:1;42360:6;42356:14;42349:45;42232:169;:::o;42407:221::-;42547:34;42543:1;42535:6;42531:14;42524:58;42616:4;42611:2;42603:6;42599:15;42592:29;42407:221;:::o;42634:244::-;42774:34;42770:1;42762:6;42758:14;42751:58;42843:27;42838:2;42830:6;42826:15;42819:52;42634:244;:::o;42884:221::-;43024:34;43020:1;43012:6;43008:14;43001:58;43093:4;43088:2;43080:6;43076:15;43069:29;42884:221;:::o;43111:179::-;43251:31;43247:1;43239:6;43235:14;43228:55;43111:179;:::o;43296:225::-;43436:34;43432:1;43424:6;43420:14;43413:58;43505:8;43500:2;43492:6;43488:15;43481:33;43296:225;:::o;43527:221::-;43667:34;43663:1;43655:6;43651:14;43644:58;43736:4;43731:2;43723:6;43719:15;43712:29;43527:221;:::o;43754:166::-;43894:18;43890:1;43882:6;43878:14;43871:42;43754:166;:::o;43926:180::-;44066:32;44062:1;44054:6;44050:14;44043:56;43926:180;:::o;44112:178::-;44252:30;44248:1;44240:6;44236:14;44229:54;44112:178;:::o;44296:175::-;44436:27;44432:1;44424:6;44420:14;44413:51;44296:175;:::o;44477:161::-;44617:13;44613:1;44605:6;44601:14;44594:37;44477:161;:::o;44644:175::-;44784:27;44780:1;44772:6;44768:14;44761:51;44644:175;:::o;44825:171::-;44965:23;44961:1;44953:6;44949:14;44942:47;44825:171;:::o;45002:241::-;45142:34;45138:1;45130:6;45126:14;45119:58;45211:24;45206:2;45198:6;45194:15;45187:49;45002:241;:::o;45249:220::-;45389:34;45385:1;45377:6;45373:14;45366:58;45458:3;45453:2;45445:6;45441:15;45434:28;45249:220;:::o;45475:178::-;45615:30;45611:1;45603:6;45599:14;45592:54;45475:178;:::o;45659:224::-;45799:34;45795:1;45787:6;45783:14;45776:58;45868:7;45863:2;45855:6;45851:15;45844:32;45659:224;:::o;45889:223::-;46029:34;46025:1;46017:6;46013:14;46006:58;46098:6;46093:2;46085:6;46081:15;46074:31;45889:223;:::o;46118:242::-;46258:34;46254:1;46246:6;46242:14;46235:58;46327:25;46322:2;46314:6;46310:15;46303:50;46118:242;:::o;46366:173::-;46506:25;46502:1;46494:6;46490:14;46483:49;46366:173;:::o;46545:224::-;46685:34;46681:1;46673:6;46669:14;46662:58;46754:7;46749:2;46741:6;46737:15;46730:32;46545:224;:::o;46775:167::-;46915:19;46911:1;46903:6;46899:14;46892:43;46775:167;:::o;46948:234::-;47088:34;47084:1;47076:6;47072:14;47065:58;47157:17;47152:2;47144:6;47140:15;47133:42;46948:234;:::o;47188:181::-;47328:33;47324:1;47316:6;47312:14;47305:57;47188:181;:::o;47375:229::-;47515:34;47511:1;47503:6;47499:14;47492:58;47584:12;47579:2;47571:6;47567:15;47560:37;47375:229;:::o;47610:122::-;47683:24;47701:5;47683:24;:::i;:::-;47676:5;47673:35;47663:63;;47722:1;47719;47712:12;47663:63;47610:122;:::o;47738:::-;47811:24;47829:5;47811:24;:::i;:::-;47804:5;47801:35;47791:63;;47850:1;47847;47840:12;47791:63;47738:122;:::o;47866:120::-;47938:23;47955:5;47938:23;:::i;:::-;47931:5;47928:34;47918:62;;47976:1;47973;47966:12;47918:62;47866:120;:::o;47992:122::-;48065:24;48083:5;48065:24;:::i;:::-;48058:5;48055:35;48045:63;;48104:1;48101;48094:12;48045:63;47992:122;:::o

Swarm Source

ipfs://4fa7b9a38bbac0da91979aeacb2779ce46fcaee6808687a8736274201e56336c
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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