Token TurtleTurtle.club: The Timmy Collection

 

Overview ERC-721

Total Supply:
1,000 TIMMY

Holders:
129 addresses

Transfers:
-

Loading
[ Download CSV Export  ] 
Loading
Loading

Click here to update the token ICO / general information
# Exchange Pair Price  24H Volume % Volume
Loading
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.

Contract Source Code Verified (Exact Match)

Contract Name:
ERC721Template

Compiler Version
v0.8.11+commit.d7f03943

Optimization Enabled:
Yes with 999999 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-02-05
*/

// SPDX-License-Identifier: MIT
pragma solidity ^0.8.10;

// Sources flattened with hardhat v2.8.3 https://hardhat.org

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

// OpenZeppelin Contracts v4.4.1 (token/ERC20/IERC20.sol)

/**
 * @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 `recipient`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address recipient, 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 `sender` to `recipient` 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 sender,
        address recipient,
        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/utils/Address.sol

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

/**
 * @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/ERC20/utils/SafeERC20.sol

// OpenZeppelin Contracts v4.4.1 (token/ERC20/utils/SafeERC20.sol)

/**
 * @title SafeERC20
 * @dev Wrappers around ERC20 operations that throw on failure (when the token
 * contract returns false). Tokens that return no value (and instead revert or
 * throw on failure) are also supported, non-reverting calls are assumed to be
 * successful.
 * To use this library you can add a `using SafeERC20 for IERC20;` statement to your contract,
 * which allows you to call the safe operations as `token.safeTransfer(...)`, etc.
 */
library SafeERC20 {
    using Address for address;

    function safeTransfer(
        IERC20 token,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(
            token,
            abi.encodeWithSelector(token.transfer.selector, to, value)
        );
    }

    function safeTransferFrom(
        IERC20 token,
        address from,
        address to,
        uint256 value
    ) internal {
        _callOptionalReturn(
            token,
            abi.encodeWithSelector(token.transferFrom.selector, from, to, value)
        );
    }

    /**
     * @dev Deprecated. This function has issues similar to the ones found in
     * {IERC20-approve}, and its usage is discouraged.
     *
     * Whenever possible, use {safeIncreaseAllowance} and
     * {safeDecreaseAllowance} instead.
     */
    function safeApprove(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        // safeApprove should only be called when setting an initial allowance,
        // or when resetting it to zero. To increase and decrease it, use
        // 'safeIncreaseAllowance' and 'safeDecreaseAllowance'
        require(
            (value == 0) || (token.allowance(address(this), spender) == 0),
            "SafeERC20: approve from non-zero to non-zero allowance"
        );
        _callOptionalReturn(
            token,
            abi.encodeWithSelector(token.approve.selector, spender, value)
        );
    }

    function safeIncreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        uint256 newAllowance = token.allowance(address(this), spender) + value;
        _callOptionalReturn(
            token,
            abi.encodeWithSelector(
                token.approve.selector,
                spender,
                newAllowance
            )
        );
    }

    function safeDecreaseAllowance(
        IERC20 token,
        address spender,
        uint256 value
    ) internal {
        unchecked {
            uint256 oldAllowance = token.allowance(address(this), spender);
            require(
                oldAllowance >= value,
                "SafeERC20: decreased allowance below zero"
            );
            uint256 newAllowance = oldAllowance - value;
            _callOptionalReturn(
                token,
                abi.encodeWithSelector(
                    token.approve.selector,
                    spender,
                    newAllowance
                )
            );
        }
    }

    /**
     * @dev Imitates a Solidity high-level call (i.e. a regular function call to a contract), relaxing the requirement
     * on the return value: the return value is optional (but if data is returned, it must not be false).
     * @param token The token targeted by the call.
     * @param data The call data (encoded using abi.encode or one of its variants).
     */
    function _callOptionalReturn(IERC20 token, bytes memory data) private {
        // We need to perform a low level call here, to bypass Solidity's return data size checking mechanism, since
        // we're implementing it ourselves. We use {Address.functionCall} to perform this call, which verifies that
        // the target address contains contract code and also asserts for success in the low-level call.

        bytes memory returndata = address(token).functionCall(
            data,
            "SafeERC20: low-level call failed"
        );
        if (returndata.length > 0) {
            // Return data is optional
            require(
                abi.decode(returndata, (bool)),
                "SafeERC20: ERC20 operation did not succeed"
            );
        }
    }
}

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

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

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

/**
 * @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/IERC721Receiver.sol

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

/**
 * @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/token/ERC721/extensions/IERC721Metadata.sol

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

/**
 * @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 internal _name;

    // Token symbol
    string internal _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

// OpenZeppelin Contracts v4.4.1 (interfaces/IERC165.sol)

// File @openzeppelin/contracts/interfaces/IERC2981.sol

// OpenZeppelin Contracts v4.4.1 (interfaces/IERC2981.sol)

/**
 * @dev Interface for the NFT Royalty Standard.
 *
 * A standardized way to retrieve royalty payment information for non-fungible tokens (NFTs) to enable universal
 * support for royalty payments across all NFT marketplaces and ecosystem participants.
 *
 * _Available since v4.5._
 */
interface IERC2981 is IERC165 {
    /**
     * @dev Returns how much royalty is owed and to whom, based on a sale price that may be denominated in any unit of
     * exchange. The royalty amount is denominated and should be payed in that same unit of exchange.
     */
    function royaltyInfo(uint256 tokenId, uint256 salePrice)
        external
        view
        returns (address receiver, uint256 royaltyAmount);
}

// File @openzeppelin/contracts/token/common/ERC2981.sol

// OpenZeppelin Contracts v4.4.0 (token/common/ERC2981.sol)

/**
 * @dev Implementation of the NFT Royalty Standard, a standardized way to retrieve royalty payment information.
 *
 * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for
 * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.
 *
 * Royalty is specified as a fraction of sale price. {_feeDenominator} is overridable but defaults to 10000, meaning the
 * fee is specified in basis points by default.
 *
 * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See
 * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to
 * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.
 *
 * _Available since v4.5._
 */
abstract contract ERC2981 is IERC2981, ERC165 {
    struct RoyaltyInfo {
        address receiver;
        uint96 royaltyFraction;
    }

    RoyaltyInfo private _defaultRoyaltyInfo;
    mapping(uint256 => RoyaltyInfo) private _tokenRoyaltyInfo;

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

    /**
     * @inheritdoc IERC2981
     */
    function royaltyInfo(uint256 _tokenId, uint256 _salePrice)
        external
        view
        virtual
        override
        returns (address, uint256)
    {
        RoyaltyInfo memory royalty = _tokenRoyaltyInfo[_tokenId];

        if (royalty.receiver == address(0)) {
            royalty = _defaultRoyaltyInfo;
        }

        uint256 royaltyAmount = (_salePrice * royalty.royaltyFraction) /
            _feeDenominator();

        return (royalty.receiver, royaltyAmount);
    }

    /**
     * @dev The denominator with which to interpret the fee set in {_setTokenRoyalty} and {_setDefaultRoyalty} as a
     * fraction of the sale price. Defaults to 10000 so fees are expressed in basis points, but may be customized by an
     * override.
     */
    function _feeDenominator() internal pure virtual returns (uint96) {
        return 10000;
    }

    /**
     * @dev Sets the royalty information that all ids in this contract will default to.
     *
     * Requirements:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setDefaultRoyalty(address receiver, uint96 feeNumerator)
        internal
        virtual
    {
        require(
            feeNumerator <= _feeDenominator(),
            "ERC2981: royalty fee will exceed salePrice"
        );
        require(receiver != address(0), "ERC2981: invalid receiver");

        _defaultRoyaltyInfo = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Removes default royalty information.
     */
    function _deleteDefaultRoyalty() internal virtual {
        delete _defaultRoyaltyInfo;
    }

    /**
     * @dev Sets the royalty information for a specific token id, overriding the global default.
     *
     * Requirements:
     *
     * - `tokenId` must be already minted.
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setTokenRoyalty(
        uint256 tokenId,
        address receiver,
        uint96 feeNumerator
    ) internal virtual {
        require(
            feeNumerator <= _feeDenominator(),
            "ERC2981: royalty fee will exceed salePrice"
        );
        require(receiver != address(0), "ERC2981: Invalid parameters");

        _tokenRoyaltyInfo[tokenId] = RoyaltyInfo(receiver, feeNumerator);
    }

    /**
     * @dev Resets royalty information for the token id back to the global default.
     */
    function _resetTokenRoyalty(uint256 tokenId) internal virtual {
        delete _tokenRoyaltyInfo[tokenId];
    }
}

// File @openzeppelin/contracts/token/ERC721/extensions/ERC721Royalty.sol

// OpenZeppelin Contracts v4.4.0 (token/ERC721/extensions/ERC721Royalty.sol)

/**
 * @dev Extension of ERC721 with the ERC2981 NFT Royalty Standard, a standardized way to retrieve royalty payment
 * information.
 *
 * Royalty information can be specified globally for all token ids via {_setDefaultRoyalty}, and/or individually for
 * specific token ids via {_setTokenRoyalty}. The latter takes precedence over the first.
 *
 * IMPORTANT: ERC-2981 only specifies a way to signal royalty information and does not enforce its payment. See
 * https://eips.ethereum.org/EIPS/eip-2981#optional-royalty-payments[Rationale] in the EIP. Marketplaces are expected to
 * voluntarily pay royalties together with sales, but note that this standard is not yet widely supported.
 *
 * _Available since v4.5._
 */
abstract contract ERC721Royalty is ERC2981, ERC721 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override(ERC721, ERC2981)
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }

    /**
     * @dev See {ERC721-_burn}. This override additionally clears the royalty information for the token.
     */
    function _burn(uint256 tokenId) internal virtual override {
        super._burn(tokenId);
        _resetTokenRoyalty(tokenId);
    }
}

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

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

/**
 * @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/ERC721Enumerable.sol

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

/**
 * @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/security/Pausable.sol

// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol)

/**
 * @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 internal _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 Modifier to make a function override the current pause state
     */
    modifier overridePause() {
        bool wasPaused = paused();
        if (wasPaused) {
            _unpause();
        }
        _;
        if (wasPaused) {
            _pause();
        }
    }

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

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

// File @openzeppelin/contracts/token/ERC721/extensions/ERC721Pausable.sol

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

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

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

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

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

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

/**
 * @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/access/AccessControl.sol

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

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

    mapping(bytes32 => RoleData) private _roles;

    bytes32 public constant DEFAULT_ADMIN_ROLE = 0x00;

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

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

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

    /**
     * @dev Revert with a standard message if `_msgSender()` is missing `role`.
     * Overriding this function changes the behavior of the {onlyRole} modifier.
     *
     * Format of the revert message is described in {_checkRole}.
     *
     * _Available since v4.6._
     */
    function _checkRole(bytes32 role) internal view virtual {
        _checkRole(role, _msgSender());
    }

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

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

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

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

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

        _revokeRole(role, account);
    }

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

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

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

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

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

// OpenZeppelin Contracts v4.4.1 (utils/structs/EnumerableSet.sol)

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

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

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

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

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

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

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

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

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

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

            return true;
        } else {
            return false;
        }
    }

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

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

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

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

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

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

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

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

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

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

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

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

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

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

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

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

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

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

        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

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

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

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

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

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

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

        assembly {
            result := store
        }

        return result;
    }
}

// File @openzeppelin/contracts/access/AccessControlEnumerable.sol

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

/**
 * @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/proxy/Clones.sol

// OpenZeppelin Contracts v4.4.1 (proxy/Clones.sol)

/**
 * @dev https://eips.ethereum.org/EIPS/eip-1167[EIP 1167] is a standard for
 * deploying minimal proxy contracts, also known as "clones".
 *
 * > To simply and cheaply clone contract functionality in an immutable way, this standard specifies
 * > a minimal bytecode implementation that delegates all calls to a known, fixed address.
 *
 * The library includes functions to deploy a proxy using either `create` (traditional deployment) or `create2`
 * (salted deterministic deployment). It also includes functions to predict the addresses of clones deployed using the
 * deterministic method.
 *
 * _Available since v3.4._
 */
library Clones {
    /**
     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
     *
     * This function uses the create opcode, which should never revert.
     */
    function clone(address implementation) internal returns (address instance) {
        assembly {
            let ptr := mload(0x40)
            mstore(
                ptr,
                0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000
            )
            mstore(add(ptr, 0x14), shl(0x60, implementation))
            mstore(
                add(ptr, 0x28),
                0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000
            )
            instance := create(0, ptr, 0x37)
        }
        require(instance != address(0), "ERC1167: create failed");
    }

    /**
     * @dev Deploys and returns the address of a clone that mimics the behaviour of `implementation`.
     *
     * This function uses the create2 opcode and a `salt` to deterministically deploy
     * the clone. Using the same `implementation` and `salt` multiple time will revert, since
     * the clones cannot be deployed twice at the same address.
     */
    function cloneDeterministic(address implementation, bytes32 salt)
        internal
        returns (address instance)
    {
        assembly {
            let ptr := mload(0x40)
            mstore(
                ptr,
                0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000
            )
            mstore(add(ptr, 0x14), shl(0x60, implementation))
            mstore(
                add(ptr, 0x28),
                0x5af43d82803e903d91602b57fd5bf30000000000000000000000000000000000
            )
            instance := create2(0, ptr, 0x37, salt)
        }
        require(instance != address(0), "ERC1167: create2 failed");
    }

    /**
     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
     */
    function predictDeterministicAddress(
        address implementation,
        bytes32 salt,
        address deployer
    ) internal pure returns (address predicted) {
        assembly {
            let ptr := mload(0x40)
            mstore(
                ptr,
                0x3d602d80600a3d3981f3363d3d373d3d3d363d73000000000000000000000000
            )
            mstore(add(ptr, 0x14), shl(0x60, implementation))
            mstore(
                add(ptr, 0x28),
                0x5af43d82803e903d91602b57fd5bf3ff00000000000000000000000000000000
            )
            mstore(add(ptr, 0x38), shl(0x60, deployer))
            mstore(add(ptr, 0x4c), salt)
            mstore(add(ptr, 0x6c), keccak256(ptr, 0x37))
            predicted := keccak256(add(ptr, 0x37), 0x55)
        }
    }

    /**
     * @dev Computes the address of a clone deployed using {Clones-cloneDeterministic}.
     */
    function predictDeterministicAddress(address implementation, bytes32 salt)
        internal
        view
        returns (address predicted)
    {
        return predictDeterministicAddress(implementation, salt, address(this));
    }
}

// File @solidity-lib/contracts/libraries/FullMath.sol

// taken from https://medium.com/coinmonks/math-in-solidity-part-3-percents-and-proportions-4db014e080b1
// license is CC-BY-4.0
library FullMath {
    function fullMul(uint256 x, uint256 y)
        internal
        pure
        returns (uint256 l, uint256 h)
    {
        uint256 mm = mulmod(x, y, type(uint256).max);
        l = x * y;
        h = mm - l;
        if (mm < l) h -= 1;
    }

    function fullDiv(
        uint256 l,
        uint256 h,
        uint256 d
    ) private pure returns (uint256) {
        uint256 pow2 = d & (type(uint256).max * d);
        d /= pow2;
        l /= pow2;
        l += h * ((type(uint256).max * pow2) / pow2 + 1);
        uint256 r = 1;
        r *= 2 - d * r;
        return l * r;
    }

    function mulDiv(
        uint256 x,
        uint256 y,
        uint256 d
    ) internal pure returns (uint256) {
        (uint256 l, uint256 h) = fullMul(x, y);

        uint256 mm = mulmod(x, y, d);
        if (mm > l) h -= 1;
        l -= mm;

        if (h == 0) return l / d;

        require(h < d, "FullMath: FULLDIV_OVERFLOW");
        return fullDiv(l, h, d);
    }
}

// File @solidity-lib/contracts/libraries/Babylonian.sol

// computes square roots using the babylonian method
// https://en.wikipedia.org/wiki/Methods_of_computing_square_roots#Babylonian_method
library Babylonian {
    // credit for this implementation goes to
    // https://github.com/abdk-consulting/abdk-libraries-solidity/blob/master/ABDKMath64x64.sol#L687
    function sqrt(uint256 x) internal pure returns (uint256) {
        if (x == 0) return 0;
        // this block is equivalent to r = uint256(1) << (BitMath.mostSignificantBit(x) / 2);
        // however that code costs significantly more gas
        uint256 xx = x;
        uint256 r = 1;
        if (xx >= 0x100000000000000000000000000000000) {
            xx >>= 128;
            r <<= 64;
        }
        if (xx >= 0x10000000000000000) {
            xx >>= 64;
            r <<= 32;
        }
        if (xx >= 0x100000000) {
            xx >>= 32;
            r <<= 16;
        }
        if (xx >= 0x10000) {
            xx >>= 16;
            r <<= 8;
        }
        if (xx >= 0x100) {
            xx >>= 8;
            r <<= 4;
        }
        if (xx >= 0x10) {
            xx >>= 4;
            r <<= 2;
        }
        if (xx >= 0x8) {
            r <<= 1;
        }
        r = (r + x / r) >> 1;
        r = (r + x / r) >> 1; // Seven iterations should be enough
        uint256 r1 = x / r;
        return (r < r1 ? r : r1);
    }
}

// File @solidity-lib/contracts/libraries/BitMath.sol

library BitMath {
    // returns the 0 indexed position of the most significant bit of the input x
    // s.t. x >= 2**msb and x < 2**(msb+1)
    function mostSignificantBit(uint256 x) internal pure returns (uint8 r) {
        require(x > 0, "BitMath::mostSignificantBit: zero");

        if (x >= 0x100000000000000000000000000000000) {
            x >>= 128;
            r += 128;
        }
        if (x >= 0x10000000000000000) {
            x >>= 64;
            r += 64;
        }
        if (x >= 0x100000000) {
            x >>= 32;
            r += 32;
        }
        if (x >= 0x10000) {
            x >>= 16;
            r += 16;
        }
        if (x >= 0x100) {
            x >>= 8;
            r += 8;
        }
        if (x >= 0x10) {
            x >>= 4;
            r += 4;
        }
        if (x >= 0x4) {
            x >>= 2;
            r += 2;
        }
        if (x >= 0x2) r += 1;
    }

    // returns the 0 indexed position of the least significant bit of the input x
    // s.t. (x & 2**lsb) != 0 and (x & (2**(lsb) - 1)) == 0)
    // i.e. the bit at the index is set and the mask of all lower bits is 0
    function leastSignificantBit(uint256 x) internal pure returns (uint8 r) {
        require(x > 0, "BitMath::leastSignificantBit: zero");

        r = 255;
        if (x & type(uint128).max > 0) {
            r -= 128;
        } else {
            x >>= 128;
        }
        if (x & type(uint64).max > 0) {
            r -= 64;
        } else {
            x >>= 64;
        }
        if (x & type(uint32).max > 0) {
            r -= 32;
        } else {
            x >>= 32;
        }
        if (x & type(uint16).max > 0) {
            r -= 16;
        } else {
            x >>= 16;
        }
        if (x & type(uint8).max > 0) {
            r -= 8;
        } else {
            x >>= 8;
        }
        if (x & 0xf > 0) {
            r -= 4;
        } else {
            x >>= 4;
        }
        if (x & 0x3 > 0) {
            r -= 2;
        } else {
            x >>= 2;
        }
        if (x & 0x1 > 0) r -= 1;
    }
}

// File @solidity-lib/contracts/libraries/FixedPoint.sol

// a library for handling binary fixed point numbers (https://en.wikipedia.org/wiki/Q_(number_format))
library FixedPoint {
    // range: [0, 2**112 - 1]
    // resolution: 1 / 2**112
    struct uq112x112 {
        uint224 _x;
    }

    // range: [0, 2**144 - 1]
    // resolution: 1 / 2**112
    struct uq144x112 {
        uint256 _x;
    }

    uint8 public constant RESOLUTION = 112;
    uint256 public constant Q112 = 0x10000000000000000000000000000; // 2**112
    uint256 private constant Q224 =
        0x100000000000000000000000000000000000000000000000000000000; // 2**224
    uint256 private constant LOWER_MASK = 0xffffffffffffffffffffffffffff; // decimal of UQ*x112 (lower 112 bits)

    // encode a uint112 as a UQ112x112
    function encode(uint112 x) internal pure returns (uq112x112 memory) {
        return uq112x112(uint224(x) << RESOLUTION);
    }

    // encodes a uint144 as a UQ144x112
    function encode144(uint144 x) internal pure returns (uq144x112 memory) {
        return uq144x112(uint256(x) << RESOLUTION);
    }

    // decode a UQ112x112 into a uint112 by truncating after the radix point
    function decode(uq112x112 memory self) internal pure returns (uint112) {
        return uint112(self._x >> RESOLUTION);
    }

    function decode112with18(uq112x112 memory self)
        internal
        pure
        returns (uint256)
    {
        return uint256(self._x) / 5192296858534827;
    }

    // decode a UQ144x112 into a uint144 by truncating after the radix point
    function decode144(uq144x112 memory self) internal pure returns (uint144) {
        return uint144(self._x >> RESOLUTION);
    }

    // multiply a UQ112x112 by a uint, returning a UQ144x112
    // reverts on overflow
    function mul(uq112x112 memory self, uint256 y)
        internal
        pure
        returns (uq144x112 memory)
    {
        uint256 z = 0;
        require(
            y == 0 || (z = self._x * y) / y == self._x,
            "FixedPoint::mul: overflow"
        );
        return uq144x112(z);
    }

    // multiply a UQ112x112 by an int and decode, returning an int
    // reverts on overflow
    function muli(uq112x112 memory self, int256 y)
        internal
        pure
        returns (int256)
    {
        uint256 z = FullMath.mulDiv(self._x, uint256(y < 0 ? -y : y), Q112);
        require(z < 2**255, "FixedPoint::muli: overflow");
        return y < 0 ? -int256(z) : int256(z);
    }

    // multiply a UQ112x112 by a UQ112x112, returning a UQ112x112
    // lossy
    function muluq(uq112x112 memory self, uq112x112 memory other)
        internal
        pure
        returns (uq112x112 memory)
    {
        if (self._x == 0 || other._x == 0) {
            return uq112x112(0);
        }
        uint112 upper_self = uint112(self._x >> RESOLUTION); // * 2^0
        uint112 lower_self = uint112(self._x & LOWER_MASK); // * 2^-112
        uint112 upper_other = uint112(other._x >> RESOLUTION); // * 2^0
        uint112 lower_other = uint112(other._x & LOWER_MASK); // * 2^-112

        // partial products
        uint224 upper = uint224(upper_self) * upper_other; // * 2^0
        uint224 lower = uint224(lower_self) * lower_other; // * 2^-224
        uint224 uppers_lowero = uint224(upper_self) * lower_other; // * 2^-112
        uint224 uppero_lowers = uint224(upper_other) * lower_self; // * 2^-112

        // so the bit shift does not overflow
        require(
            upper <= type(uint112).max,
            "FixedPoint::muluq: upper overflow"
        );

        // this cannot exceed 256 bits, all values are 224 bits
        uint256 sum = uint256(upper << RESOLUTION) +
            uppers_lowero +
            uppero_lowers +
            (lower >> RESOLUTION);

        // so the cast does not overflow
        require(sum <= type(uint224).max, "FixedPoint::muluq: sum overflow");

        return uq112x112(uint224(sum));
    }

    // divide a UQ112x112 by a UQ112x112, returning a UQ112x112
    function divuq(uq112x112 memory self, uq112x112 memory other)
        internal
        pure
        returns (uq112x112 memory)
    {
        require(other._x > 0, "FixedPoint::divuq: division by zero");
        if (self._x == other._x) {
            return uq112x112(uint224(Q112));
        }
        if (self._x <= type(uint144).max) {
            uint256 value = (uint256(self._x) << RESOLUTION) / other._x;
            require(value <= type(uint224).max, "FixedPoint::divuq: overflow");
            return uq112x112(uint224(value));
        }

        uint256 result = FullMath.mulDiv(Q112, self._x, other._x);
        require(result <= type(uint224).max, "FixedPoint::divuq: overflow");
        return uq112x112(uint224(result));
    }

    // returns a UQ112x112 which represents the ratio of the numerator to the denominator
    // can be lossy
    function fraction(uint256 numerator, uint256 denominator)
        internal
        pure
        returns (uq112x112 memory)
    {
        require(denominator > 0, "FixedPoint::fraction: division by zero");
        if (numerator == 0) return FixedPoint.uq112x112(0);

        if (numerator <= type(uint144).max) {
            uint256 result = (numerator << RESOLUTION) / denominator;
            require(
                result <= type(uint224).max,
                "FixedPoint::fraction: overflow"
            );
            return uq112x112(uint224(result));
        } else {
            uint256 result = FullMath.mulDiv(numerator, Q112, denominator);
            require(
                result <= type(uint224).max,
                "FixedPoint::fraction: overflow"
            );
            return uq112x112(uint224(result));
        }
    }

    // take the reciprocal of a UQ112x112
    // reverts on overflow
    // lossy
    function reciprocal(uq112x112 memory self)
        internal
        pure
        returns (uq112x112 memory)
    {
        require(self._x != 0, "FixedPoint::reciprocal: reciprocal of zero");
        require(self._x != 1, "FixedPoint::reciprocal: overflow");
        return uq112x112(uint224(Q224 / self._x));
    }

    // square root of a UQ112x112
    // lossy between 0/1 and 40 bits
    function sqrt(uq112x112 memory self)
        internal
        pure
        returns (uq112x112 memory)
    {
        if (self._x <= type(uint144).max) {
            return uq112x112(uint224(Babylonian.sqrt(uint256(self._x) << 112)));
        }

        uint8 safeShiftBits = 255 - BitMath.mostSignificantBit(self._x);
        safeShiftBits -= safeShiftBits % 2;
        return
            uq112x112(
                uint224(
                    Babylonian.sqrt(uint256(self._x) << safeShiftBits) <<
                        ((112 - safeShiftBits) / 2)
                )
            );
    }
}

// File contracts/interfaces/IUniswapV2TWAPOracle.sol

interface IUniswapV2TWAPOracle {
    function PERIOD() external view returns (uint256);

    struct LastValue {
        address token0;
        address token1;
        uint256 price0Cumulative;
        uint256 price1Cumulative;
        uint32 blockTimestamp;
        FixedPoint.uq112x112 price0Average;
        FixedPoint.uq112x112 price1Average;
    }

    function consult(
        address pair,
        address token,
        uint256 amountIn
    ) external view returns (uint256 amountOut);

    function consultCurrent(
        address pair,
        address token,
        uint256 amountIn
    ) external view returns (uint256);

    function lastValue(address pair) external view returns (LastValue memory);

    function update(address pair) external;

    function updateAll() external;
}

// File contracts/interfaces/IPaymentSplitter.sol

interface IPaymentSplitter {
    function initialize() external;

    function initialize(address[] memory payees, uint256[] memory shares_)
        external;

    function addPayee(address payee_, uint256 shares_) external;

    function count() external view returns (uint256);

    function totalShares() external view returns (uint256);

    function totalReleased() external view returns (uint256);

    function totalReleased(address token) external view returns (uint256);

    function shares(address account) external view returns (uint256);

    function released(address account) external view returns (uint256);

    function released(address token, address account)
        external
        view
        returns (uint256);

    function payee(uint256 index) external view returns (address);

    function pending(address account) external view returns (uint256);

    function pending(address token, address account)
        external
        view
        returns (uint256);

    function releaseAll() external;

    function releaseAll(address token) external;

    function release(address account) external;

    function release(address token, address account) external;
}

// File contracts/interfaces/IBlockTimeTracker.sol

interface IBlockTimeTracker {
    function PRECISION() external view returns (uint8);

    function startBlock() external view returns (uint256);

    function startTimestamp() external view returns (uint256);

    function average() external view returns (uint256);

    function reset() external;
}

// File contracts/TimmyNFT/TimmyNFT.sol

contract ERC721Template is
    ERC721Enumerable,
    ERC721Royalty,
    ERC721Pausable,
    AccessControlEnumerable
{
    using SafeERC20 for IERC20;
    using Strings for uint256;
    using Address for address;
    using Clones for address;

    event RoyaltyDeployed(
        address indexed _contract,
        uint256 indexed _tokenId,
        address indexed recipient
    );

    // fee settings
    uint256 public MINTING_FEE = 10 ether;
    uint256 public immutable MAX_TOKENS_PER_MINT = 10;
    uint96 public FTM_PREMIUM = 12500;
    address public immutable TRADING_PAIR =
        address(0xa8DE5367290Ed79658A9f9B9Ae1f633c355f1e1F);
    IERC20 public immutable PAYMENT_TOKEN =
        IERC20(0x6a31Aca4d2f7398F04d9B6ffae2D898d9A8e7938);
    IUniswapV2TWAPOracle public immutable ORACLE =
        IUniswapV2TWAPOracle(0x4B1B9F7ce4C40E9EdC1453F421Cf5CaeC384A085);

    // supply settings
    uint256 public immutable MAX_SUPPLY = 1000;

    // URI settings
    string private BASE_URI;
    string private URI_EXTENSION = ".json";

    // Royalty settings
    address public PAYMENT_SPLITTER =
        address(0xaab3D332F05Af59A3Ada9Df9b7D3CED6EBe6b919);
    IPaymentSplitter public baseRoyaltyReceiver;
    mapping(address => IPaymentSplitter) public knownRoyaltyReceivers;
    mapping(uint256 => address) public tokenRoyaltyReceiver;
    address private immutable deployer;

    // Pauser role ID
    bytes32 public constant PAUSER_ROLE = keccak256("PAUSER_ROLE");
    bytes32 public constant SERVICE_ROLE = keccak256("SERVICE_ROLE");

    // random seed for used in tokenURI generation
    uint256 private immutable RANDOM_SEED;
    // BlockTimeTracker for randomization
    IBlockTimeTracker private constant tracker =
        IBlockTimeTracker(0x706e05D2b47cc6B1fb615EE76DD3789d2329E22e);

    constructor() ERC721("TurtleTurtle.club: The Timmy Collection", "TIMMY") {
        _setupRole(DEFAULT_ADMIN_ROLE, _msgSender());
        _setupRole(PAUSER_ROLE, _msgSender());
        _setupRole(SERVICE_ROLE, _msgSender());
        deployer = _msgSender();

        baseRoyaltyReceiver = IPaymentSplitter(PAYMENT_SPLITTER.clone());
        baseRoyaltyReceiver.initialize();
        baseRoyaltyReceiver.addPayee(_msgSender(), 4);
        baseRoyaltyReceiver.addPayee(address(this), 6);

        RANDOM_SEED = uint256(
            keccak256(
                abi.encodePacked(
                    _msgSender(),
                    block.timestamp,
                    block.number,
                    address(this),
                    tracker.average()
                )
            )
        );

        emit RoyaltyDeployed(address(baseRoyaltyReceiver), 0, address(this));

        _setDefaultRoyalty(
            address(baseRoyaltyReceiver),
            500 // in basis points, 5%
        );

        _pause();
    }

    /****** ROYALTY SETTINGS ******/

    function _constructRoyaltyReceiver(uint256 tokenId, address receiver)
        internal
    {
        if (address(knownRoyaltyReceivers[receiver]) == address(0)) {
            knownRoyaltyReceivers[receiver] = IPaymentSplitter(
                PAYMENT_SPLITTER.clone()
            );
            knownRoyaltyReceivers[receiver].initialize();
            knownRoyaltyReceivers[receiver].addPayee(
                address(baseRoyaltyReceiver),
                1
            );
            knownRoyaltyReceivers[receiver].addPayee(receiver, 1);

            emit RoyaltyDeployed(
                address(knownRoyaltyReceivers[receiver]),
                tokenId,
                receiver
            );
        }

        tokenRoyaltyReceiver[tokenId] = receiver;
    }

    /**
     * @dev Returns the pending royalties due to the original minter of the given token Id
     */
    function pendingRoyalties(uint256 tokenId) public view returns (uint256) {
        if (!_exists(tokenId)) {
            return 0;
        }

        return
            knownRoyaltyReceivers[tokenRoyaltyReceiver[tokenId]].pending(
                tokenRoyaltyReceiver[tokenId]
            );
    }

    /**
     * @dev Returns the pending royalties due to the original minter specified
     */
    function pendingRoyalties(address minter) public view returns (uint256) {
        if (address(knownRoyaltyReceivers[minter]) == address(0)) {
            return 0;
        }

        return knownRoyaltyReceivers[minter].pending(minter);
    }

    /**
     * @dev Pays out any pending royalties due to the specified original minter
     */
    function releaseRoyalties(address minter) public {
        require(
            address(knownRoyaltyReceivers[minter]) != address(0),
            "not an original minter"
        );
        knownRoyaltyReceivers[minter].releaseAll();
    }

    /****** MINT METHODS ******/

    function getFTMQuote() public view returns (uint256) {
        uint256 ftmRate = ORACLE.consultCurrent(
            TRADING_PAIR,
            address(PAYMENT_TOKEN),
            MINTING_FEE
        );

        return (ftmRate * FTM_PREMIUM) / 10000;
    }

    function getFTMQuoteSlippage()
        internal
        view
        returns (uint256 _min, uint256 _max)
    {
        uint256 mintFee = getFTMQuote();
        _min = (mintFee * 9750) / 10000; // allows for -2.5%
        _max = (mintFee * 10250) / 10000; // allows for +2.5%
    }

    function updateOracle() internal {
        ORACLE.update(TRADING_PAIR);
    }

    /**
     * @dev standard mint function that regular users call while
     * paying the appropriate mint fee to mint the ERC721
     */
    function mint() public payable whenNotPaused returns (uint256) {
        (uint256 min, uint256 max) = getFTMQuoteSlippage();
        require(
            msg.value >= min && msg.value <= max,
            "ERC20: caller did not supply correct amount of FTM"
        );

        updateOracle();

        return _mintERC721(_msgSender());
    }

    /**
     * @dev standard mint function that regular users call while
     * paying the appropriate mint fee to mint a number of ERC721s
     */
    function mintCount(uint8 count)
        public
        payable
        whenNotPaused
        returns (uint256[] memory)
    {
        require(
            count <= MAX_TOKENS_PER_MINT,
            "ERC721: must mint less than the maximum count per mint"
        );

        (uint256 min, uint256 max) = getFTMQuoteSlippage();

        require(
            msg.value >= min * count && msg.value <= max * count,
            "ERC20: caller did not supply correct amount of FTM"
        );

        uint256[] memory tokenIds = new uint256[](count);

        for (uint256 i = 0; i < count; i++) {
            tokenIds[i] = _mintERC721(_msgSender());
        }

        updateOracle();

        return tokenIds;
    }

    /**
     * @dev standard mint function that regular users call while
     * paying the appropriate mint fee to mint a ERC721
     */
    function mintWithToken() public whenNotPaused returns (uint256) {
        require(
            PAYMENT_TOKEN.allowance(_msgSender(), address(this)) >= MINTING_FEE,
            "ERC20: caller must provide approval to spend token"
        );

        PAYMENT_TOKEN.safeTransferFrom(
            _msgSender(),
            address(this),
            MINTING_FEE
        );

        return _mintERC721(_msgSender());
    }

    /**
     * @dev standard mint function that regular users call while
     * paying the appropriate mint fee to mint a number of ERC721s
     */
    function mintWithTokenCount(uint256 count)
        public
        whenNotPaused
        returns (uint256[] memory)
    {
        require(
            count <= MAX_TOKENS_PER_MINT,
            "ERC721: must mint less than the maximum count per mint"
        );

        uint256 totalMintingFee = MINTING_FEE * count;

        require(
            PAYMENT_TOKEN.allowance(_msgSender(), address(this)) >=
                totalMintingFee,
            "ERC20: caller must provide approval to spend token"
        );

        PAYMENT_TOKEN.safeTransferFrom(
            _msgSender(),
            address(this),
            totalMintingFee
        );

        uint256[] memory tokenIds = new uint256[](count);

        for (uint256 i = 0; i < count; i++) {
            tokenIds[i] = _mintERC721(_msgSender());
        }

        return tokenIds;
    }

    /**
     * @dev mint process for admins only that allows overriding the
     * requirement for paying for the mint, allows minting while paused,
     * and mints the ERC721 directly to the wallet address specified
     */
    function mintAdmin(address _to)
        public
        virtual
        onlyRole(DEFAULT_ADMIN_ROLE)
        overridePause
        returns (uint256)
    {
        return _mintERC721(_to);
    }

    /**
     * @dev mint process for admins only that allows overriding the
     * requirement for paying for the mint, allows minting while paused,
     * overrides the maximum number of ERC721s per mint, and mints the
     * ERC721 directly to the wallet address specified for the specified count
     */
    function mintAdminCount(address _to, uint256 count)
        public
        onlyRole(DEFAULT_ADMIN_ROLE)
        overridePause
        returns (uint256[] memory)
    {
        uint256[] memory tokenIds = new uint256[](count);

        for (uint256 i = 0; i < count; i++) {
            tokenIds[i] = _mintERC721(_to);
        }

        return tokenIds;
    }

    /**
     * @dev internal mint method that sets up the actual ERC721
     */
    function _mintERC721(address _to) internal virtual returns (uint256) {
        uint256 supply = totalSupply();
        require(supply + 1 <= MAX_SUPPLY, "mint completed");

        uint256 tokenId = supply + 1;

        _constructRoyaltyReceiver(tokenId, _to);

        _safeMint(_to, tokenId);

        _setTokenRoyalty(
            tokenId,
            address(knownRoyaltyReceivers[tokenRoyaltyReceiver[tokenId]]),
            500
        ); // in basis points, 5%

        return tokenId;
    }

    /****** BASIC SETTING METHODS ******/

    function pause() public onlyRole(PAUSER_ROLE) {
        _pause();
    }

    function unpause() public onlyRole(PAUSER_ROLE) {
        _unpause();
    }

    /****** FEE SETTING METHODS ******/

    function setMintFee(uint256 _minting_fee)
        public
        onlyRole(DEFAULT_ADMIN_ROLE)
    {
        MINTING_FEE = _minting_fee;
    }

    function setFTMPremium(uint96 _ftm_premium)
        public
        onlyRole(DEFAULT_ADMIN_ROLE)
    {
        FTM_PREMIUM = _ftm_premium;
    }

    /****** URI SETTINGS ******/

    /**
     * @dev updates the base URI for the token metadata to the provided URI
     */
    function setBaseURI(string memory _base_uri)
        public
        onlyRole(DEFAULT_ADMIN_ROLE)
    {
        BASE_URI = _base_uri;
    }

    /**
     * @dev Generates a masked token URI so that people cannot guess what the next
     * NFT result will be
     */
    function _generateTokenURI(uint256 tokenId)
        internal
        view
        returns (string memory)
    {
        return
            uint256(
                keccak256(
                    abi.encodePacked(RANDOM_SEED.toString(), tokenId.toString())
                )
            ).toHexString(32);
    }

    /**
     * @dev returns the token masked URI for the given token Id
     */
    function tokenMaskedURI(uint256 tokenId)
        public
        view
        onlyRole(SERVICE_ROLE)
        returns (string memory)
    {
        return _generateTokenURI(tokenId);
    }

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

        return
            string(
                abi.encodePacked(
                    BASE_URI,
                    _generateTokenURI(tokenId),
                    URI_EXTENSION
                )
            );
    }

    /****** WITHDRAW METHODS ******/

    /**
     * @dev sends the full balance held by this contract to the caller
     */
    function withdraw() public onlyRole(DEFAULT_ADMIN_ROLE) {
        require(address(this).balance != 0, "contract has no balance");

        IPaymentSplitter splitter = IPaymentSplitter(PAYMENT_SPLITTER.clone());
        splitter.initialize();
        splitter.addPayee(_msgSender(), 90);

        if (_msgSender() != deployer) {
            splitter.addPayee(deployer, 10);
        }

        payable(address(splitter)).transfer(address(this).balance);
        splitter.releaseAll();
    }

    /**
     * @dev sends the full balance of the given token held by this contract to the caller
     */
    function withdraw(IERC20 token) public onlyRole(DEFAULT_ADMIN_ROLE) {
        require(
            token.balanceOf(address(this)) != 0,
            "contract has no balance of token"
        );

        IPaymentSplitter splitter = IPaymentSplitter(PAYMENT_SPLITTER.clone());
        splitter.initialize();
        splitter.addPayee(_msgSender(), 90);

        if (_msgSender() != deployer) {
            splitter.addPayee(deployer, 10);
        }

        token.safeTransfer(address(splitter), token.balanceOf(address(this)));
        splitter.releaseAll(address(token));
    }

    receive() external payable {}

    /****** INTERNAL OVERRIDES ******/

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

    function _afterTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal override {
        if (tokenRoyaltyReceiver[tokenId] != address(0)) {
            knownRoyaltyReceivers[tokenRoyaltyReceiver[tokenId]].releaseAll();
        }

        baseRoyaltyReceiver.releaseAll();

        super._afterTokenTransfer(from, to, tokenId);
    }

    function _burn(uint256 tokenId) internal override(ERC721, ERC721Royalty) {
        super._burn(tokenId);
    }

    function supportsInterface(bytes4 interfaceId)
        public
        view
        virtual
        override(
            AccessControlEnumerable,
            ERC721,
            ERC721Enumerable,
            ERC721Royalty
        )
        returns (bool)
    {
        return super.supportsInterface(interfaceId);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":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":"_contract","type":"address"},{"indexed":true,"internalType":"uint256","name":"_tokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"recipient","type":"address"}],"name":"RoyaltyDeployed","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"DEFAULT_ADMIN_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FTM_PREMIUM","outputs":[{"internalType":"uint96","name":"","type":"uint96"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_TOKENS_PER_MINT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINTING_FEE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"ORACLE","outputs":[{"internalType":"contract IUniswapV2TWAPOracle","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAUSER_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAYMENT_SPLITTER","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PAYMENT_TOKEN","outputs":[{"internalType":"contract IERC20","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"SERVICE_ROLE","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TRADING_PAIR","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseRoyaltyReceiver","outputs":[{"internalType":"contract IPaymentSplitter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getFTMQuote","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":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"knownRoyaltyReceivers","outputs":[{"internalType":"contract IPaymentSplitter","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"}],"name":"mintAdmin","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"count","type":"uint256"}],"name":"mintAdminCount","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint8","name":"count","type":"uint8"}],"name":"mintCount","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintWithToken","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"name":"mintWithTokenCount","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"pendingRoyalties","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"pendingRoyalties","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"minter","type":"address"}],"name":"releaseRoyalties","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"renounceRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"role","type":"bytes32"},{"internalType":"address","name":"account","type":"address"}],"name":"revokeRole","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_base_uri","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint96","name":"_ftm_premium","type":"uint96"}],"name":"setFTMPremium","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minting_fee","type":"uint256"}],"name":"setMintFee","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":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenMaskedURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"tokenRoyaltyReceiver","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

678ac7230489e80000600f55600a608052601080546001600160601b0319166130d417905573a8de5367290ed79658a9f9b9ae1f633c355f1e1f60a052736a31aca4d2f7398f04d9b6ffae2d898d9a8e793860c052734b1b9f7ce4c40e9edc1453f421cf5caec384a08560e0526103e8610100526101a0604052600561016081905264173539b7b760d91b6101809081526200009f916012919062000828565b50601380546001600160a01b03191673aab3d332f05af59a3ada9df9b7d3ced6ebe6b919179055348015620000d357600080fd5b506040518060600160405280602781526020016200690e602791396040518060400160405280600581526020016454494d4d5960d81b81525081600290805190602001906200012492919062000828565b5080516200013a90600390602084019062000828565b5050600c805460ff19169055506200015460003362000470565b620001807f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a3362000470565b620001ac7fd8a7a79547af723ee3e12b59a480111268d8969c634e1a34a144d2c8b91d635b3362000470565b336001600160a01b0390811661012052601354620001d7911662000480602090811b62002df817901c565b601480546001600160a01b0319166001600160a01b039290921691821790556040805163204a7f0760e21b81529051638129fc1c9160048082019260009290919082900301818387803b1580156200022e57600080fd5b505af115801562000243573d6000803e3d6000fd5b50506014546001600160a01b031691506318f9b0239050336040516001600160e01b031960e084901b1681526001600160a01b039091166004828101919091526024820152604401600060405180830381600087803b158015620002a657600080fd5b505af1158015620002bb573d6000803e3d6000fd5b50506014546040516318f9b02360e01b8152306004820152600660248201526001600160a01b0390911692506318f9b0239150604401600060405180830381600087803b1580156200030c57600080fd5b505af115801562000321573d6000803e3d6000fd5b50505050620003356200046c60201b60201c565b42433073706e05d2b47cc6b1fb615ee76dd3789d2329e22e6001600160a01b031663b250717a6040518163ffffffff1660e01b8152600401602060405180830381865afa1580156200038b573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190620003b19190620008ce565b6040516001600160601b0319606096871b8116602083015260348201959095526054810193909352931b9091166074820152608881019190915260a80160408051601f198184030181529082905280516020909101206101405260145430916000916001600160a01b0316907fafa098bd63d0c6b0ddc6f328aba242372f2fe7974da70f45af0745ce98162f5c908390a46014546200045c906001600160a01b03166101f462000533565b6200046662000634565b62000925565b3390565b6200047c8282620006cf565b5050565b60006040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528260601b60148201526e5af43d82803e903d91602b57fd5bf360881b60288201526037816000f09150506001600160a01b0381166200052e5760405162461bcd60e51b815260206004820152601660248201527f455243313136373a20637265617465206661696c65640000000000000000000060448201526064015b60405180910390fd5b919050565b6127106001600160601b0382161115620005a35760405162461bcd60e51b815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c206578636565646044820152692073616c65507269636560b01b606482015260840162000525565b6001600160a01b038216620005fb5760405162461bcd60e51b815260206004820152601960248201527f455243323938313a20696e76616c696420726563656976657200000000000000604482015260640162000525565b604080518082019091526001600160a01b039092168083526001600160601b039091166020909201829052600160a01b90910217600055565b600c5460ff16156200067c5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b604482015260640162000525565b600c805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258620006b23390565b6040516001600160a01b03909116815260200160405180910390a1565b620006e682826200071260201b62002ed51760201c565b6000828152600e602090815260409091206200070d91839062002fc9620007b6821b17901c565b505050565b6000828152600d602090815260408083206001600160a01b038516845290915290205460ff166200047c576000828152600d602090815260408083206001600160a01b03851684529091529020805460ff19166001179055620007723390565b6001600160a01b0316816001600160a01b0316837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b6000620007cd836001600160a01b038416620007d6565b90505b92915050565b60008181526001830160205260408120546200081f57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155620007d0565b506000620007d0565b8280546200083690620008e8565b90600052602060002090601f0160209004810192826200085a5760008555620008a5565b82601f106200087557805160ff1916838001178555620008a5565b82800160010185558215620008a5579182015b82811115620008a557825182559160200191906001019062000888565b50620008b3929150620008b7565b5090565b5b80821115620008b35760008155600101620008b8565b600060208284031215620008e157600080fd5b5051919050565b600181811c90821680620008fd57607f821691505b602082108114156200091f57634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05160c05160e051610100516101205161014051615f25620009e960003960006139b00152600081816119af01528181611a4301528181611ed20152611f660152600081816105ec01526131dc0152600081816106740152818161293101526134440152600081816108120152818161121201528181611377015281816128fc01528181612bcc0152612d18015260008181610a09015281816128d4015261341c0152600081816106200152818161231f0152612af40152615f256000f3fe60806040526004361061037a5760003560e01c80636352211e116101d1578063a5f0292b11610102578063d547741f116100a0578063e6226e5b1161006f578063e6226e5b14610b59578063e63ab1e914610b79578063e985e9c514610bad578063eddd0d9c14610c0357600080fd5b8063d547741f14610aee578063d642b4b114610b0e578063dfef140d14610b24578063e2fb107014610b3957600080fd5b8063c87b56dd116100dc578063c87b56dd14610a4b578063ca15c87314610a6b578063d0888d4414610a8b578063d4ba7d1214610aab57600080fd5b8063a5f0292b146109ca578063b608129c146109f7578063b88d4fde14610a2b57600080fd5b8063938f86af1161016f5780639a2fa9bb116101495780639a2fa9bb14610941578063a20e7d4714610961578063a217fddf14610995578063a22cb465146109aa57600080fd5b8063938f86af146108a757806395d89b41146108ea5780639991f016146108ff57600080fd5b80638456cb59116101ab5780638456cb59146107eb578063877c86fb146108005780639010d07c1461083457806391d148541461085457600080fd5b80636352211e1461079857806370a08231146107b8578063784b1ff0146107d857600080fd5b80632f745c59116102ab5780633f4ba83a116102495780634f6ccce7116102235780634f6ccce71461072057806351cff8d91461074057806355f804b3146107605780635c975abb1461078057600080fd5b80633f4ba83a146106cb57806342842e0e146106e0578063487458511461070057600080fd5b806336568abe1161028557806336568abe1461064257806338013f0214610662578063396478d3146106965780633ccfd60b146106b657600080fd5b80632f745c59146105ba57806332cb6b0c146105da5780633377cd661461060e57600080fd5b80631249c58b1161031857806323b872dd116102f257806323b872dd146104fe578063248a9ca31461051e5780632a55205a1461054e5780632f2ff15d1461059a57600080fd5b80631249c58b146104be578063171be8d0146104d457806318160ddd146104e957600080fd5b8063081812fc11610354578063081812fc1461042f578063095ea7b31461044f5780630e199130146104715780630e24d8e91461049e57600080fd5b806301ffc9a71461038657806305bab821146103bb57806306fdde031461040d57600080fd5b3661038157005b600080fd5b34801561039257600080fd5b506103a66103a136600461563a565b610c23565b60405190151581526020015b60405180910390f35b3480156103c757600080fd5b506014546103e89073ffffffffffffffffffffffffffffffffffffffff1681565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016103b2565b34801561041957600080fd5b50610422610c34565b6040516103b291906156cd565b34801561043b57600080fd5b506103e861044a3660046156e0565b610cc6565b34801561045b57600080fd5b5061046f61046a36600461571b565b610da5565b005b34801561047d57600080fd5b5061049161048c36600461571b565b610f32565b6040516103b29190615747565b3480156104aa57600080fd5b5061046f6104b936600461578b565b611000565b6104c661104b565b6040519081526020016103b2565b3480156104e057600080fd5b506104c6611183565b3480156104f557600080fd5b50600a546104c6565b34801561050a57600080fd5b5061046f6105193660046157b9565b6113ae565b34801561052a57600080fd5b506104c66105393660046156e0565b6000908152600d602052604090206001015490565b34801561055a57600080fd5b5061056e6105693660046157fa565b61144f565b6040805173ffffffffffffffffffffffffffffffffffffffff90931683526020830191909152016103b2565b3480156105a657600080fd5b5061046f6105b536600461581c565b611546565b3480156105c657600080fd5b506104c66105d536600461571b565b61156b565b3480156105e657600080fd5b506104c67f000000000000000000000000000000000000000000000000000000000000000081565b34801561061a57600080fd5b506104c67f000000000000000000000000000000000000000000000000000000000000000081565b34801561064e57600080fd5b5061046f61065d36600461581c565b61163a565b34801561066e57600080fd5b506103e87f000000000000000000000000000000000000000000000000000000000000000081565b3480156106a257600080fd5b5061046f6106b136600461584c565b6116ed565b3480156106c257600080fd5b5061046f61180c565b3480156106d757600080fd5b5061046f611b56565b3480156106ec57600080fd5b5061046f6106fb3660046157b9565b611b8b565b34801561070c57600080fd5b5061042261071b3660046156e0565b611ba6565b34801561072c57600080fd5b506104c661073b3660046156e0565b611be4565b34801561074c57600080fd5b5061046f61075b36600461584c565b611ca2565b34801561076c57600080fd5b5061046f61077b36600461592c565b61210a565b34801561078c57600080fd5b50600c5460ff166103a6565b3480156107a457600080fd5b506103e86107b33660046156e0565b612128565b3480156107c457600080fd5b506104c66107d336600461584c565b6121da565b6104916107e6366004615975565b6122a8565b3480156107f757600080fd5b5061046f612537565b34801561080c57600080fd5b506103e87f000000000000000000000000000000000000000000000000000000000000000081565b34801561084057600080fd5b506103e861084f3660046157fa565b612569565b34801561086057600080fd5b506103a661086f36600461581c565b6000918252600d6020908152604080842073ffffffffffffffffffffffffffffffffffffffff93909316845291905290205460ff1690565b3480156108b357600080fd5b506103e86108c236600461584c565b60156020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b3480156108f657600080fd5b50610422612588565b34801561090b57600080fd5b50601054610924906bffffffffffffffffffffffff1681565b6040516bffffffffffffffffffffffff90911681526020016103b2565b34801561094d57600080fd5b506104c661095c36600461584c565b612597565b34801561096d57600080fd5b506104c67fd8a7a79547af723ee3e12b59a480111268d8969c634e1a34a144d2c8b91d635b81565b3480156109a157600080fd5b506104c6600081565b3480156109b657600080fd5b5061046f6109c53660046159a6565b612672565b3480156109d657600080fd5b506013546103e89073ffffffffffffffffffffffffffffffffffffffff1681565b348015610a0357600080fd5b506103e87f000000000000000000000000000000000000000000000000000000000000000081565b348015610a3757600080fd5b5061046f610a463660046159d4565b61267d565b348015610a5757600080fd5b50610422610a663660046156e0565b612725565b348015610a7757600080fd5b506104c6610a863660046156e0565b61280e565b348015610a9757600080fd5b506104c6610aa636600461584c565b612825565b348015610ab757600080fd5b506103e8610ac63660046156e0565b60166020526000908152604090205473ffffffffffffffffffffffffffffffffffffffff1681565b348015610afa57600080fd5b5061046f610b0936600461581c565b61286f565b348015610b1a57600080fd5b506104c6600f5481565b348015610b3057600080fd5b506104c6612894565b348015610b4557600080fd5b506104c6610b543660046156e0565b6129d0565b348015610b6557600080fd5b50610491610b743660046156e0565b612a7d565b348015610b8557600080fd5b506104c67f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a81565b348015610bb957600080fd5b506103a6610bc8366004615a54565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260076020908152604080832093909416825291909152205460ff1690565b348015610c0f57600080fd5b5061046f610c1e3660046156e0565b612de7565b6000610c2e82612feb565b92915050565b606060028054610c4390615a82565b80601f0160208091040260200160405190810160405280929190818152602001828054610c6f90615a82565b8015610cbc5780601f10610c9157610100808354040283529160200191610cbc565b820191906000526020600020905b815481529060010190602001808311610c9f57829003601f168201915b5050505050905090565b60008181526004602052604081205473ffffffffffffffffffffffffffffffffffffffff16610d7c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5060009081526006602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b6000610db082612128565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610e6e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f72000000000000000000000000000000000000000000000000000000000000006064820152608401610d73565b3373ffffffffffffffffffffffffffffffffffffffff82161480610e975750610e978133610bc8565b610f23576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610d73565b610f2d8383613041565b505050565b60606000610f3f816130e1565b6000610f4d600c5460ff1690565b90508015610f5d57610f5d6130eb565b60008467ffffffffffffffff811115610f7857610f78615869565b604051908082528060200260200182016040528015610fa1578160200160208202803683370190505b50905060005b85811015610fe757610fb8876131cc565b828281518110610fca57610fca615ad0565b602090810291909101015280610fdf81615b2e565b915050610fa7565b5092508015610ff857610ff86132d5565b505092915050565b600061100b816130e1565b50601080547fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166bffffffffffffffffffffffff92909216919091179055565b6000611059600c5460ff1690565b156110c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610d73565b6000806110cb613395565b915091508134101580156110df5750803411155b61116b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f45524332303a2063616c6c657220646964206e6f7420737570706c7920636f7260448201527f7265637420616d6f756e74206f662046544d00000000000000000000000000006064820152608401610d73565b6111736133df565b61117c336131cc565b9250505090565b6000611191600c5460ff1690565b156111f8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610d73565b600f5473ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663dd62ed3e336040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152306024820152604401602060405180830381865afa1580156112a7573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906112cb9190615b67565b1015611359576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f45524332303a2063616c6c6572206d7573742070726f7669646520617070726f60448201527f76616c20746f207370656e6420746f6b656e00000000000000000000000000006064820152608401610d73565b6113a033600f5473ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000169190309061349c565b6113a9336131cc565b905090565b6113b83382613578565b611444576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f7665640000000000000000000000000000006064820152608401610d73565b610f2d8383836136e8565b600082815260016020908152604080832081518083019092525473ffffffffffffffffffffffffffffffffffffffff8116808352740100000000000000000000000000000000000000009091046bffffffffffffffffffffffff1692820192909252829161150a57506040805180820190915260005473ffffffffffffffffffffffffffffffffffffffff811682527401000000000000000000000000000000000000000090046bffffffffffffffffffffffff1660208201525b60208101516000906127109061152e906bffffffffffffffffffffffff1687615b80565b6115389190615bec565b915196919550909350505050565b6000828152600d6020526040902060010154611561816130e1565b610f2d8383613960565b6000611576836121da565b8210611604576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e64730000000000000000000000000000000000000000006064820152608401610d73565b5073ffffffffffffffffffffffffffffffffffffffff919091166000908152600860209081526040808320938352929052205490565b73ffffffffffffffffffffffffffffffffffffffff811633146116df576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f416363657373436f6e74726f6c3a2063616e206f6e6c792072656e6f756e636560448201527f20726f6c657320666f722073656c6600000000000000000000000000000000006064820152608401610d73565b6116e98282613982565b5050565b73ffffffffffffffffffffffffffffffffffffffff8181166000908152601560205260409020541661177b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f6e6f7420616e206f726967696e616c206d696e746572000000000000000000006044820152606401610d73565b73ffffffffffffffffffffffffffffffffffffffff8082166000908152601560205260408082205481517f5be7fde80000000000000000000000000000000000000000000000000000000081529151931692635be7fde89260048084019391929182900301818387803b1580156117f157600080fd5b505af1158015611805573d6000803e3d6000fd5b5050505050565b6000611817816130e1565b4761187e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601760248201527f636f6e747261637420686173206e6f2062616c616e63650000000000000000006044820152606401610d73565b6013546000906118a39073ffffffffffffffffffffffffffffffffffffffff16612df8565b90508073ffffffffffffffffffffffffffffffffffffffff16638129fc1c6040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156118ed57600080fd5b505af1158015611901573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff166318f9b0236119283390565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152605a6024820152604401600060405180830381600087803b15801561199557600080fd5b505af11580156119a9573d6000803e3d6000fd5b505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff166119eb3390565b73ffffffffffffffffffffffffffffffffffffffff1614611aaf576040517f18f9b02300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166004830152600a60248301528216906318f9b02390604401600060405180830381600087803b158015611a9657600080fd5b505af1158015611aaa573d6000803e3d6000fd5b505050505b60405173ffffffffffffffffffffffffffffffffffffffff8216904780156108fc02916000818181858888f19350505050158015611af1573d6000803e3d6000fd5b508073ffffffffffffffffffffffffffffffffffffffff16635be7fde86040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611b3a57600080fd5b505af1158015611b4e573d6000803e3d6000fd5b505050505050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a611b80816130e1565b611b886130eb565b50565b610f2d8383836040518060200160405280600081525061267d565b60607fd8a7a79547af723ee3e12b59a480111268d8969c634e1a34a144d2c8b91d635b611bd2816130e1565b611bdb836139a4565b91505b50919050565b6000611bef600a5490565b8210611c7d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e647300000000000000000000000000000000000000006064820152608401610d73565b600a8281548110611c9057611c90615ad0565b90600052602060002001549050919050565b6000611cad816130e1565b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015273ffffffffffffffffffffffffffffffffffffffff8316906370a0823190602401602060405180830381865afa158015611d17573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611d3b9190615b67565b611da1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f636f6e747261637420686173206e6f2062616c616e6365206f6620746f6b656e6044820152606401610d73565b601354600090611dc69073ffffffffffffffffffffffffffffffffffffffff16612df8565b90508073ffffffffffffffffffffffffffffffffffffffff16638129fc1c6040518163ffffffff1660e01b8152600401600060405180830381600087803b158015611e1057600080fd5b505af1158015611e24573d6000803e3d6000fd5b505050508073ffffffffffffffffffffffffffffffffffffffff166318f9b023611e4b3390565b6040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152605a6024820152604401600060405180830381600087803b158015611eb857600080fd5b505af1158015611ecc573d6000803e3d6000fd5b505050507f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff16611f0e3390565b73ffffffffffffffffffffffffffffffffffffffff1614611fd2576040517f18f9b02300000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f000000000000000000000000000000000000000000000000000000000000000081166004830152600a60248301528216906318f9b02390604401600060405180830381600087803b158015611fb957600080fd5b505af1158015611fcd573d6000803e3d6000fd5b505050505b6040517f70a0823100000000000000000000000000000000000000000000000000000000815230600482015261208490829073ffffffffffffffffffffffffffffffffffffffff8616906370a0823190602401602060405180830381865afa158015612042573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906120669190615b67565b73ffffffffffffffffffffffffffffffffffffffff86169190613a2a565b6040517f580fc80a00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff848116600483015282169063580fc80a90602401600060405180830381600087803b1580156120ed57600080fd5b505af1158015612101573d6000803e3d6000fd5b50505050505050565b6000612115816130e1565b8151610f2d906011906020850190615573565b60008181526004602052604081205473ffffffffffffffffffffffffffffffffffffffff1680610c2e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e00000000000000000000000000000000000000000000006064820152608401610d73565b600073ffffffffffffffffffffffffffffffffffffffff821661227f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f2061646472657373000000000000000000000000000000000000000000006064820152608401610d73565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526005602052604090205490565b60606122b6600c5460ff1690565b1561231d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610d73565b7f00000000000000000000000000000000000000000000000000000000000000008260ff1611156123d0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4552433732313a206d757374206d696e74206c657373207468616e207468652060448201527f6d6178696d756d20636f756e7420706572206d696e74000000000000000000006064820152608401610d73565b6000806123db613395565b90925090506123ed60ff851683615b80565b3410158015612408575061240460ff851682615b80565b3411155b612494576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f45524332303a2063616c6c657220646964206e6f7420737570706c7920636f7260448201527f7265637420616d6f756e74206f662046544d00000000000000000000000000006064820152608401610d73565b60008460ff1667ffffffffffffffff8111156124b2576124b2615869565b6040519080825280602002602001820160405280156124db578160200160208202803683370190505b50905060005b8560ff16811015612524576124f5336131cc565b82828151811061250757612507615ad0565b60209081029190910101528061251c81615b2e565b9150506124e1565b5061252d6133df565b925050505b919050565b7f65d7a28e3265b37a6474929f336521b332c1681b933f6cb9f3376673440d862a612561816130e1565b611b886132d5565b6000828152600e602052604081206125819083613a80565b9392505050565b606060038054610c4390615a82565b73ffffffffffffffffffffffffffffffffffffffff8181166000908152601560205260408120549091166125cd57506000919050565b73ffffffffffffffffffffffffffffffffffffffff828116600081815260156020526040908190205490517f5eebea20000000000000000000000000000000000000000000000000000000008152600481019290925290911690635eebea20906024015b602060405180830381865afa15801561264e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2e9190615b67565b6116e9338383613a8c565b6126873383613578565b612713576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f7665640000000000000000000000000000006064820152608401610d73565b61271f84848484613bba565b50505050565b60008181526004602052604090205460609073ffffffffffffffffffffffffffffffffffffffff166127d9576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201527f6e6578697374656e7420746f6b656e00000000000000000000000000000000006064820152608401610d73565b60116127e4836139a4565b60126040516020016127f893929190615cd1565b6040516020818303038152906040529050919050565b6000818152600e60205260408120610c2e90613c5d565b600080612831816130e1565b600061283f600c5460ff1690565b9050801561284f5761284f6130eb565b612858846131cc565b92508015612868576128686132d5565b5050919050565b6000828152600d602052604090206001015461288a816130e1565b610f2d8383613982565b600f546040517ffd5cb07d00000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301527f000000000000000000000000000000000000000000000000000000000000000081166024830152604482019290925260009182917f00000000000000000000000000000000000000000000000000000000000000009091169063fd5cb07d90606401602060405180830381865afa15801561297a573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061299e9190615b67565b601054909150612710906129c0906bffffffffffffffffffffffff1683615b80565b6129ca9190615bec565b91505090565b60008181526004602052604081205473ffffffffffffffffffffffffffffffffffffffff16612a0157506000919050565b60008281526016602081815260408084205473ffffffffffffffffffffffffffffffffffffffff90811680865260158452828620549588905293909252517f5eebea2000000000000000000000000000000000000000000000000000000000815260048101929092529190911690635eebea2090602401612631565b6060612a8b600c5460ff1690565b15612af2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610d73565b7f0000000000000000000000000000000000000000000000000000000000000000821115612ba2576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603660248201527f4552433732313a206d757374206d696e74206c657373207468616e207468652060448201527f6d6178696d756d20636f756e7420706572206d696e74000000000000000000006064820152608401610d73565b600082600f54612bb29190615b80565b90508073ffffffffffffffffffffffffffffffffffffffff7f00000000000000000000000000000000000000000000000000000000000000001663dd62ed3e336040517fffffffff0000000000000000000000000000000000000000000000000000000060e084901b16815273ffffffffffffffffffffffffffffffffffffffff9091166004820152306024820152604401602060405180830381865afa158015612c61573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190612c859190615b67565b1015612d13576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f45524332303a2063616c6c6572206d7573742070726f7669646520617070726f60448201527f76616c20746f207370656e6420746f6b656e00000000000000000000000000006064820152608401610d73565b612d557f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff1633308461349c565b60008367ffffffffffffffff811115612d7057612d70615869565b604051908082528060200260200182016040528015612d99578160200160208202803683370190505b50905060005b84811015612ddf57612db0336131cc565b828281518110612dc257612dc2615ad0565b602090810291909101015280612dd781615b2e565b915050612d9f565b509392505050565b6000612df2816130e1565b50600f55565b60006040517f3d602d80600a3d3981f3363d3d373d3d3d363d7300000000000000000000000081528260601b60148201527f5af43d82803e903d91602b57fd5bf3000000000000000000000000000000000060288201526037816000f091505073ffffffffffffffffffffffffffffffffffffffff8116612532576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601660248201527f455243313136373a20637265617465206661696c6564000000000000000000006044820152606401610d73565b6000828152600d6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166116e9576000828152600d6020908152604080832073ffffffffffffffffffffffffffffffffffffffff85168452909152902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00166001179055612f6b3390565b73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16837f2f8788117e7eff1d82e926ec794901d17c78024a50270940304540a733656f0d60405160405180910390a45050565b60006125818373ffffffffffffffffffffffffffffffffffffffff8416613c67565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f5a05180f000000000000000000000000000000000000000000000000000000001480610c2e5750610c2e82613cb6565b600081815260066020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416908117909155819061309b82612128565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b611b888133613d0c565b600c5460ff16613157576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f5061757361626c653a206e6f74207061757365640000000000000000000000006044820152606401610d73565b600c80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b60405173ffffffffffffffffffffffffffffffffffffffff909116815260200160405180910390a1565b6000806131d8600a5490565b90507f0000000000000000000000000000000000000000000000000000000000000000613206826001615cf9565b111561326e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f6d696e7420636f6d706c657465640000000000000000000000000000000000006044820152606401610d73565b600061327b826001615cf9565b90506132878185613dde565b61329184826140c6565b60008181526016602090815260408083205473ffffffffffffffffffffffffffffffffffffffff9081168452601590925290912054612581918391166101f46140e0565b600c5460ff1615613342576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601060248201527f5061757361626c653a20706175736564000000000000000000000000000000006044820152606401610d73565b600c80547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a2586131a23390565b60008060006133a2612894565b90506127106133b382612616615b80565b6133bd9190615bec565b92506127106133ce8261280a615b80565b6133d89190615bec565b9150509091565b6040517f1c1b877200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff7f0000000000000000000000000000000000000000000000000000000000000000811660048301527f00000000000000000000000000000000000000000000000000000000000000001690631c1b877290602401600060405180830381600087803b15801561348857600080fd5b505af115801561271f573d6000803e3d6000fd5b60405173ffffffffffffffffffffffffffffffffffffffff8085166024830152831660448201526064810182905261271f9085907f23b872dd00000000000000000000000000000000000000000000000000000000906084015b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190526020810180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff167fffffffff000000000000000000000000000000000000000000000000000000009093169290921790915261426a565b60008181526004602052604081205473ffffffffffffffffffffffffffffffffffffffff16613629576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e00000000000000000000000000000000000000006064820152608401610d73565b600061363483612128565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806136a357508373ffffffffffffffffffffffffffffffffffffffff1661368b84610cc6565b73ffffffffffffffffffffffffffffffffffffffff16145b806136e0575073ffffffffffffffffffffffffffffffffffffffff80821660009081526007602090815260408083209388168352929052205460ff165b949350505050565b8273ffffffffffffffffffffffffffffffffffffffff1661370882612128565b73ffffffffffffffffffffffffffffffffffffffff16146137ab576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201527f6f776e65720000000000000000000000000000000000000000000000000000006064820152608401610d73565b73ffffffffffffffffffffffffffffffffffffffff821661384d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f72657373000000000000000000000000000000000000000000000000000000006064820152608401610d73565b613858838383614376565b613863600082613041565b73ffffffffffffffffffffffffffffffffffffffff83166000908152600560205260408120805460019290613899908490615d11565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526005602052604081208054600192906138d4908490615cf9565b909155505060008181526004602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4610f2d838383614381565b61396a8282612ed5565b6000828152600e60205260409020610f2d9082612fc9565b61398c82826144ae565b6000828152600e60205260409020610f2d9082614569565b6060610c2e60206139d47f000000000000000000000000000000000000000000000000000000000000000061458b565b6139dd8561458b565b6040516020016139ee929190615d28565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe08184030181529190528051602090910120906146bd565b60405173ffffffffffffffffffffffffffffffffffffffff8316602482015260448101829052610f2d9084907fa9059cbb00000000000000000000000000000000000000000000000000000000906064016134f6565b60006125818383614900565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415613b22576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610d73565b73ffffffffffffffffffffffffffffffffffffffff83811660008181526007602090815260408083209487168084529482529182902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b613bc58484846136e8565b613bd18484848461492a565b61271f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610d73565b6000610c2e825490565b6000818152600183016020526040812054613cae57508154600181810184556000848152602080822090930184905584548482528286019093526040902091909155610c2e565b506000610c2e565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f7965db0b000000000000000000000000000000000000000000000000000000001480610c2e5750610c2e82614b1a565b6000828152600d6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff166116e957613d648173ffffffffffffffffffffffffffffffffffffffff1660146146bd565b613d6f8360206146bd565b604051602001613d80929190615d57565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152908290527f08c379a0000000000000000000000000000000000000000000000000000000008252610d73916004016156cd565b73ffffffffffffffffffffffffffffffffffffffff8181166000908152601560205260409020541661407357601354613e2c9073ffffffffffffffffffffffffffffffffffffffff16612df8565b73ffffffffffffffffffffffffffffffffffffffff82811660009081526015602052604080822080547fffffffffffffffffffffffff0000000000000000000000000000000000000000169490931693841790925581517f8129fc1c0000000000000000000000000000000000000000000000000000000081529151638129fc1c92600480820193929182900301818387803b158015613ecb57600080fd5b505af1158015613edf573d6000803e3d6000fd5b5050505073ffffffffffffffffffffffffffffffffffffffff818116600090815260156020526040908190205460145491517f18f9b023000000000000000000000000000000000000000000000000000000008152918316600483015260016024830152909116906318f9b02390604401600060405180830381600087803b158015613f6a57600080fd5b505af1158015613f7e573d6000803e3d6000fd5b5050505073ffffffffffffffffffffffffffffffffffffffff818116600081815260156020526040908190205490517f18f9b023000000000000000000000000000000000000000000000000000000008152600481019290925260016024830152909116906318f9b02390604401600060405180830381600087803b15801561400657600080fd5b505af115801561401a573d6000803e3d6000fd5b50505073ffffffffffffffffffffffffffffffffffffffff808316600081815260156020526040808220549051929450869316917fafa098bd63d0c6b0ddc6f328aba242372f2fe7974da70f45af0745ce98162f5c9190a45b60009182526016602052604090912080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff909216919091179055565b6116e9828260405180602001604052806000815250614b25565b6127106bffffffffffffffffffffffff82161115614180576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f455243323938313a20726f79616c7479206665652077696c6c2065786365656460448201527f2073616c655072696365000000000000000000000000000000000000000000006064820152608401610d73565b73ffffffffffffffffffffffffffffffffffffffff82166141fd576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601b60248201527f455243323938313a20496e76616c696420706172616d657465727300000000006044820152606401610d73565b60408051808201825273ffffffffffffffffffffffffffffffffffffffff93841681526bffffffffffffffffffffffff9283166020808301918252600096875260019052919094209351905190911674010000000000000000000000000000000000000000029116179055565b60006142cc826040518060400160405280602081526020017f5361666545524332303a206c6f772d6c6576656c2063616c6c206661696c65648152508573ffffffffffffffffffffffffffffffffffffffff16614bc89092919063ffffffff16565b805190915015610f2d57808060200190518101906142ea9190615dd8565b610f2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f5361666545524332303a204552433230206f7065726174696f6e20646964206e60448201527f6f742073756363656564000000000000000000000000000000000000000000006064820152608401610d73565b610f2d838383614bd7565b60008181526016602052604090205473ffffffffffffffffffffffffffffffffffffffff16156144445760008181526016602090815260408083205473ffffffffffffffffffffffffffffffffffffffff908116845260159092528083205481517f5be7fde80000000000000000000000000000000000000000000000000000000081529151921692635be7fde89260048084019382900301818387803b15801561442b57600080fd5b505af115801561443f573d6000803e3d6000fd5b505050505b601460009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16635be7fde86040518163ffffffff1660e01b8152600401600060405180830381600087803b1580156120ed57600080fd5b6000828152600d6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516845290915290205460ff16156116e9576000828152600d6020908152604080832073ffffffffffffffffffffffffffffffffffffffff8516808552925280832080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016905551339285917ff6391f5c32d9c69d2a47ea670b442974b53935d1edc7fd64eb21e047a839171b9190a45050565b60006125818373ffffffffffffffffffffffffffffffffffffffff8416614c75565b6060816145cb57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156145f557806145df81615b2e565b91506145ee9050600a83615bec565b91506145cf565b60008167ffffffffffffffff81111561461057614610615869565b6040519080825280601f01601f19166020018201604052801561463a576020820181803683370190505b5090505b841561252d5761464f600183615d11565b915061465c600a86615df5565b614667906030615cf9565b60f81b81838151811061467c5761467c615ad0565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506146b6600a86615bec565b945061463e565b606060006146cc836002615b80565b6146d7906002615cf9565b67ffffffffffffffff8111156146ef576146ef615869565b6040519080825280601f01601f191660200182016040528015614719576020820181803683370190505b5090507f30000000000000000000000000000000000000000000000000000000000000008160008151811061475057614750615ad0565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053507f7800000000000000000000000000000000000000000000000000000000000000816001815181106147b3576147b3615ad0565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060006147ef846002615b80565b6147fa906001615cf9565b90505b6001811115614897577f303132333435363738396162636465660000000000000000000000000000000085600f166010811061483b5761483b615ad0565b1a60f81b82828151811061485157614851615ad0565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535060049490941c9361489081615e09565b90506147fd565b508315612581576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f537472696e67733a20686578206c656e67746820696e73756666696369656e746044820152606401610d73565b600082600001828154811061491757614917615ad0565b9060005260206000200154905092915050565b600073ffffffffffffffffffffffffffffffffffffffff84163b15614b0f576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063150b7a02906149a1903390899088908890600401615e3e565b6020604051808303816000875af19250505080156149fa575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526149f791810190615e87565b60015b614ac4573d808015614a28576040519150601f19603f3d011682016040523d82523d6000602084013e614a2d565b606091505b508051614abc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610d73565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a02000000000000000000000000000000000000000000000000000000001490506136e0565b506001949350505050565b6000610c2e82614d68565b614b2f8383614dbe565b614b3c600084848461492a565b610f2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e74657200000000000000000000000000006064820152608401610d73565b60606136e08484600085614f94565b614be283838361512a565b600c5460ff1615610f2d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f4552433732315061757361626c653a20746f6b656e207472616e73666572207760448201527f68696c65207061757365640000000000000000000000000000000000000000006064820152608401610d73565b60008181526001830160205260408120548015614d5e576000614c99600183615d11565b8554909150600090614cad90600190615d11565b9050818114614d12576000866000018281548110614ccd57614ccd615ad0565b9060005260206000200154905080876000018481548110614cf057614cf0615ad0565b6000918252602080832090910192909255918252600188019052604090208390555b8554869080614d2357614d23615ea4565b600190038181906000526020600020016000905590558560010160008681526020019081526020016000206000905560019350505050610c2e565b6000915050610c2e565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f780e9d63000000000000000000000000000000000000000000000000000000001480610c2e5750610c2e82615230565b73ffffffffffffffffffffffffffffffffffffffff8216614e3b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610d73565b60008181526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1615614ec7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610d73565b614ed360008383614376565b73ffffffffffffffffffffffffffffffffffffffff82166000908152600560205260408120805460019290614f09908490615cf9565b909155505060008181526004602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a46116e960008383614381565b606082471015615026576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f416464726573733a20696e73756666696369656e742062616c616e636520666f60448201527f722063616c6c00000000000000000000000000000000000000000000000000006064820152608401610d73565b73ffffffffffffffffffffffffffffffffffffffff85163b6150a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601d60248201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e74726163740000006044820152606401610d73565b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516150cd9190615ed3565b60006040518083038185875af1925050503d806000811461510a576040519150601f19603f3d011682016040523d82523d6000602084013e61510f565b606091505b509150915061511f8282866152d2565b979650505050505050565b73ffffffffffffffffffffffffffffffffffffffff83166151925761518d81600a80546000838152600b60205260408120829055600182018355919091527fc65a7bb8d6351c1cf70c95a316cc6a92839c986682d98bc35f958f4883f9d2a80155565b6151cf565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146151cf576151cf8382615325565b73ffffffffffffffffffffffffffffffffffffffff82166151f357610f2d816153dc565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614610f2d57610f2d828261548b565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd0000000000000000000000000000000000000000000000000000000014806152c357507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b80610c2e5750610c2e826154dc565b606083156152e1575081612581565b8251156152f15782518084602001fd5b816040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7391906156cd565b60006001615332846121da565b61533c9190615d11565b60008381526009602052604090205490915080821461539c5773ffffffffffffffffffffffffffffffffffffffff841660009081526008602090815260408083208584528252808320548484528184208190558352600990915290208190555b50600091825260096020908152604080842084905573ffffffffffffffffffffffffffffffffffffffff9094168352600881528383209183525290812055565b600a546000906153ee90600190615d11565b6000838152600b6020526040812054600a805493945090928490811061541657615416615ad0565b9060005260206000200154905080600a838154811061543757615437615ad0565b6000918252602080832090910192909255828152600b9091526040808220849055858252812055600a80548061546f5761546f615ea4565b6001900381819060005260206000200160009055905550505050565b6000615496836121da565b73ffffffffffffffffffffffffffffffffffffffff9093166000908152600860209081526040808320868452825280832085905593825260099052919091209190915550565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f2a55205a000000000000000000000000000000000000000000000000000000001480610c2e57507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610c2e565b82805461557f90615a82565b90600052602060002090601f0160209004810192826155a157600085556155e7565b82601f106155ba57805160ff19168380011785556155e7565b828001600101855582156155e7579182015b828111156155e75782518255916020019190600101906155cc565b506155f39291506155f7565b5090565b5b808211156155f357600081556001016155f8565b7fffffffff0000000000000000000000000000000000000000000000000000000081168114611b8857600080fd5b60006020828403121561564c57600080fd5b81356125818161560c565b60005b8381101561567257818101518382015260200161565a565b8381111561271f5750506000910152565b6000815180845261569b816020860160208601615657565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b6020815260006125816020830184615683565b6000602082840312156156f257600080fd5b5035919050565b73ffffffffffffffffffffffffffffffffffffffff81168114611b8857600080fd5b6000806040838503121561572e57600080fd5b8235615739816156f9565b946020939093013593505050565b6020808252825182820181905260009190848201906040850190845b8181101561577f57835183529284019291840191600101615763565b50909695505050505050565b60006020828403121561579d57600080fd5b81356bffffffffffffffffffffffff8116811461258157600080fd5b6000806000606084860312156157ce57600080fd5b83356157d9816156f9565b925060208401356157e9816156f9565b929592945050506040919091013590565b6000806040838503121561580d57600080fd5b50508035926020909101359150565b6000806040838503121561582f57600080fd5b823591506020830135615841816156f9565b809150509250929050565b60006020828403121561585e57600080fd5b8135612581816156f9565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600067ffffffffffffffff808411156158b3576158b3615869565b604051601f85017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0908116603f011681019082821181831017156158f9576158f9615869565b8160405280935085815286868601111561591257600080fd5b858560208301376000602087830101525050509392505050565b60006020828403121561593e57600080fd5b813567ffffffffffffffff81111561595557600080fd5b8201601f8101841361596657600080fd5b6136e084823560208401615898565b60006020828403121561598757600080fd5b813560ff8116811461258157600080fd5b8015158114611b8857600080fd5b600080604083850312156159b957600080fd5b82356159c4816156f9565b9150602083013561584181615998565b600080600080608085870312156159ea57600080fd5b84356159f5816156f9565b93506020850135615a05816156f9565b925060408501359150606085013567ffffffffffffffff811115615a2857600080fd5b8501601f81018713615a3957600080fd5b615a4887823560208401615898565b91505092959194509250565b60008060408385031215615a6757600080fd5b8235615a72816156f9565b91506020830135615841816156f9565b600181811c90821680615a9657607f821691505b60208210811415611bde577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415615b6057615b60615aff565b5060010190565b600060208284031215615b7957600080fd5b5051919050565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615bb857615bb8615aff565b500290565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600082615bfb57615bfb615bbd565b500490565b8054600090600181811c9080831680615c1a57607f831692505b6020808410821415615c55577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b818015615c695760018114615c9857615cc5565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00861689528489019650615cc5565b60008881526020902060005b86811015615cbd5781548b820152908501908301615ca4565b505084890196505b50505050505092915050565b6000615cdd8286615c00565b8451615ced818360208901615657565b61511f81830186615c00565b60008219821115615d0c57615d0c615aff565b500190565b600082821015615d2357615d23615aff565b500390565b60008351615d3a818460208801615657565b835190830190615d4e818360208801615657565b01949350505050565b7f416363657373436f6e74726f6c3a206163636f756e7420000000000000000000815260008351615d8f816017850160208801615657565b7f206973206d697373696e6720726f6c65200000000000000000000000000000006017918401918201528351615dcc816028840160208801615657565b01602801949350505050565b600060208284031215615dea57600080fd5b815161258181615998565b600082615e0457615e04615bbd565b500690565b600081615e1857615e18615aff565b507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0190565b600073ffffffffffffffffffffffffffffffffffffffff808716835280861660208401525083604083015260806060830152615e7d6080830184615683565b9695505050505050565b600060208284031215615e9957600080fd5b81516125818161560c565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60008251615ee5818460208701615657565b919091019291505056fea26469706673582212208d2e5667d706f0318413a45098f3f617b56728a8b5ceb6eb2023c85f6f56ba6264736f6c634300080b0033547572746c65547572746c652e636c75623a205468652054696d6d7920436f6c6c656374696f6e

Deployed ByteCode Sourcemap

109057:14998:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;123720:332;;;;;;;;;;-1:-1:-1;123720:332:0;;;;;:::i;:::-;;:::i;:::-;;;611:14:1;;604:22;586:41;;574:2;559:18;123720:332:0;;;;;;;;110261:43;;;;;;;;;;-1:-1:-1;110261:43:0;;;;;;;;;;;839:42:1;827:55;;;809:74;;797:2;782:18;110261:43:0;638:251:1;30644:100:0;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;32338:308::-;;;;;;;;;;-1:-1:-1;32338:308:0;;;;;:::i;:::-;;:::i;31861:411::-;;;;;;;;;;-1:-1:-1;31861:411:0;;;;;:::i;:::-;;:::i;:::-;;118395:370;;;;;;;;;;-1:-1:-1;118395:370:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;119787:148::-;;;;;;;;;;-1:-1:-1;119787:148:0;;;;;:::i;:::-;;:::i;114772:351::-;;;:::i;:::-;;;3679:25:1;;;3667:2;3652:18;114772:351:0;3533:177:1;116170:430:0;;;;;;;;;;;;;:::i;53254:113::-;;;;;;;;;;-1:-1:-1;53342:10:0;:17;53254:113;;33257:376;;;;;;;;;;-1:-1:-1;33257:376:0;;;;;:::i;:::-;;:::i;71270:181::-;;;;;;;;;;-1:-1:-1;71270:181:0;;;;;:::i;:::-;71389:7;71421:12;;;:6;:12;;;;;:22;;;;71270:181;46204:507;;;;;;;;;;-1:-1:-1;46204:507:0;;;;;:::i;:::-;;:::i;:::-;;;;5000:42:1;4988:55;;;4970:74;;5075:2;5060:18;;5053:34;;;;4943:18;46204:507:0;4796:297:1;71713:188:0;;;;;;;;;;-1:-1:-1;71713:188:0;;;;;:::i;:::-;;:::i;52835:343::-;;;;;;;;;;-1:-1:-1;52835:343:0;;;;;:::i;:::-;;:::i;109986:42::-;;;;;;;;;;;;;;;109524:49;;;;;;;;;;;;;;;72843:287;;;;;;;;;;-1:-1:-1;72843:287:0;;;;;:::i;:::-;;:::i;109833:120::-;;;;;;;;;;;;;;;113685:245;;;;;;;;;;-1:-1:-1;113685:245:0;;;;;:::i;:::-;;:::i;121662:501::-;;;;;;;;;;;;;:::i;119505:77::-;;;;;;;;;;;;;:::i;33704:185::-;;;;;;;;;;-1:-1:-1;33704:185:0;;;;;:::i;:::-;;:::i;120766:193::-;;;;;;;;;;-1:-1:-1;120766:193:0;;;;;:::i;:::-;;:::i;53444:320::-;;;;;;;;;;-1:-1:-1;53444:320:0;;;;;:::i;:::-;;:::i;122280:593::-;;;;;;;;;;-1:-1:-1;122280:593:0;;;;;:::i;:::-;;:::i;120074:143::-;;;;;;;;;;-1:-1:-1;120074:143:0;;;;;:::i;:::-;;:::i;59964:86::-;;;;;;;;;;-1:-1:-1;60035:7:0;;;;59964:86;;30251:326;;;;;;;;;;-1:-1:-1;30251:326:0;;;;;:::i;:::-;;:::i;29894:295::-;;;;;;;;;;-1:-1:-1;29894:295:0;;;;;:::i;:::-;;:::i;115283:738::-;;;;;;:::i;:::-;;:::i;119424:73::-;;;;;;;;;;;;;:::i;109727:99::-;;;;;;;;;;;;;;;89471:203;;;;;;;;;;-1:-1:-1;89471:203:0;;;;;:::i;:::-;;:::i;69680:197::-;;;;;;;;;;-1:-1:-1;69680:197:0;;;;;:::i;:::-;69811:4;69840:12;;;:6;:12;;;;;;;;:29;;;;;;;;;;;;;;;;69680:197;110311:65;;;;;;;;;;-1:-1:-1;110311:65:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;30813:104;;;;;;;;;;;;;:::i;109580:33::-;;;;;;;;;;-1:-1:-1;109580:33:0;;;;;;;;;;;8481:26:1;8469:39;;;8451:58;;8439:2;8424:18;109580:33:0;8307:208:1;113330:248:0;;;;;;;;;;-1:-1:-1;113330:248:0;;;;;:::i;:::-;;:::i;110580:64::-;;;;;;;;;;;;110619:25;110580:64;;68709:49;;;;;;;;;;-1:-1:-1;68709:49:0;68754:4;68709:49;;32718:187;;;;;;;;;;-1:-1:-1;32718:187:0;;;;;:::i;:::-;;:::i;110160:94::-;;;;;;;;;;-1:-1:-1;110160:94:0;;;;;;;;109620:100;;;;;;;;;;;;;;;33960:365;;;;;;;;;;-1:-1:-1;33960:365:0;;;;;:::i;:::-;;:::i;121030:494::-;;;;;;;;;;-1:-1:-1;121030:494:0;;;;;:::i;:::-;;:::i;89848:192::-;;;;;;;;;;-1:-1:-1;89848:192:0;;;;;:::i;:::-;;:::i;117874:200::-;;;;;;;;;;-1:-1:-1;117874:200:0;;;;;:::i;:::-;;:::i;110383:55::-;;;;;;;;;;-1:-1:-1;110383:55:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;72146:190;;;;;;;;;;-1:-1:-1;72146:190:0;;;;;:::i;:::-;;:::i;109480:37::-;;;;;;;;;;;;;;;;113974:263;;;;;;;;;;;;;:::i;112919:305::-;;;;;;;;;;-1:-1:-1;112919:305:0;;;;;:::i;:::-;;:::i;116760:875::-;;;;;;;;;;-1:-1:-1;116760:875:0;;;;;:::i;:::-;;:::i;110511:62::-;;;;;;;;;;;;110549:24;110511:62;;32976:214;;;;;;;;;;-1:-1:-1;32976:214:0;;;;;:::i;:::-;33147:25;;;;33118:4;33147:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;32976:214;119633:146;;;;;;;;;;-1:-1:-1;119633:146:0;;;;;:::i;:::-;;:::i;123720:332::-;123979:4;124008:36;124032:11;124008:23;:36::i;:::-;124001:43;123720:332;-1:-1:-1;;123720:332:0:o;30644:100::-;30698:13;30731:5;30724:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;30644:100;:::o;32338:308::-;32459:7;35961:16;;;:7;:16;;;;;;:30;:16;32484:110;;;;;;;10867:2:1;32484:110:0;;;10849:21:1;10906:2;10886:18;;;10879:30;10945:34;10925:18;;;10918:62;11016:14;10996:18;;;10989:42;11048:19;;32484:110:0;;;;;;;;;-1:-1:-1;32614:24:0;;;;:15;:24;;;;;;;;;32338:308::o;31861:411::-;31942:13;31958:23;31973:7;31958:14;:23::i;:::-;31942:39;;32006:5;32000:11;;:2;:11;;;;31992:57;;;;;;;11280:2:1;31992:57:0;;;11262:21:1;11319:2;11299:18;;;11292:30;11358:34;11338:18;;;11331:62;11429:3;11409:18;;;11402:31;11450:19;;31992:57:0;11078:397:1;31992:57:0;24818:10;32084:21;;;;;:62;;-1:-1:-1;32109:37:0;32126:5;24818:10;32976:214;:::i;32109:37::-;32062:168;;;;;;;11682:2:1;32062:168:0;;;11664:21:1;11721:2;11701:18;;;11694:30;11760:34;11740:18;;;11733:62;11831:26;11811:18;;;11804:54;11875:19;;32062:168:0;11480:420:1;32062:168:0;32243:21;32252:2;32256:7;32243:8;:21::i;:::-;31931:341;31861:411;;:::o;118395:370::-;118542:16;68754:4;69200:16;68754:4;69200:10;:16::i;:::-;60756:14:::1;60773:8;60035:7:::0;;;;;59964:86;60773:8:::1;60756:25;;60796:9;60792:52;;;60822:10;:8;:10::i;:::-;118576:25:::2;118618:5;118604:20;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;118604:20:0::2;;118576:48;;118642:9;118637:93;118661:5;118657:1;:9;118637:93;;;118702:16;118714:3;118702:11;:16::i;:::-;118688:8;118697:1;118688:11;;;;;;;;:::i;:::-;;::::0;;::::2;::::0;;;;;:30;118668:3;::::2;::::0;::::2;:::i;:::-;;;;118637:93;;;-1:-1:-1::0;118749:8:0;-1:-1:-1;60870:9:0::1;60866:50;;;60896:8;:6;:8::i;:::-;60745:178;118395:370:::0;;;;;:::o;119787:148::-;68754:4;69200:16;68754:4;69200:10;:16::i;:::-;-1:-1:-1;119901:11:0::1;:26:::0;;;::::1;;::::0;;;::::1;::::0;;;::::1;::::0;;119787:148::o;114772:351::-;114826:7;60290:8;60035:7;;;;;59964:86;60290:8;60289:9;60281:38;;;;;;;12685:2:1;60281:38:0;;;12667:21:1;12724:2;12704:18;;;12697:30;12763:18;12743;;;12736:46;12799:18;;60281:38:0;12483:340:1;60281:38:0;114847:11:::1;114860::::0;114875:21:::1;:19;:21::i;:::-;114846:50;;;;114942:3;114929:9;:16;;:36;;;;;114962:3;114949:9;:16;;114929:36;114907:136;;;::::0;::::1;::::0;;13030:2:1;114907:136:0::1;::::0;::::1;13012:21:1::0;13069:2;13049:18;;;13042:30;13108:34;13088:18;;;13081:62;13179:20;13159:18;;;13152:48;13217:19;;114907:136:0::1;12828:414:1::0;114907:136:0::1;115056:14;:12;:14::i;:::-;115090:25;24818:10:::0;115090:11:::1;:25::i;:::-;115083:32;;;;114772:351:::0;:::o;116170:430::-;116225:7;60290:8;60035:7;;;;;59964:86;60290:8;60289:9;60281:38;;;;;;;12685:2:1;60281:38:0;;;12667:21:1;12724:2;12704:18;;;12697:30;12763:18;12743;;;12736:46;12799:18;;60281:38:0;12483:340:1;60281:38:0;116323:11:::1;::::0;116267:23:::1;:13;:23;;24818:10:::0;116267:52:::1;::::0;;::::1;::::0;;;;;;13431:42:1;13500:15;;;116267:52:0::1;::::0;::::1;13482:34:1::0;116313:4:0::1;13532:18:1::0;;;13525:43;13394:18;;116267:52:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:67;;116245:167;;;::::0;::::1;::::0;;13970:2:1;116245:167:0::1;::::0;::::1;13952:21:1::0;14009:2;13989:18;;;13982:30;14048:34;14028:18;;;14021:62;14119:20;14099:18;;;14092:48;14157:19;;116245:167:0::1;13768:414:1::0;116245:167:0::1;116425:122;24818:10:::0;116525:11:::1;::::0;116425:30:::1;:13;:30;::::0;:122;116505:4:::1;::::0;116425:30:::1;:122::i;:::-;116567:25;24818:10:::0;115090:11:::1;:25::i;116567:::-;116560:32;;116170:430:::0;:::o;33257:376::-;33466:41;24818:10;33499:7;33466:18;:41::i;:::-;33444:140;;;;;;;14389:2:1;33444:140:0;;;14371:21:1;14428:2;14408:18;;;14401:30;14467:34;14447:18;;;14440:62;14538:19;14518:18;;;14511:47;14575:19;;33444:140:0;14187:413:1;33444:140:0;33597:28;33607:4;33613:2;33617:7;33597:9;:28::i;46204:507::-;46348:7;46411:27;;;:17;:27;;;;;;;;46382:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;46348:7;;46451:92;;-1:-1:-1;46502:29:0;;;;;;;;;-1:-1:-1;46502:29:0;;;;;;;;;;;;;;;46451:92;46593:23;;;;46555:21;;47077:5;;46580:36;;46579:71;46580:36;:10;:36;:::i;:::-;46579:71;;;;:::i;:::-;46671:16;;;;;-1:-1:-1;46204:507:0;;-1:-1:-1;;;;46204:507:0:o;71713:188::-;71389:7;71421:12;;;:6;:12;;;;;:22;;;69200:16;69211:4;69200:10;:16::i;:::-;71868:25:::1;71879:4;71885:7;71868:10;:25::i;52835:343::-:0;52977:7;53032:23;53049:5;53032:16;:23::i;:::-;53024:5;:31;53002:124;;;;;;;15354:2:1;53002:124:0;;;15336:21:1;15393:2;15373:18;;;15366:30;15432:34;15412:18;;;15405:62;15503:13;15483:18;;;15476:41;15534:19;;53002:124:0;15152:407:1;53002:124:0;-1:-1:-1;53144:19:0;;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;52835:343::o;72843:287::-;72985:23;;;24818:10;72985:23;72963:120;;;;;;;15766:2:1;72963:120:0;;;15748:21:1;15805:2;15785:18;;;15778:30;15844:34;15824:18;;;15817:62;15915:17;15895:18;;;15888:45;15950:19;;72963:120:0;15564:411:1;72963:120:0;73096:26;73108:4;73114:7;73096:11;:26::i;:::-;72843:287;;:::o;113685:245::-;113767:52;113775:29;;;113817:1;113775:29;;;:21;:29;;;;;;;113745:124;;;;;;;16182:2:1;113745:124:0;;;16164:21:1;16221:2;16201:18;;;16194:30;16260:24;16240:18;;;16233:52;16302:18;;113745:124:0;15980:346:1;113745:124:0;113880:29;;;;;;;;:21;:29;;;;;;;:42;;;;;;;:29;;;:40;;:42;;;;;:29;;:42;;;;;;:29;;:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;113685:245;:::o;121662:501::-;68754:4;69200:16;68754:4;69200:10;:16::i;:::-;121737:21:::1;121729:62;;;::::0;::::1;::::0;;16533:2:1;121729:62:0::1;::::0;::::1;16515:21:1::0;16572:2;16552:18;;;16545:30;16611:25;16591:18;;;16584:53;16654:18;;121729:62:0::1;16331:347:1::0;121729:62:0::1;121849:16;::::0;121804:25:::1;::::0;121849:24:::1;::::0;:16:::1;;:22;:24::i;:::-;121804:70;;121885:8;:19;;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;121917:8;:17;;;121935:12;24818:10:::0;;24738:98;121935:12:::1;121917:35;::::0;;::::1;::::0;;;;;;5000:42:1;4988:55;;;121917:35:0::1;::::0;::::1;4970:74:1::0;121949:2:0::1;5060:18:1::0;;;5053:34;4943:18;;121917:35:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;121985:8;121969:24;;:12;24818:10:::0;;24738:98;121969:12:::1;:24;;;121965:88;;122010:31;::::0;;;;:17:::1;122028:8;4988:55:1::0;;122010:31:0::1;::::0;::::1;4970:74:1::0;122038:2:0::1;5060:18:1::0;;;5053:34;122010:17:0;::::1;::::0;::::1;::::0;4943:18:1;;122010:31:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;121965:88;122065:58;::::0;:35:::1;::::0;::::1;::::0;122101:21:::1;122065:58:::0;::::1;;;::::0;::::1;::::0;;;122101:21;122065:35;:58;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;122134:8;:19;;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;121718:445;121662:501:::0;:::o;119505:77::-;110549:24;69200:16;69211:4;69200:10;:16::i;:::-;119564:10:::1;:8;:10::i;:::-;119505:77:::0;:::o;33704:185::-;33842:39;33859:4;33865:2;33869:7;33842:39;;;;;;;;;;;;:16;:39::i;120766:193::-;120887:13;110619:25;69200:16;69211:4;69200:10;:16::i;:::-;120925:26:::1;120943:7;120925:17;:26::i;:::-;120918:33;;69227:1;120766:193:::0;;;;:::o;53444:320::-;53564:7;53619:30;53342:10;:17;;53254:113;53619:30;53611:5;:38;53589:132;;;;;;;17507:2:1;53589:132:0;;;17489:21:1;17546:2;17526:18;;;17519:30;17585:34;17565:18;;;17558:62;17656:14;17636:18;;;17629:42;17688:19;;53589:132:0;17305:408:1;53589:132:0;53739:10;53750:5;53739:17;;;;;;;;:::i;:::-;;;;;;;;;53732:24;;53444:320;;;:::o;122280:593::-;68754:4;69200:16;68754:4;69200:10;:16::i;:::-;122381:30:::1;::::0;;;;122405:4:::1;122381:30;::::0;::::1;809:74:1::0;122381:15:0::1;::::0;::::1;::::0;::::1;::::0;782:18:1;;122381:30:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;122359:117;;;::::0;::::1;::::0;;17920:2:1;122359:117:0::1;::::0;::::1;17902:21:1::0;;;17939:18;;;17932:30;17998:34;17978:18;;;17971:62;18050:18;;122359:117:0::1;17718:356:1::0;122359:117:0::1;122534:16;::::0;122489:25:::1;::::0;122534:24:::1;::::0;:16:::1;;:22;:24::i;:::-;122489:70;;122570:8;:19;;;:21;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;122602:8;:17;;;122620:12;24818:10:::0;;24738:98;122620:12:::1;122602:35;::::0;;::::1;::::0;;;;;;5000:42:1;4988:55;;;122602:35:0::1;::::0;::::1;4970:74:1::0;122634:2:0::1;5060:18:1::0;;;5053:34;4943:18;;122602:35:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;122670:8;122654:24;;:12;24818:10:::0;;24738:98;122654:12:::1;:24;;;122650:88;;122695:31;::::0;;;;:17:::1;122713:8;4988:55:1::0;;122695:31:0::1;::::0;::::1;4970:74:1::0;122723:2:0::1;5060:18:1::0;;;5053:34;122695:17:0;::::1;::::0;::::1;::::0;4943:18:1;;122695:31:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;122650:88;122788:30;::::0;;;;122812:4:::1;122788:30;::::0;::::1;809:74:1::0;122750:69:0::1;::::0;122777:8;;122788:15:::1;::::0;::::1;::::0;::::1;::::0;782:18:1;;122788:30:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;122750:18;::::0;::::1;::::0;:69;:18:::1;:69::i;:::-;122830:35;::::0;;;;:19:::1;827:55:1::0;;;122830:35:0::1;::::0;::::1;809:74:1::0;122830:19:0;::::1;::::0;::::1;::::0;782:18:1;;122830:35:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;122348:525;122280:593:::0;;:::o;120074:143::-;68754:4;69200:16;68754:4;69200:10;:16::i;:::-;120189:20;;::::1;::::0;:8:::1;::::0;:20:::1;::::0;::::1;::::0;::::1;:::i;30251:326::-:0;30368:7;30409:16;;;:7;:16;;;;;;;;30458:19;30436:110;;;;;;;18281:2:1;30436:110:0;;;18263:21:1;18320:2;18300:18;;;18293:30;18359:34;18339:18;;;18332:62;18430:11;18410:18;;;18403:39;18459:19;;30436:110:0;18079:405:1;29894:295:0;30011:7;30058:19;;;30036:111;;;;;;;18691:2:1;30036:111:0;;;18673:21:1;18730:2;18710:18;;;18703:30;18769:34;18749:18;;;18742:62;18840:12;18820:18;;;18813:40;18870:19;;30036:111:0;18489:406:1;30036:111:0;-1:-1:-1;30165:16:0;;;;;;:9;:16;;;;;;;29894:295::o;115283:738::-;115389:16;60290:8;60035:7;;;;;59964:86;60290:8;60289:9;60281:38;;;;;;;12685:2:1;60281:38:0;;;12667:21:1;12724:2;12704:18;;;12697:30;12763:18;12743;;;12736:46;12799:18;;60281:38:0;12483:340:1;60281:38:0;115454:19:::1;115445:5;:28;;;;115423:132;;;::::0;::::1;::::0;;19102:2:1;115423:132:0::1;::::0;::::1;19084:21:1::0;19141:2;19121:18;;;19114:30;19180:34;19160:18;;;19153:62;19251:24;19231:18;;;19224:52;19293:19;;115423:132:0::1;18900:418:1::0;115423:132:0::1;115569:11;115582::::0;115597:21:::1;:19;:21::i;:::-;115568:50:::0;;-1:-1:-1;115568:50:0;-1:-1:-1;115666:11:0::1;;::::0;::::1;115568:50:::0;115666:11:::1;:::i;:::-;115653:9;:24;;:52;;;;-1:-1:-1::0;115694:11:0::1;;::::0;::::1;:3:::0;:11:::1;:::i;:::-;115681:9;:24;;115653:52;115631:152;;;::::0;::::1;::::0;;13030:2:1;115631:152:0::1;::::0;::::1;13012:21:1::0;13069:2;13049:18;;;13042:30;13108:34;13088:18;;;13081:62;13179:20;13159:18;;;13152:48;13217:19;;115631:152:0::1;12828:414:1::0;115631:152:0::1;115796:25;115838:5;115824:20;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;115824:20:0::1;;115796:48;;115862:9;115857:102;115881:5;115877:9;;:1;:9;115857:102;;;115922:25;24818:10:::0;115090:11:::1;:25::i;115922:::-;115908:8;115917:1;115908:11;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;:39;115888:3;::::1;::::0;::::1;:::i;:::-;;;;115857:102;;;;115971:14;:12;:14::i;:::-;116005:8:::0;-1:-1:-1;;;60330:1:0::1;115283:738:::0;;;:::o;119424:73::-;110549:24;69200:16;69211:4;69200:10;:16::i;:::-;119481:8:::1;:6;:8::i;89471:203::-:0;89606:7;89638:18;;;:12;:18;;;;;:28;;89660:5;89638:21;:28::i;:::-;89631:35;89471:203;-1:-1:-1;;;89471:203:0:o;30813:104::-;30869:13;30902:7;30895:14;;;;;:::i;113330:248::-;113417:52;113425:29;;;113393:7;113425:29;;;:21;:29;;;;;;113393:7;;113425:29;113413:93;;-1:-1:-1;113493:1:0;;113330:248;-1:-1:-1;113330:248:0:o;113413:93::-;113525:29;;;;;;;;:21;:29;;;;;;;;:45;;;;;;;;809:74:1;;;;113525:29:0;;;;:37;;782:18:1;;113525:45:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;32718:187::-;32845:52;24818:10;32878:8;32888;32845:18;:52::i;33960:365::-;34149:41;24818:10;34182:7;34149:18;:41::i;:::-;34127:140;;;;;;;14389:2:1;34127:140:0;;;14371:21:1;14428:2;14408:18;;;14401:30;14467:34;14447:18;;;14440:62;14538:19;14518:18;;;14511:47;14575:19;;34127:140:0;14187:413:1;34127:140:0;34278:39;34292:4;34298:2;34302:7;34311:5;34278:13;:39::i;:::-;33960:365;;;;:::o;121030:494::-;35937:4;35961:16;;;:7;:16;;;;;;121148:13;;35961:30;:16;121179:113;;;;;;;19525:2:1;121179:113:0;;;19507:21:1;19564:2;19544:18;;;19537:30;19603:34;19583:18;;;19576:62;19674:17;19654:18;;;19647:45;19709:19;;121179:113:0;19323:411:1;121179:113:0;121389:8;121420:26;121438:7;121420:17;:26::i;:::-;121469:13;121350:151;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;121305:211;;121030:494;;;:::o;89848:192::-;89973:7;90005:18;;;:12;:18;;;;;:27;;:25;:27::i;117874:200::-;118018:7;;69200:16;118018:7;69200:10;:16::i;:::-;60756:14:::1;60773:8;60035:7:::0;;;;;59964:86;60773:8:::1;60756:25;;60796:9;60792:52;;;60822:10;:8;:10::i;:::-;118050:16:::2;118062:3;118050:11;:16::i;:::-;118043:23;;60870:9:::1;60866:50;;;60896:8;:6;:8::i;:::-;60745:178;117874:200:::0;;;;:::o;72146:190::-;71389:7;71421:12;;;:6;:12;;;;;:22;;;69200:16;69211:4;69200:10;:16::i;:::-;72302:26:::1;72314:4;72320:7;72302:11;:26::i;113974:263::-:0;114156:11;;114056:122;;;;;:21;114092:12;21700:15:1;;114056:122:0;;;21682:34:1;114127:13:0;21752:15:1;;21732:18;;;21725:43;21784:18;;;21777:34;;;;-1:-1:-1;;;;114056:6:0;:21;;;;;;21594:18:1;;114056:122:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;114209:11;;114038:140;;-1:-1:-1;114224:5:0;;114199:21;;114209:11;;114038:140;114199:21;:::i;:::-;114198:31;;;;:::i;:::-;114191:38;;;113974:263;:::o;112919:305::-;112983:7;35961:16;;;:7;:16;;;;;;:30;:16;113003:58;;-1:-1:-1;113048:1:0;;112919:305;-1:-1:-1;112919:305:0:o;113003:58::-;113093:52;113115:29;;;:20;:29;;;;;;;;;;;;;113093:52;;;:21;:52;;;;;;113172:29;;;;;;;;113093:123;;;;;;;809:74:1;;;;113093:52:0;;;;;:60;;782:18:1;;113093:123:0;638:251:1;116760:875:0;116860:16;60290:8;60035:7;;;;;59964:86;60290:8;60289:9;60281:38;;;;;;;12685:2:1;60281:38:0;;;12667:21:1;12724:2;12704:18;;;12697:30;12763:18;12743;;;12736:46;12799:18;;60281:38:0;12483:340:1;60281:38:0;116925:19:::1;116916:5;:28;;116894:132;;;::::0;::::1;::::0;;19102:2:1;116894:132:0::1;::::0;::::1;19084:21:1::0;19141:2;19121:18;;;19114:30;19180:34;19160:18;;;19153:62;19251:24;19231:18;;;19224:52;19293:19;;116894:132:0::1;18900:418:1::0;116894:132:0::1;117039:23;117079:5;117065:11;;:19;;;;:::i;:::-;117039:45:::0;-1:-1:-1;117039:45:0;117119:23:::1;:13;:23;;24818:10:::0;117119:52:::1;::::0;;::::1;::::0;;;;;;13431:42:1;13500:15;;;117119:52:0::1;::::0;::::1;13482:34:1::0;117165:4:0::1;13532:18:1::0;;;13525:43;13394:18;;117119:52:0::1;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:88;;117097:188;;;::::0;::::1;::::0;;13970:2:1;117097:188:0::1;::::0;::::1;13952:21:1::0;14009:2;13989:18;;;13982:30;14048:34;14028:18;;;14021:62;14119:20;14099:18;;;14092:48;14157:19;;117097:188:0::1;13768:414:1::0;117097:188:0::1;117298:126;:13;:30;;24818:10:::0;117378:4:::1;117398:15:::0;117298:30:::1;:126::i;:::-;117437:25;117479:5;117465:20;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;-1:-1:-1;117465:20:0::1;;117437:48;;117503:9;117498:102;117522:5;117518:1;:9;117498:102;;;117563:25;24818:10:::0;115090:11:::1;:25::i;117563:::-;117549:8;117558:1;117549:11;;;;;;;;:::i;:::-;;::::0;;::::1;::::0;;;;;:39;117529:3;::::1;::::0;::::1;:::i;:::-;;;;117498:102;;;-1:-1:-1::0;117619:8:0;116760:875;-1:-1:-1;;;116760:875:0:o;119633:146::-;68754:4;69200:16;68754:4;69200:10;:16::i;:::-;-1:-1:-1;119745:11:0::1;:26:::0;119633:146::o;91615:622::-;91672:16;91742:4;91736:11;91808:66;91786:3;91761:128;91936:14;91930:4;91926:25;91919:4;91914:3;91910:14;91903:49;92024:66;92000:4;91995:3;91991:14;91966:139;92146:4;92141:3;92138:1;92131:20;92119:32;-1:-1:-1;;92180:22:0;;;92172:57;;;;;;;22024:2:1;92172:57:0;;;22006:21:1;22063:2;22043:18;;;22036:30;22102:24;22082:18;;;22075:52;22144:18;;92172:57:0;21822:346:1;74413:238:0;69811:4;69840:12;;;:6;:12;;;;;;;;:29;;;;;;;;;;;;;74492:152;;74536:12;;;;:6;:12;;;;;;;;:29;;;;;;;;;;:36;;;;74568:4;74536:36;;;74619:12;24818:10;;24738:98;74619:12;74592:40;;74610:7;74592:40;;74604:4;74592:40;;;;;;;;;;74413:238;;:::o;83077:175::-;83165:4;83194:50;83199:3;83219:23;;;83194:4;:50::i;88582:290::-;88712:4;88754:57;;;88769:42;88754:57;;:110;;;88828:36;88852:11;88828:23;:36::i;40159:174::-;40234:24;;;;:15;:24;;;;;:29;;;;;;;;;;;;;:24;;40288:23;40234:24;40288:14;:23::i;:::-;40279:46;;;;;;;;;;;;40159:174;;:::o;70181:105::-;70248:30;70259:4;24818:10;70248;:30::i;61326:120::-;60035:7;;;;60559:41;;;;;;;22375:2:1;60559:41:0;;;22357:21:1;22414:2;22394:18;;;22387:30;22453:22;22433:18;;;22426:50;22493:18;;60559:41:0;22173:344:1;60559:41:0;61385:7:::1;:15:::0;;;::::1;::::0;;61416:22:::1;24818:10:::0;61425:12:::1;61416:22;::::0;839:42:1;827:55;;;809:74;;797:2;782:18;61416:22:0::1;;;;;;;61326:120::o:0;118856:515::-;118916:7;118936:14;118953:13;53342:10;:17;;53254:113;118953:13;118936:30;-1:-1:-1;118999:10:0;118985;118936:30;118994:1;118985:10;:::i;:::-;:24;;118977:51;;;;;;;22857:2:1;118977:51:0;;;22839:21:1;22896:2;22876:18;;;22869:30;22935:16;22915:18;;;22908:44;22969:18;;118977:51:0;22655:338:1;118977:51:0;119041:15;119059:10;:6;119068:1;119059:10;:::i;:::-;119041:28;;119082:39;119108:7;119117:3;119082:25;:39::i;:::-;119134:23;119144:3;119149:7;119134:9;:23::i;:::-;119231:52;119253:29;;;:20;:29;;;;;;;;;;;;;119231:52;;:21;:52;;;;;;;119170:143;;119201:7;;119231:52;119299:3;119170:16;:143::i;61067:118::-;60035:7;;;;60289:9;60281:38;;;;;;;12685:2:1;60281:38:0;;;12667:21:1;12724:2;12704:18;;;12697:30;12763:18;12743;;;12736:46;12799:18;;60281:38:0;12483:340:1;60281:38:0;61127:7:::1;:14:::0;;;::::1;61137:4;61127:14;::::0;;61157:20:::1;61164:12;24818:10:::0;;24738:98;114245:289;114326:12;114340;114370:15;114388:13;:11;:13::i;:::-;114370:31;-1:-1:-1;114438:5:0;114420:14;114370:31;114430:4;114420:14;:::i;:::-;114419:24;;;;:::i;:::-;114412:31;-1:-1:-1;114501:5:0;114482:15;:7;114492:5;114482:15;:::i;:::-;114481:25;;;;:::i;:::-;114474:32;;114359:175;114245:289;;:::o;114542:79::-;114586:27;;;;;:13;114600:12;827:55:1;;114586:27:0;;;809:74:1;114586:6:0;:13;;;;782:18:1;;114586:27:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;12914:285;13112:68;;21631:42:1;21700:15;;;13112:68:0;;;21682:34:1;21752:15;;21732:18;;;21725:43;21784:18;;;21777:34;;;13058:133:0;;13092:5;;13135:27;;21594:18:1;;13112:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13058:19;:133::i;36166:452::-;36295:4;35961:16;;;:7;:16;;;;;;:30;:16;36317:110;;;;;;;23200:2:1;36317:110:0;;;23182:21:1;23239:2;23219:18;;;23212:30;23278:34;23258:18;;;23251:62;23349:14;23329:18;;;23322:42;23381:19;;36317:110:0;22998:408:1;36317:110:0;36438:13;36454:23;36469:7;36454:14;:23::i;:::-;36438:39;;36507:5;36496:16;;:7;:16;;;:64;;;;36553:7;36529:31;;:20;36541:7;36529:11;:20::i;:::-;:31;;;36496:64;:113;;;-1:-1:-1;33147:25:0;;;;33118:4;33147:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;36577:32;36488:122;36166:452;-1:-1:-1;;;;36166:452:0:o;39379:662::-;39552:4;39525:31;;:23;39540:7;39525:14;:23::i;:::-;:31;;;39503:118;;;;;;;23613:2:1;39503:118:0;;;23595:21:1;23652:2;23632:18;;;23625:30;23691:34;23671:18;;;23664:62;23762:7;23742:18;;;23735:35;23787:19;;39503:118:0;23411:401:1;39503:118:0;39640:16;;;39632:65;;;;;;;24019:2:1;39632:65:0;;;24001:21:1;24058:2;24038:18;;;24031:30;24097:34;24077:18;;;24070:62;24168:6;24148:18;;;24141:34;24192:19;;39632:65:0;23817:400:1;39632:65:0;39710:39;39731:4;39737:2;39741:7;39710:20;:39::i;:::-;39814:29;39831:1;39835:7;39814:8;:29::i;:::-;39856:15;;;;;;;:9;:15;;;;;:20;;39875:1;;39856:15;:20;;39875:1;;39856:20;:::i;:::-;;;;-1:-1:-1;;39887:13:0;;;;;;;:9;:13;;;;;:18;;39904:1;;39887:13;:18;;39904:1;;39887:18;:::i;:::-;;;;-1:-1:-1;;39916:16:0;;;;:7;:16;;;;;;:21;;;;;;;;;;;;;;39955:27;;39916:16;;39955:27;;;;;;;39995:38;40015:4;40021:2;40025:7;39995:19;:38::i;90133:201::-;90253:31;90270:4;90276:7;90253:16;:31::i;:::-;90295:18;;;;:12;:18;;;;;:31;;90318:7;90295:22;:31::i;90428:206::-;90549:32;90567:4;90573:7;90549:17;:32::i;:::-;90592:18;;;;:12;:18;;;;;:34;;90618:7;90592:25;:34::i;120354:321::-;120448:13;120499:168;120664:2;120574:22;:11;:20;:22::i;:::-;120598:18;:7;:16;:18::i;:::-;120557:60;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;120525:111;;120557:60;120525:111;;;;;120499:164;:168::i;12658:248::-;12829:58;;5000:42:1;4988:55;;12829:58:0;;;4970:74:1;5060:18;;;5053:34;;;12775:123:0;;12809:5;;12852:23;;4943:18:1;;12829:58:0;4796:297:1;84451:190:0;84552:7;84608:22;84612:3;84624:5;84608:3;:22::i;40475:315::-;40630:8;40621:17;;:5;:17;;;;40613:55;;;;;;;25029:2:1;40613:55:0;;;25011:21:1;25068:2;25048:18;;;25041:30;25107:27;25087:18;;;25080:55;25152:18;;40613:55:0;24827:349:1;40613:55:0;40679:25;;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;;;;;;;;;;;;40741:41;;586::1;;;40741::0;;559:18:1;40741:41:0;;;;;;;40475:315;;;:::o;35207:352::-;35364:28;35374:4;35380:2;35384:7;35364:9;:28::i;:::-;35425:48;35448:4;35454:2;35458:7;35467:5;35425:22;:48::i;:::-;35403:148;;;;;;;25383:2:1;35403:148:0;;;25365:21:1;25422:2;25402:18;;;25395:30;25461:34;25441:18;;;25434:62;25532:20;25512:18;;;25505:48;25570:19;;35403:148:0;25181:414:1;83980:117:0;84043:7;84070:19;84078:3;79212:18;;79129:109;76786:414;76849:4;79011:19;;;:12;;;:19;;;;;;76866:327;;-1:-1:-1;76909:23:0;;;;;;;;:11;:23;;;;;;;;;;;;;77092:18;;77070:19;;;:12;;;:19;;;;;;:40;;;;77125:11;;76866:327;-1:-1:-1;77176:5:0;77169:12;;69308:280;69438:4;69480:47;;;69495:32;69480:47;;:100;;;69544:36;69568:11;69544:23;:36::i;70576:505::-;69811:4;69840:12;;;:6;:12;;;;;;;;:29;;;;;;;;;;;;;70660:414;;70853:41;70881:7;70853:41;;70891:2;70853:19;:41::i;:::-;70967:38;70995:4;71002:2;70967:19;:38::i;:::-;70758:270;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;70704:358;;;;;;;;:::i;112014:787::-;112122:54;112130:31;;;112174:1;112130:31;;;:21;:31;;;;;;;112118:623;;112262:16;;:24;;:16;;:22;:24::i;:::-;112193:31;;;;;;;;:21;:31;;;;;;:108;;;;;;;;;;;;;;112316:44;;;;;;;:42;;:44;;;;;112193:31;112316:44;;;;;;112193:31;:108;112316:44;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;112375:31:0;;;;;;;;:21;:31;;;;;;;;112442:19;;112375:122;;;;;112442:19;;;112375:122;;;4970:74:1;112375:31:0;5060:18:1;;;5053:34;112375:31:0;;;;:40;;4943:18:1;;112375:122:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;112512:31:0;;;;;;;;:21;:31;;;;;;;;:53;;;;;;;;4970:74:1;;;;112512:31:0;5060:18:1;;;5053:34;112512:31:0;;;;:40;;4943:18:1;;112512:53:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;112587:142:0;;;;112629:31;;;;:21;:31;;;;;;;112587:142;;;;-1:-1:-1;112680:7:0;;112629:31;;112587:142;;112629:31;112587:142;112118:623;112753:29;;;;:20;:29;;;;;;:40;;;;;;;;;;;;;;112014:787::o;36960:110::-;37036:26;37046:2;37050:7;37036:26;;;;;;;;;;;;:9;:26::i;48248:427::-;47077:5;48414:33;;;;;48392:125;;;;;;;26903:2:1;48392:125:0;;;26885:21:1;26942:2;26922:18;;;26915:30;26981:34;26961:18;;;26954:62;27052:12;27032:18;;;27025:40;27082:19;;48392:125:0;26701:406:1;48392:125:0;48536:22;;;48528:62;;;;;;;27314:2:1;48528:62:0;;;27296:21:1;27353:2;27333:18;;;27326:30;27392:29;27372:18;;;27365:57;27439:18;;48528:62:0;27112:351:1;48528:62:0;48632:35;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;48603:26:0;;;:17;:26;;;;;;:64;;;;;;;;;;;;;;48248:427::o;15625:802::-;16049:23;16075:106;16117:4;16075:106;;;;;;;;;;;;;;;;;16083:5;16075:27;;;;:106;;;;;:::i;:::-;16196:17;;16049:132;;-1:-1:-1;16196:21:0;16192:228;;16311:10;16300:30;;;;;;;;;;;;:::i;:::-;16274:134;;;;;;;27920:2:1;16274:134:0;;;27902:21:1;27959:2;27939:18;;;27932:30;27998:34;27978:18;;;27971:62;28069:12;28049:18;;;28042:40;28099:19;;16274:134:0;27718:406:1;122960:239:0;123146:45;123173:4;123179:2;123183:7;123146:26;:45::i;123207:385::-;123387:1;123346:29;;;:20;:29;;;;;;:43;:29;:43;123342:141;;123406:52;123428:29;;;:20;:29;;;;;;;;;;;;;123406:52;;:21;:52;;;;;;;:65;;;;;;;:52;;;:63;;:65;;;;;;;;;;:52;;:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;123342:141;123495:19;;;;;;;;;;;:30;;;:32;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;74783:239;69811:4;69840:12;;;:6;:12;;;;;;;;:29;;;;;;;;;;;;;74863:152;;;74938:5;74906:12;;;:6;:12;;;;;;;;:29;;;;;;;;;;;:37;;;;;;74963:40;24818:10;;74906:12;;74963:40;;74938:5;74963:40;74783:239;;:::o;83428:181::-;83519:4;83548:53;83556:3;83576:23;;;83548:7;:53::i;25287:723::-;25343:13;25564:10;25560:53;;-1:-1:-1;;25591:10:0;;;;;;;;;;;;;;;;;;25287:723::o;25560:53::-;25638:5;25623:12;25679:78;25686:9;;25679:78;;25712:8;;;;:::i;:::-;;-1:-1:-1;25735:10:0;;-1:-1:-1;25743:2:0;25735:10;;:::i;:::-;;;25679:78;;;25767:19;25799:6;25789:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;25789:17:0;;25767:39;;25817:154;25824:10;;25817:154;;25851:11;25861:1;25851:11;;:::i;:::-;;-1:-1:-1;25920:10:0;25928:2;25920:5;:10;:::i;:::-;25907:24;;:2;:24;:::i;:::-;25894:39;;25877:6;25884;25877:14;;;;;;;;:::i;:::-;;;;:56;;;;;;;;;;-1:-1:-1;25948:11:0;25957:2;25948:11;;:::i;:::-;;;25817:154;;26588:483;26690:13;26721:19;26753:10;26757:6;26753:1;:10;:::i;:::-;:14;;26766:1;26753:14;:::i;:::-;26743:25;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;26743:25:0;;26721:47;;26779:15;:6;26786:1;26779:9;;;;;;;;:::i;:::-;;;;:15;;;;;;;;;;;26805;:6;26812:1;26805:9;;;;;;;;:::i;:::-;;;;:15;;;;;;;;;;-1:-1:-1;26836:9:0;26848:10;26852:6;26848:1;:10;:::i;:::-;:14;;26861:1;26848:14;:::i;:::-;26836:26;;26831:135;26868:1;26864;:5;26831:135;;;26903:12;26916:5;26924:3;26916:11;26903:25;;;;;;;:::i;:::-;;;;26891:6;26898:1;26891:9;;;;;;;;:::i;:::-;;;;:37;;;;;;;;;;-1:-1:-1;26953:1:0;26943:11;;;;;26871:3;;;:::i;:::-;;;26831:135;;;-1:-1:-1;26984:10:0;;26976:55;;;;;;;28649:2:1;26976:55:0;;;28631:21:1;;;28668:18;;;28661:30;28727:34;28707:18;;;28700:62;28779:18;;26976:55:0;28447:356:1;79592:152:0;79686:7;79718:3;:11;;79730:5;79718:18;;;;;;;;:::i;:::-;;;;;;;;;79711:25;;79592:152;;;;:::o;41355:980::-;41510:4;41531:13;;;4553:19;:23;41527:801;;41584:175;;;;;:36;;;;;;:175;;24818:10;;41678:4;;41705:7;;41735:5;;41584:175;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41584:175:0;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;41563:710;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;41942:13:0;;41938:320;;41985:108;;;;;25383:2:1;41985:108:0;;;25365:21:1;25422:2;25402:18;;;25395:30;25461:34;25441:18;;;25434:62;25532:20;25512:18;;;25505:48;25570:19;;41985:108:0;25181:414:1;41938:320:0;42208:6;42202:13;42193:6;42189:2;42185:15;42178:38;41563:710;41823:51;;41833:41;41823:51;;-1:-1:-1;41816:58:0;;41527:801;-1:-1:-1;42312:4:0;41355:980;;;;;;:::o;49920:220::-;50067:4;50096:36;50120:11;50096:23;:36::i;37297:321::-;37427:18;37433:2;37437:7;37427:5;:18::i;:::-;37478:54;37509:1;37513:2;37517:7;37526:5;37478:22;:54::i;:::-;37456:154;;;;;;;25383:2:1;37456:154:0;;;25365:21:1;25422:2;25402:18;;;25395:30;25461:34;25441:18;;;25434:62;25532:20;25512:18;;;25505:48;25570:19;;37456:154:0;25181:414:1;7100:229:0;7237:12;7269:52;7291:6;7299:4;7305:1;7308:12;7269:21;:52::i;62097:275::-;62241:45;62268:4;62274:2;62278:7;62241:26;:45::i;:::-;60035:7;;;;62307:9;62299:65;;;;;;;29781:2:1;62299:65:0;;;29763:21:1;29820:2;29800:18;;;29793:30;29859:34;29839:18;;;29832:62;29930:13;29910:18;;;29903:41;29961:19;;62299:65:0;29579:407:1;77376:1420:0;77442:4;77581:19;;;:12;;;:19;;;;;;77617:15;;77613:1176;;77992:21;78016:14;78029:1;78016:10;:14;:::i;:::-;78065:18;;77992:38;;-1:-1:-1;78045:17:0;;78065:22;;78086:1;;78065:22;:::i;:::-;78045:42;;78121:13;78108:9;:26;78104:405;;78155:17;78175:3;:11;;78187:9;78175:22;;;;;;;;:::i;:::-;;;;;;;;;78155:42;;78329:9;78300:3;:11;;78312:13;78300:26;;;;;;;;:::i;:::-;;;;;;;;;;;;:38;;;;78414:23;;;:12;;;:23;;;;;:36;;;78104:405;78590:17;;:3;;:17;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;78685:3;:12;;:19;78698:5;78685:19;;;;;;;;;;;78678:26;;;78728:4;78721:11;;;;;;;77613:1176;78772:5;78765:12;;;;;52451:300;52598:4;52640:50;;;52655:35;52640:50;;:103;;;52707:36;52731:11;52707:23;:36::i;37954:439::-;38034:16;;;38026:61;;;;;;;30382:2:1;38026:61:0;;;30364:21:1;;;30401:18;;;30394:30;30460:34;30440:18;;;30433:62;30512:18;;38026:61:0;30180:356:1;38026:61:0;35937:4;35961:16;;;:7;:16;;;;;;:30;:16;:30;38098:58;;;;;;;30743:2:1;38098:58:0;;;30725:21:1;30782:2;30762:18;;;30755:30;30821;30801:18;;;30794:58;30869:18;;38098:58:0;30541:352:1;38098:58:0;38169:45;38198:1;38202:2;38206:7;38169:20;:45::i;:::-;38227:13;;;;;;;:9;:13;;;;;:18;;38244:1;;38227:13;:18;;38244:1;;38227:18;:::i;:::-;;;;-1:-1:-1;;38256:16:0;;;;:7;:16;;;;;;:21;;;;;;;;;;;;;38295:33;;38256:16;;;38295:33;;38256:16;;38295:33;38341:44;38369:1;38373:2;38377:7;38341:19;:44::i;8316:571::-;8486:12;8558:5;8533:21;:30;;8511:118;;;;;;;31100:2:1;8511:118:0;;;31082:21:1;31139:2;31119:18;;;31112:30;31178:34;31158:18;;;31151:62;31249:8;31229:18;;;31222:36;31275:19;;8511:118:0;30898:402:1;8511:118:0;4553:19;;;;8640:60;;;;;;;31507:2:1;8640:60:0;;;31489:21:1;31546:2;31526:18;;;31519:30;31585:31;31565:18;;;31558:59;31634:18;;8640:60:0;31305:353:1;8640:60:0;8714:12;8728:23;8755:6;:11;;8774:5;8795:4;8755:55;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8713:97;;;;8828:51;8845:7;8854:10;8866:12;8828:16;:51::i;:::-;8821:58;8316:571;-1:-1:-1;;;;;;;8316:571:0:o;54377:589::-;54583:18;;;54579:187;;54618:40;54650:7;55793:10;:17;;55766:24;;;;:15;:24;;;;;:44;;;55821:24;;;;;;;;;;;;55689:164;54618:40;54579:187;;;54688:2;54680:10;;:4;:10;;;54676:90;;54707:47;54740:4;54746:7;54707:32;:47::i;:::-;54780:16;;;54776:183;;54813:45;54850:7;54813:36;:45::i;54776:183::-;54886:4;54880:10;;:2;:10;;;54876:83;;54907:40;54935:2;54939:7;54907:27;:40::i;29475:355::-;29622:4;29664:40;;;29679:25;29664:40;;:105;;-1:-1:-1;29721:48:0;;;29736:33;29721:48;29664:105;:158;;;;29786:36;29810:11;29786:23;:36::i;11276:712::-;11426:12;11455:7;11451:530;;;-1:-1:-1;11486:10:0;11479:17;;11451:530;11600:17;;:21;11596:374;;11798:10;11792:17;11859:15;11846:10;11842:2;11838:19;11831:44;11596:374;11941:12;11934:20;;;;;;;;;;;:::i;56480:1002::-;56760:22;56810:1;56785:22;56802:4;56785:16;:22::i;:::-;:26;;;;:::i;:::-;56822:18;56843:26;;;:17;:26;;;;;;56760:51;;-1:-1:-1;56976:28:0;;;56972:328;;57043:18;;;57021:19;57043:18;;;:12;:18;;;;;;;;:34;;;;;;;;;57094:30;;;;;;:44;;;57211:30;;:17;:30;;;;;:43;;;56972:328;-1:-1:-1;57396:26:0;;;;:17;:26;;;;;;;;57389:33;;;57440:18;;;;;;:12;:18;;;;;:34;;;;;;;57433:41;56480:1002::o;57777:1079::-;58055:10;:17;58030:22;;58055:21;;58075:1;;58055:21;:::i;:::-;58087:18;58108:24;;;:15;:24;;;;;;58481:10;:26;;58030:46;;-1:-1:-1;58108:24:0;;58030:46;;58481:26;;;;;;:::i;:::-;;;;;;;;;58459:48;;58545:11;58520:10;58531;58520:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;58625:28;;;:15;:28;;;;;;;:41;;;58797:24;;;;;58790:31;58832:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;57848:1008;;;57777:1079;:::o;55267:221::-;55352:14;55369:20;55386:2;55369:16;:20::i;:::-;55400:16;;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;55445:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;55267:221:0:o;45858:291::-;46005:4;46047:41;;;46062:26;46047:41;;:94;;-1:-1:-1;28085:25:0;28070:40;;;;46105:36;27911:207;-1:-1:-1;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:177:1;99:66;92:5;88:78;81:5;78:89;68:117;;181:1;178;171:12;196:245;254:6;307:2;295:9;286:7;282:23;278:32;275:52;;;323:1;320;313:12;275:52;362:9;349:23;381:30;405:5;381:30;:::i;894:258::-;966:1;976:113;990:6;987:1;984:13;976:113;;;1066:11;;;1060:18;1047:11;;;1040:39;1012:2;1005:10;976:113;;;1107:6;1104:1;1101:13;1098:48;;;-1:-1:-1;;1142:1:1;1124:16;;1117:27;894:258::o;1157:317::-;1199:3;1237:5;1231:12;1264:6;1259:3;1252:19;1280:63;1336:6;1329:4;1324:3;1320:14;1313:4;1306:5;1302:16;1280:63;:::i;:::-;1388:2;1376:15;1393:66;1372:88;1363:98;;;;1463:4;1359:109;;1157:317;-1:-1:-1;;1157:317:1:o;1479:220::-;1628:2;1617:9;1610:21;1591:4;1648:45;1689:2;1678:9;1674:18;1666:6;1648:45;:::i;1704:180::-;1763:6;1816:2;1804:9;1795:7;1791:23;1787:32;1784:52;;;1832:1;1829;1822:12;1784:52;-1:-1:-1;1855:23:1;;1704:180;-1:-1:-1;1704:180:1:o;2120:154::-;2206:42;2199:5;2195:54;2188:5;2185:65;2175:93;;2264:1;2261;2254:12;2279:315;2347:6;2355;2408:2;2396:9;2387:7;2383:23;2379:32;2376:52;;;2424:1;2421;2414:12;2376:52;2463:9;2450:23;2482:31;2507:5;2482:31;:::i;:::-;2532:5;2584:2;2569:18;;;;2556:32;;-1:-1:-1;;;2279:315:1:o;2599:632::-;2770:2;2822:21;;;2892:13;;2795:18;;;2914:22;;;2741:4;;2770:2;2993:15;;;;2967:2;2952:18;;;2741:4;3036:169;3050:6;3047:1;3044:13;3036:169;;;3111:13;;3099:26;;3180:15;;;;3145:12;;;;3072:1;3065:9;3036:169;;;-1:-1:-1;3222:3:1;;2599:632;-1:-1:-1;;;;;;2599:632:1:o;3236:292::-;3294:6;3347:2;3335:9;3326:7;3322:23;3318:32;3315:52;;;3363:1;3360;3353:12;3315:52;3402:9;3389:23;3452:26;3445:5;3441:38;3434:5;3431:49;3421:77;;3494:1;3491;3484:12;3715:456;3792:6;3800;3808;3861:2;3849:9;3840:7;3836:23;3832:32;3829:52;;;3877:1;3874;3867:12;3829:52;3916:9;3903:23;3935:31;3960:5;3935:31;:::i;:::-;3985:5;-1:-1:-1;4042:2:1;4027:18;;4014:32;4055:33;4014:32;4055:33;:::i;:::-;3715:456;;4107:7;;-1:-1:-1;;;4161:2:1;4146:18;;;;4133:32;;3715:456::o;4543:248::-;4611:6;4619;4672:2;4660:9;4651:7;4647:23;4643:32;4640:52;;;4688:1;4685;4678:12;4640:52;-1:-1:-1;;4711:23:1;;;4781:2;4766:18;;;4753:32;;-1:-1:-1;4543:248:1:o;5098:315::-;5166:6;5174;5227:2;5215:9;5206:7;5202:23;5198:32;5195:52;;;5243:1;5240;5233:12;5195:52;5279:9;5266:23;5256:33;;5339:2;5328:9;5324:18;5311:32;5352:31;5377:5;5352:31;:::i;:::-;5402:5;5392:15;;;5098:315;;;;;:::o;5678:247::-;5737:6;5790:2;5778:9;5769:7;5765:23;5761:32;5758:52;;;5806:1;5803;5796:12;5758:52;5845:9;5832:23;5864:31;5889:5;5864:31;:::i;6195:184::-;6247:77;6244:1;6237:88;6344:4;6341:1;6334:15;6368:4;6365:1;6358:15;6384:691;6449:5;6479:18;6520:2;6512:6;6509:14;6506:40;;;6526:18;;:::i;:::-;6660:2;6654:9;6726:2;6714:15;;6565:66;6710:24;;;6736:2;6706:33;6702:42;6690:55;;;6760:18;;;6780:22;;;6757:46;6754:72;;;6806:18;;:::i;:::-;6846:10;6842:2;6835:22;6875:6;6866:15;;6905:6;6897;6890:22;6945:3;6936:6;6931:3;6927:16;6924:25;6921:45;;;6962:1;6959;6952:12;6921:45;7012:6;7007:3;7000:4;6992:6;6988:17;6975:44;7067:1;7060:4;7051:6;7043;7039:19;7035:30;7028:41;;;;6384:691;;;;;:::o;7080:451::-;7149:6;7202:2;7190:9;7181:7;7177:23;7173:32;7170:52;;;7218:1;7215;7208:12;7170:52;7258:9;7245:23;7291:18;7283:6;7280:30;7277:50;;;7323:1;7320;7313:12;7277:50;7346:22;;7399:4;7391:13;;7387:27;-1:-1:-1;7377:55:1;;7428:1;7425;7418:12;7377:55;7451:74;7517:7;7512:2;7499:16;7494:2;7490;7486:11;7451:74;:::i;7536:269::-;7593:6;7646:2;7634:9;7625:7;7621:23;7617:32;7614:52;;;7662:1;7659;7652:12;7614:52;7701:9;7688:23;7751:4;7744:5;7740:16;7733:5;7730:27;7720:55;;7771:1;7768;7761:12;8520:118;8606:5;8599:13;8592:21;8585:5;8582:32;8572:60;;8628:1;8625;8618:12;8643:382;8708:6;8716;8769:2;8757:9;8748:7;8744:23;8740:32;8737:52;;;8785:1;8782;8775:12;8737:52;8824:9;8811:23;8843:31;8868:5;8843:31;:::i;:::-;8893:5;-1:-1:-1;8950:2:1;8935:18;;8922:32;8963:30;8922:32;8963:30;:::i;9030:795::-;9125:6;9133;9141;9149;9202:3;9190:9;9181:7;9177:23;9173:33;9170:53;;;9219:1;9216;9209:12;9170:53;9258:9;9245:23;9277:31;9302:5;9277:31;:::i;:::-;9327:5;-1:-1:-1;9384:2:1;9369:18;;9356:32;9397:33;9356:32;9397:33;:::i;:::-;9449:7;-1:-1:-1;9503:2:1;9488:18;;9475:32;;-1:-1:-1;9558:2:1;9543:18;;9530:32;9585:18;9574:30;;9571:50;;;9617:1;9614;9607:12;9571:50;9640:22;;9693:4;9685:13;;9681:27;-1:-1:-1;9671:55:1;;9722:1;9719;9712:12;9671:55;9745:74;9811:7;9806:2;9793:16;9788:2;9784;9780:11;9745:74;:::i;:::-;9735:84;;;9030:795;;;;;;;:::o;9830:388::-;9898:6;9906;9959:2;9947:9;9938:7;9934:23;9930:32;9927:52;;;9975:1;9972;9965:12;9927:52;10014:9;10001:23;10033:31;10058:5;10033:31;:::i;:::-;10083:5;-1:-1:-1;10140:2:1;10125:18;;10112:32;10153:33;10112:32;10153:33;:::i;10223:437::-;10302:1;10298:12;;;;10345;;;10366:61;;10420:4;10412:6;10408:17;10398:27;;10366:61;10473:2;10465:6;10462:14;10442:18;10439:38;10436:218;;;10510:77;10507:1;10500:88;10611:4;10608:1;10601:15;10639:4;10636:1;10629:15;11905:184;11957:77;11954:1;11947:88;12054:4;12051:1;12044:15;12078:4;12075:1;12068:15;12094:184;12146:77;12143:1;12136:88;12243:4;12240:1;12233:15;12267:4;12264:1;12257:15;12283:195;12322:3;12353:66;12346:5;12343:77;12340:103;;;12423:18;;:::i;:::-;-1:-1:-1;12470:1:1;12459:13;;12283:195::o;13579:184::-;13649:6;13702:2;13690:9;13681:7;13677:23;13673:32;13670:52;;;13718:1;13715;13708:12;13670:52;-1:-1:-1;13741:16:1;;13579:184;-1:-1:-1;13579:184:1:o;14605:228::-;14645:7;14771:1;14703:66;14699:74;14696:1;14693:81;14688:1;14681:9;14674:17;14670:105;14667:131;;;14778:18;;:::i;:::-;-1:-1:-1;14818:9:1;;14605:228::o;14838:184::-;14890:77;14887:1;14880:88;14987:4;14984:1;14977:15;15011:4;15008:1;15001:15;15027:120;15067:1;15093;15083:35;;15098:18;;:::i;:::-;-1:-1:-1;15132:9:1;;15027:120::o;19865:1088::-;19950:12;;19915:3;;20005:1;20025:18;;;;20078;;;;20105:61;;20159:4;20151:6;20147:17;20137:27;;20105:61;20185:2;20233;20225:6;20222:14;20202:18;20199:38;20196:218;;;20270:77;20267:1;20260:88;20371:4;20368:1;20361:15;20399:4;20396:1;20389:15;20196:218;20430:18;20457:162;;;;20633:1;20628:319;;;;20423:524;;20457:162;20505:66;20494:9;20490:82;20485:3;20478:95;20602:6;20597:3;20593:16;20586:23;;20457:162;;20628:319;19812:1;19805:14;;;19849:4;19836:18;;20722:1;20736:165;20750:6;20747:1;20744:13;20736:165;;;20828:14;;20815:11;;;20808:35;20871:16;;;;20765:10;;20736:165;;;20740:3;;20930:6;20925:3;20921:16;20914:23;;20423:524;;;;;;;19865:1088;;;;:::o;20958:456::-;21179:3;21207:38;21241:3;21233:6;21207:38;:::i;:::-;21274:6;21268:13;21290:52;21335:6;21331:2;21324:4;21316:6;21312:17;21290:52;:::i;:::-;21358:50;21400:6;21396:2;21392:15;21384:6;21358:50;:::i;22522:128::-;22562:3;22593:1;22589:6;22586:1;22583:13;22580:39;;;22599:18;;:::i;:::-;-1:-1:-1;22635:9:1;;22522:128::o;24222:125::-;24262:4;24290:1;24287;24284:8;24281:34;;;24295:18;;:::i;:::-;-1:-1:-1;24332:9:1;;24222:125::o;24352:470::-;24531:3;24569:6;24563:13;24585:53;24631:6;24626:3;24619:4;24611:6;24607:17;24585:53;:::i;:::-;24701:13;;24660:16;;;;24723:57;24701:13;24660:16;24757:4;24745:17;;24723:57;:::i;:::-;24796:20;;24352:470;-1:-1:-1;;;;24352:470:1:o;25600:786::-;26011:25;26006:3;25999:38;25981:3;26066:6;26060:13;26082:62;26137:6;26132:2;26127:3;26123:12;26116:4;26108:6;26104:17;26082:62;:::i;:::-;26208:19;26203:2;26163:16;;;26195:11;;;26188:40;26253:13;;26275:63;26253:13;26324:2;26316:11;;26309:4;26297:17;;26275:63;:::i;:::-;26358:17;26377:2;26354:26;;25600:786;-1:-1:-1;;;;25600:786:1:o;27468:245::-;27535:6;27588:2;27576:9;27567:7;27563:23;27559:32;27556:52;;;27604:1;27601;27594:12;27556:52;27636:9;27630:16;27655:28;27677:5;27655:28;:::i;28129:112::-;28161:1;28187;28177:35;;28192:18;;:::i;:::-;-1:-1:-1;28226:9:1;;28129:112::o;28246:196::-;28285:3;28313:5;28303:39;;28322:18;;:::i;:::-;-1:-1:-1;28369:66:1;28358:78;;28246:196::o;28808:512::-;29002:4;29031:42;29112:2;29104:6;29100:15;29089:9;29082:34;29164:2;29156:6;29152:15;29147:2;29136:9;29132:18;29125:43;;29204:6;29199:2;29188:9;29184:18;29177:34;29247:3;29242:2;29231:9;29227:18;29220:31;29268:46;29309:3;29298:9;29294:19;29286:6;29268:46;:::i;:::-;29260:54;28808:512;-1:-1:-1;;;;;;28808:512:1:o;29325:249::-;29394:6;29447:2;29435:9;29426:7;29422:23;29418:32;29415:52;;;29463:1;29460;29453:12;29415:52;29495:9;29489:16;29514:30;29538:5;29514:30;:::i;29991:184::-;30043:77;30040:1;30033:88;30140:4;30137:1;30130:15;30164:4;30161:1;30154:15;31663:274;31792:3;31830:6;31824:13;31846:53;31892:6;31887:3;31880:4;31872:6;31868:17;31846:53;:::i;:::-;31915:16;;;;;31663:274;-1:-1:-1;;31663:274:1:o

Swarm Source

ipfs://8d2e5667d706f0318413a45098f3f617b56728a8b5ceb6eb2023c85f6f56ba62
Loading