ETH Price: $2,506.12 (-4.87%)

Token

Robotic_Rabbit_Syndicate (Robotic Rabbit Syndicate)
 

Overview

Max Total Supply

3,333 Robotic Rabbit Syndicate

Holders

417

Market

Volume (24H)

0.019 ETH

Min Price (24H)

$7.52 @ 0.003000 ETH

Max Price (24H)

$25.06 @ 0.010000 ETH
Balance
1 Robotic Rabbit Syndicate
0x4c1aa634E5d12681b1C3f167838Cad1D8c10Ef16
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
Robotic_Rabbit_Syndicate

Compiler Version
v0.8.20+commit.a1b79de6

Optimization Enabled:
No with 200 runs

Other Settings:
london EvmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2024-03-20
*/

// SPDX-License-Identifier: MIT
// File: @openzeppelin/contracts/interfaces/IERC5267.sol


// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC5267.sol)

pragma solidity ^0.8.20;

interface IERC5267 {
    /**
     * @dev MAY be emitted to signal that the domain could have changed.
     */
    event EIP712DomainChanged();

    /**
     * @dev returns the fields and values that describe the domain separator used by this contract for EIP-712
     * signature.
     */
    function eip712Domain()
        external
        view
        returns (
            bytes1 fields,
            string memory name,
            string memory version,
            uint256 chainId,
            address verifyingContract,
            bytes32 salt,
            uint256[] memory extensions
        );
}

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


// OpenZeppelin Contracts (last updated v5.0.0) (utils/StorageSlot.sol)
// This file was procedurally generated from scripts/generate/templates/StorageSlot.js.

pragma solidity ^0.8.20;

/**
 * @dev Library for reading and writing primitive types to specific storage slots.
 *
 * Storage slots are often used to avoid storage conflict when dealing with upgradeable contracts.
 * This library helps with reading and writing to such slots without the need for inline assembly.
 *
 * The functions in this library return Slot structs that contain a `value` member that can be used to read or write.
 *
 * Example usage to set ERC1967 implementation slot:
 * ```solidity
 * contract ERC1967 {
 *     bytes32 internal constant _IMPLEMENTATION_SLOT = 0x360894a13ba1a3210667c828492db98dca3e2076cc3735a920a3ca505d382bbc;
 *
 *     function _getImplementation() internal view returns (address) {
 *         return StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value;
 *     }
 *
 *     function _setImplementation(address newImplementation) internal {
 *         require(newImplementation.code.length > 0);
 *         StorageSlot.getAddressSlot(_IMPLEMENTATION_SLOT).value = newImplementation;
 *     }
 * }
 * ```
 */
library StorageSlot {
    struct AddressSlot {
        address value;
    }

    struct BooleanSlot {
        bool value;
    }

    struct Bytes32Slot {
        bytes32 value;
    }

    struct Uint256Slot {
        uint256 value;
    }

    struct StringSlot {
        string value;
    }

    struct BytesSlot {
        bytes value;
    }

    /**
     * @dev Returns an `AddressSlot` with member `value` located at `slot`.
     */
    function getAddressSlot(bytes32 slot) internal pure returns (AddressSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `BooleanSlot` with member `value` located at `slot`.
     */
    function getBooleanSlot(bytes32 slot) internal pure returns (BooleanSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Bytes32Slot` with member `value` located at `slot`.
     */
    function getBytes32Slot(bytes32 slot) internal pure returns (Bytes32Slot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `Uint256Slot` with member `value` located at `slot`.
     */
    function getUint256Slot(bytes32 slot) internal pure returns (Uint256Slot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `StringSlot` with member `value` located at `slot`.
     */
    function getStringSlot(bytes32 slot) internal pure returns (StringSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `StringSlot` representation of the string storage pointer `store`.
     */
    function getStringSlot(string storage store) internal pure returns (StringSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := store.slot
        }
    }

    /**
     * @dev Returns an `BytesSlot` with member `value` located at `slot`.
     */
    function getBytesSlot(bytes32 slot) internal pure returns (BytesSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := slot
        }
    }

    /**
     * @dev Returns an `BytesSlot` representation of the bytes storage pointer `store`.
     */
    function getBytesSlot(bytes storage store) internal pure returns (BytesSlot storage r) {
        /// @solidity memory-safe-assembly
        assembly {
            r.slot := store.slot
        }
    }
}

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


// OpenZeppelin Contracts (last updated v5.0.0) (utils/ShortStrings.sol)

pragma solidity ^0.8.20;


// | string  | 0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA   |
// | length  | 0x                                                              BB |
type ShortString is bytes32;

/**
 * @dev This library provides functions to convert short memory strings
 * into a `ShortString` type that can be used as an immutable variable.
 *
 * Strings of arbitrary length can be optimized using this library if
 * they are short enough (up to 31 bytes) by packing them with their
 * length (1 byte) in a single EVM word (32 bytes). Additionally, a
 * fallback mechanism can be used for every other case.
 *
 * Usage example:
 *
 * ```solidity
 * contract Named {
 *     using ShortStrings for *;
 *
 *     ShortString private immutable _name;
 *     string private _nameFallback;
 *
 *     constructor(string memory contractName) {
 *         _name = contractName.toShortStringWithFallback(_nameFallback);
 *     }
 *
 *     function name() external view returns (string memory) {
 *         return _name.toStringWithFallback(_nameFallback);
 *     }
 * }
 * ```
 */
library ShortStrings {
    // Used as an identifier for strings longer than 31 bytes.
    bytes32 private constant FALLBACK_SENTINEL = 0x00000000000000000000000000000000000000000000000000000000000000FF;

    error StringTooLong(string str);
    error InvalidShortString();

    /**
     * @dev Encode a string of at most 31 chars into a `ShortString`.
     *
     * This will trigger a `StringTooLong` error is the input string is too long.
     */
    function toShortString(string memory str) internal pure returns (ShortString) {
        bytes memory bstr = bytes(str);
        if (bstr.length > 31) {
            revert StringTooLong(str);
        }
        return ShortString.wrap(bytes32(uint256(bytes32(bstr)) | bstr.length));
    }

    /**
     * @dev Decode a `ShortString` back to a "normal" string.
     */
    function toString(ShortString sstr) internal pure returns (string memory) {
        uint256 len = byteLength(sstr);
        // using `new string(len)` would work locally but is not memory safe.
        string memory str = new string(32);
        /// @solidity memory-safe-assembly
        assembly {
            mstore(str, len)
            mstore(add(str, 0x20), sstr)
        }
        return str;
    }

    /**
     * @dev Return the length of a `ShortString`.
     */
    function byteLength(ShortString sstr) internal pure returns (uint256) {
        uint256 result = uint256(ShortString.unwrap(sstr)) & 0xFF;
        if (result > 31) {
            revert InvalidShortString();
        }
        return result;
    }

    /**
     * @dev Encode a string into a `ShortString`, or write it to storage if it is too long.
     */
    function toShortStringWithFallback(string memory value, string storage store) internal returns (ShortString) {
        if (bytes(value).length < 32) {
            return toShortString(value);
        } else {
            StorageSlot.getStringSlot(store).value = value;
            return ShortString.wrap(FALLBACK_SENTINEL);
        }
    }

    /**
     * @dev Decode a string that was encoded to `ShortString` or written to storage using {setWithFallback}.
     */
    function toStringWithFallback(ShortString value, string storage store) internal pure returns (string memory) {
        if (ShortString.unwrap(value) != FALLBACK_SENTINEL) {
            return toString(value);
        } else {
            return store;
        }
    }

    /**
     * @dev Return the length of a string that was encoded to `ShortString` or written to storage using
     * {setWithFallback}.
     *
     * WARNING: This will return the "byte length" of the string. This may not reflect the actual length in terms of
     * actual characters as the UTF-8 encoding of a single character can span over multiple bytes.
     */
    function byteLengthWithFallback(ShortString value, string storage store) internal view returns (uint256) {
        if (ShortString.unwrap(value) != FALLBACK_SENTINEL) {
            return byteLength(value);
        } else {
            return bytes(store).length;
        }
    }
}

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


// OpenZeppelin Contracts (last updated v5.0.0) (utils/Address.sol)

pragma solidity ^0.8.20;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev The ETH balance of the account is not enough to perform the operation.
     */
    error AddressInsufficientBalance(address account);

    /**
     * @dev There's no code at `target` (it is not a contract).
     */
    error AddressEmptyCode(address target);

    /**
     * @dev A call to an address target failed. The target may have reverted.
     */
    error FailedInnerCall();

    /**
     * @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://consensys.net/diligence/blog/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.8.20/security-considerations.html#use-the-checks-effects-interactions-pattern[checks-effects-interactions pattern].
     */
    function sendValue(address payable recipient, uint256 amount) internal {
        if (address(this).balance < amount) {
            revert AddressInsufficientBalance(address(this));
        }

        (bool success, ) = recipient.call{value: amount}("");
        if (!success) {
            revert FailedInnerCall();
        }
    }

    /**
     * @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 or custom error, it is bubbled
     * up by this function (like regular Solidity function calls). However, if
     * the call reverted with no returned reason, this function reverts with a
     * {FailedInnerCall} error.
     *
     * 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.
     */
    function functionCall(address target, bytes memory data) internal returns (bytes memory) {
        return functionCallWithValue(target, data, 0);
    }

    /**
     * @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`.
     */
    function functionCallWithValue(address target, bytes memory data, uint256 value) internal returns (bytes memory) {
        if (address(this).balance < value) {
            revert AddressInsufficientBalance(address(this));
        }
        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a static call.
     */
    function functionStaticCall(address target, bytes memory data) internal view returns (bytes memory) {
        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-}[`functionCall`],
     * but performing a delegate call.
     */
    function functionDelegateCall(address target, bytes memory data) internal returns (bytes memory) {
        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResultFromTarget(target, success, returndata);
    }

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and reverts if the target
     * was not a contract or bubbling up the revert reason (falling back to {FailedInnerCall}) in case of an
     * unsuccessful call.
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata
    ) internal view returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            // only check if target is a contract if the call was successful and the return data is empty
            // otherwise we already know that it was a contract
            if (returndata.length == 0 && target.code.length == 0) {
                revert AddressEmptyCode(target);
            }
            return returndata;
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and reverts if it wasn't, either by bubbling the
     * revert reason or with a default {FailedInnerCall} error.
     */
    function verifyCallResult(bool success, bytes memory returndata) internal pure returns (bytes memory) {
        if (!success) {
            _revert(returndata);
        } else {
            return returndata;
        }
    }

    /**
     * @dev Reverts with returndata if present. Otherwise reverts with {FailedInnerCall}.
     */
    function _revert(bytes memory returndata) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert FailedInnerCall();
        }
    }
}

// File: @openzeppelin/contracts/interfaces/draft-IERC6093.sol


// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/draft-IERC6093.sol)
pragma solidity ^0.8.20;

/**
 * @dev Standard ERC20 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC20 tokens.
 */
interface IERC20Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientBalance(address sender, uint256 balance, uint256 needed);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC20InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC20InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `spender`’s `allowance`. Used in transfers.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     * @param allowance Amount of tokens a `spender` is allowed to operate with.
     * @param needed Minimum amount required to perform a transfer.
     */
    error ERC20InsufficientAllowance(address spender, uint256 allowance, uint256 needed);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC20InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `spender` to be approved. Used in approvals.
     * @param spender Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC20InvalidSpender(address spender);
}

/**
 * @dev Standard ERC721 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC721 tokens.
 */
interface IERC721Errors {
    /**
     * @dev Indicates that an address can't be an owner. For example, `address(0)` is a forbidden owner in EIP-20.
     * Used in balance queries.
     * @param owner Address of the current owner of a token.
     */
    error ERC721InvalidOwner(address owner);

    /**
     * @dev Indicates a `tokenId` whose `owner` is the zero address.
     * @param tokenId Identifier number of a token.
     */
    error ERC721NonexistentToken(uint256 tokenId);

    /**
     * @dev Indicates an error related to the ownership over a particular token. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param tokenId Identifier number of a token.
     * @param owner Address of the current owner of a token.
     */
    error ERC721IncorrectOwner(address sender, uint256 tokenId, address owner);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC721InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC721InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param tokenId Identifier number of a token.
     */
    error ERC721InsufficientApproval(address operator, uint256 tokenId);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC721InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC721InvalidOperator(address operator);
}

/**
 * @dev Standard ERC1155 Errors
 * Interface of the https://eips.ethereum.org/EIPS/eip-6093[ERC-6093] custom errors for ERC1155 tokens.
 */
interface IERC1155Errors {
    /**
     * @dev Indicates an error related to the current `balance` of a `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     * @param balance Current balance for the interacting account.
     * @param needed Minimum amount required to perform a transfer.
     * @param tokenId Identifier number of a token.
     */
    error ERC1155InsufficientBalance(address sender, uint256 balance, uint256 needed, uint256 tokenId);

    /**
     * @dev Indicates a failure with the token `sender`. Used in transfers.
     * @param sender Address whose tokens are being transferred.
     */
    error ERC1155InvalidSender(address sender);

    /**
     * @dev Indicates a failure with the token `receiver`. Used in transfers.
     * @param receiver Address to which tokens are being transferred.
     */
    error ERC1155InvalidReceiver(address receiver);

    /**
     * @dev Indicates a failure with the `operator`’s approval. Used in transfers.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     * @param owner Address of the current owner of a token.
     */
    error ERC1155MissingApprovalForAll(address operator, address owner);

    /**
     * @dev Indicates a failure with the `approver` of a token to be approved. Used in approvals.
     * @param approver Address initiating an approval operation.
     */
    error ERC1155InvalidApprover(address approver);

    /**
     * @dev Indicates a failure with the `operator` to be approved. Used in approvals.
     * @param operator Address that may be allowed to operate on tokens without being their owner.
     */
    error ERC1155InvalidOperator(address operator);

    /**
     * @dev Indicates an array length mismatch between ids and values in a safeBatchTransferFrom operation.
     * Used in batch transfers.
     * @param idsLength Length of the array of token identifiers
     * @param valuesLength Length of the array of token amounts
     */
    error ERC1155InvalidArrayLength(uint256 idsLength, uint256 valuesLength);
}

// File: @openzeppelin/contracts/utils/math/SignedMath.sol


// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/SignedMath.sol)

pragma solidity ^0.8.20;

/**
 * @dev Standard signed math utilities missing in the Solidity language.
 */
library SignedMath {
    /**
     * @dev Returns the largest of two signed numbers.
     */
    function max(int256 a, int256 b) internal pure returns (int256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two signed numbers.
     */
    function min(int256 a, int256 b) internal pure returns (int256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two signed numbers without overflow.
     * The result is rounded towards zero.
     */
    function average(int256 a, int256 b) internal pure returns (int256) {
        // Formula from the book "Hacker's Delight"
        int256 x = (a & b) + ((a ^ b) >> 1);
        return x + (int256(uint256(x) >> 255) & (a ^ b));
    }

    /**
     * @dev Returns the absolute unsigned value of a signed value.
     */
    function abs(int256 n) internal pure returns (uint256) {
        unchecked {
            // must be unchecked in order to support `n = type(int256).min`
            return uint256(n >= 0 ? n : -n);
        }
    }
}

// File: @openzeppelin/contracts/utils/math/Math.sol


// OpenZeppelin Contracts (last updated v5.0.0) (utils/math/Math.sol)

pragma solidity ^0.8.20;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    /**
     * @dev Muldiv operation overflow.
     */
    error MathOverflowedMulDiv();

    enum Rounding {
        Floor, // Toward negative infinity
        Ceil, // Toward positive infinity
        Trunc, // Toward zero
        Expand // Away from zero
    }

    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, with an overflow flag.
     */
    function trySub(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b > a) return (false, 0);
            return (true, a - b);
        }
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, with an overflow flag.
     */
    function tryMul(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            // Gas optimization: this is cheaper than requiring 'a' not being zero, but the
            // benefit is lost if 'b' is also tested.
            // See: https://github.com/OpenZeppelin/openzeppelin-contracts/pull/522
            if (a == 0) return (true, 0);
            uint256 c = a * b;
            if (c / a != b) return (false, 0);
            return (true, c);
        }
    }

    /**
     * @dev Returns the division of two unsigned integers, with a division by zero flag.
     */
    function tryDiv(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a / b);
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers, with a division by zero flag.
     */
    function tryMod(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            if (b == 0) return (false, 0);
            return (true, a % b);
        }
    }

    /**
     * @dev Returns the largest of two numbers.
     */
    function max(uint256 a, uint256 b) internal pure returns (uint256) {
        return a > b ? a : b;
    }

    /**
     * @dev Returns the smallest of two numbers.
     */
    function min(uint256 a, uint256 b) internal pure returns (uint256) {
        return a < b ? a : b;
    }

    /**
     * @dev Returns the average of two numbers. The result is rounded towards
     * zero.
     */
    function average(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b) / 2 can overflow.
        return (a & b) + (a ^ b) / 2;
    }

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds towards infinity instead
     * of rounding towards zero.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        if (b == 0) {
            // Guarantee the same behavior as in a regular Solidity division.
            return a / b;
        }

        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

    /**
     * @notice Calculates floor(x * y / denominator) with full precision. Throws if result overflows a uint256 or
     * denominator == 0.
     * @dev Original credit to Remco Bloemen under MIT license (https://xn--2-umb.com/21/muldiv) with further edits by
     * Uniswap Labs also under MIT license.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator) internal pure returns (uint256 result) {
        unchecked {
            // 512-bit multiply [prod1 prod0] = x * y. Compute the product mod 2^256 and mod 2^256 - 1, then use
            // use the Chinese Remainder Theorem to reconstruct the 512 bit result. The result is stored in two 256
            // variables such that product = prod1 * 2^256 + prod0.
            uint256 prod0 = x * y; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // Solidity will revert if denominator == 0, unlike the div opcode on its own.
                // The surrounding unchecked block does not change this fact.
                // See https://docs.soliditylang.org/en/latest/control-structures.html#checked-or-unchecked-arithmetic.
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            if (denominator <= prod1) {
                revert MathOverflowedMulDiv();
            }

            ///////////////////////////////////////////////
            // 512 by 256 division.
            ///////////////////////////////////////////////

            // Make division exact by subtracting the remainder from [prod1 prod0].
            uint256 remainder;
            assembly {
                // Compute remainder using mulmod.
                remainder := mulmod(x, y, denominator)

                // Subtract 256 bit number from 512 bit number.
                prod1 := sub(prod1, gt(remainder, prod0))
                prod0 := sub(prod0, remainder)
            }

            // Factor powers of two out of denominator and compute largest power of two divisor of denominator.
            // Always >= 1. See https://cs.stackexchange.com/q/138556/92363.

            uint256 twos = denominator & (0 - denominator);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

                // Divide [prod1 prod0] by twos.
                prod0 := div(prod0, twos)

                // Flip twos such that it is 2^256 / twos. If twos is zero, then it becomes one.
                twos := add(div(sub(0, twos), twos), 1)
            }

            // Shift in bits from prod1 into prod0.
            prod0 |= prod1 * twos;

            // Invert denominator mod 2^256. Now that denominator is an odd number, it has an inverse modulo 2^256 such
            // that denominator * inv = 1 mod 2^256. Compute the inverse by starting with a seed that is correct for
            // four bits. That is, denominator * inv = 1 mod 2^4.
            uint256 inverse = (3 * denominator) ^ 2;

            // Use the Newton-Raphson iteration to improve the precision. Thanks to Hensel's lifting lemma, this also
            // works in modular arithmetic, doubling the correct bits in each step.
            inverse *= 2 - denominator * inverse; // inverse mod 2^8
            inverse *= 2 - denominator * inverse; // inverse mod 2^16
            inverse *= 2 - denominator * inverse; // inverse mod 2^32
            inverse *= 2 - denominator * inverse; // inverse mod 2^64
            inverse *= 2 - denominator * inverse; // inverse mod 2^128
            inverse *= 2 - denominator * inverse; // inverse mod 2^256

            // Because the division is now exact we can divide by multiplying with the modular inverse of denominator.
            // This will give us the correct result modulo 2^256. Since the preconditions guarantee that the outcome is
            // less than 2^256, this is the final result. We don't need to compute the high bits of the result and prod1
            // is no longer required.
            result = prod0 * inverse;
            return result;
        }
    }

    /**
     * @notice Calculates x * y / denominator with full precision, following the selected rounding direction.
     */
    function mulDiv(uint256 x, uint256 y, uint256 denominator, Rounding rounding) internal pure returns (uint256) {
        uint256 result = mulDiv(x, y, denominator);
        if (unsignedRoundsUp(rounding) && mulmod(x, y, denominator) > 0) {
            result += 1;
        }
        return result;
    }

    /**
     * @dev Returns the square root of a number. If the number is not a perfect square, the value is rounded
     * towards zero.
     *
     * Inspired by Henry S. Warren, Jr.'s "Hacker's Delight" (Chapter 11).
     */
    function sqrt(uint256 a) internal pure returns (uint256) {
        if (a == 0) {
            return 0;
        }

        // For our first guess, we get the biggest power of 2 which is smaller than the square root of the target.
        //
        // We know that the "msb" (most significant bit) of our target number `a` is a power of 2 such that we have
        // `msb(a) <= a < 2*msb(a)`. This value can be written `msb(a)=2**k` with `k=log2(a)`.
        //
        // This can be rewritten `2**log2(a) <= a < 2**(log2(a) + 1)`
        // → `sqrt(2**k) <= sqrt(a) < sqrt(2**(k+1))`
        // → `2**(k/2) <= sqrt(a) < 2**((k+1)/2) <= 2**(k/2 + 1)`
        //
        // Consequently, `2**(log2(a) / 2)` is a good first approximation of `sqrt(a)` with at least 1 correct bit.
        uint256 result = 1 << (log2(a) >> 1);

        // At this point `result` is an estimation with one bit of precision. We know the true value is a uint128,
        // since it is the square root of a uint256. Newton's method converges quadratically (precision doubles at
        // every iteration). We thus need at most 7 iteration to turn our partial result with one bit of precision
        // into the expected uint128 result.
        unchecked {
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            result = (result + a / result) >> 1;
            return min(result, a / result);
        }
    }

    /**
     * @notice Calculates sqrt(a), following the selected rounding direction.
     */
    function sqrt(uint256 a, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = sqrt(a);
            return result + (unsignedRoundsUp(rounding) && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2 of a positive value rounded towards zero.
     * Returns 0 if given 0.
     */
    function log2(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 128;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 64;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 32;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 16;
            }
            if (value >> 8 > 0) {
                value >>= 8;
                result += 8;
            }
            if (value >> 4 > 0) {
                value >>= 4;
                result += 4;
            }
            if (value >> 2 > 0) {
                value >>= 2;
                result += 2;
            }
            if (value >> 1 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 2, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log2(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log2(value);
            return result + (unsignedRoundsUp(rounding) && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10 of a positive value rounded towards zero.
     * Returns 0 if given 0.
     */
    function log10(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >= 10 ** 64) {
                value /= 10 ** 64;
                result += 64;
            }
            if (value >= 10 ** 32) {
                value /= 10 ** 32;
                result += 32;
            }
            if (value >= 10 ** 16) {
                value /= 10 ** 16;
                result += 16;
            }
            if (value >= 10 ** 8) {
                value /= 10 ** 8;
                result += 8;
            }
            if (value >= 10 ** 4) {
                value /= 10 ** 4;
                result += 4;
            }
            if (value >= 10 ** 2) {
                value /= 10 ** 2;
                result += 2;
            }
            if (value >= 10 ** 1) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 10, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log10(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log10(value);
            return result + (unsignedRoundsUp(rounding) && 10 ** result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256 of a positive value rounded towards zero.
     * Returns 0 if given 0.
     *
     * Adding one to the result gives the number of pairs of hex symbols needed to represent `value` as a hex string.
     */
    function log256(uint256 value) internal pure returns (uint256) {
        uint256 result = 0;
        unchecked {
            if (value >> 128 > 0) {
                value >>= 128;
                result += 16;
            }
            if (value >> 64 > 0) {
                value >>= 64;
                result += 8;
            }
            if (value >> 32 > 0) {
                value >>= 32;
                result += 4;
            }
            if (value >> 16 > 0) {
                value >>= 16;
                result += 2;
            }
            if (value >> 8 > 0) {
                result += 1;
            }
        }
        return result;
    }

    /**
     * @dev Return the log in base 256, following the selected rounding direction, of a positive value.
     * Returns 0 if given 0.
     */
    function log256(uint256 value, Rounding rounding) internal pure returns (uint256) {
        unchecked {
            uint256 result = log256(value);
            return result + (unsignedRoundsUp(rounding) && 1 << (result << 3) < value ? 1 : 0);
        }
    }

    /**
     * @dev Returns whether a provided rounding mode is considered rounding up for unsigned integers.
     */
    function unsignedRoundsUp(Rounding rounding) internal pure returns (bool) {
        return uint8(rounding) % 2 == 1;
    }
}

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


// OpenZeppelin Contracts (last updated v5.0.0) (utils/Strings.sol)

pragma solidity ^0.8.20;



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

    /**
     * @dev The `value` string doesn't fit in the specified `length`.
     */
    error StringsInsufficientHexLength(uint256 value, uint256 length);

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        unchecked {
            uint256 length = Math.log10(value) + 1;
            string memory buffer = new string(length);
            uint256 ptr;
            /// @solidity memory-safe-assembly
            assembly {
                ptr := add(buffer, add(32, length))
            }
            while (true) {
                ptr--;
                /// @solidity memory-safe-assembly
                assembly {
                    mstore8(ptr, byte(mod(value, 10), HEX_DIGITS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @dev Converts a `int256` to its ASCII `string` decimal representation.
     */
    function toStringSigned(int256 value) internal pure returns (string memory) {
        return string.concat(value < 0 ? "-" : "", toString(SignedMath.abs(value)));
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        unchecked {
            return toHexString(value, Math.log256(value) + 1);
        }
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation with fixed length.
     */
    function toHexString(uint256 value, uint256 length) internal pure returns (string memory) {
        uint256 localValue = value;
        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_DIGITS[localValue & 0xf];
            localValue >>= 4;
        }
        if (localValue != 0) {
            revert StringsInsufficientHexLength(value, length);
        }
        return string(buffer);
    }

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

    /**
     * @dev Returns true if the two strings are equal.
     */
    function equal(string memory a, string memory b) internal pure returns (bool) {
        return bytes(a).length == bytes(b).length && keccak256(bytes(a)) == keccak256(bytes(b));
    }
}

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


// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/MessageHashUtils.sol)

pragma solidity ^0.8.20;


/**
 * @dev Signature message hash utilities for producing digests to be consumed by {ECDSA} recovery or signing.
 *
 * The library provides methods for generating a hash of a message that conforms to the
 * https://eips.ethereum.org/EIPS/eip-191[EIP 191] and https://eips.ethereum.org/EIPS/eip-712[EIP 712]
 * specifications.
 */
library MessageHashUtils {
    /**
     * @dev Returns the keccak256 digest of an EIP-191 signed data with version
     * `0x45` (`personal_sign` messages).
     *
     * The digest is calculated by prefixing a bytes32 `messageHash` with
     * `"\x19Ethereum Signed Message:\n32"` and hashing the result. It corresponds with the
     * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method.
     *
     * NOTE: The `messageHash` parameter is intended to be the result of hashing a raw message with
     * keccak256, although any bytes32 value can be safely used because the final digest will
     * be re-hashed.
     *
     * See {ECDSA-recover}.
     */
    function toEthSignedMessageHash(bytes32 messageHash) internal pure returns (bytes32 digest) {
        /// @solidity memory-safe-assembly
        assembly {
            mstore(0x00, "\x19Ethereum Signed Message:\n32") // 32 is the bytes-length of messageHash
            mstore(0x1c, messageHash) // 0x1c (28) is the length of the prefix
            digest := keccak256(0x00, 0x3c) // 0x3c is the length of the prefix (0x1c) + messageHash (0x20)
        }
    }

    /**
     * @dev Returns the keccak256 digest of an EIP-191 signed data with version
     * `0x45` (`personal_sign` messages).
     *
     * The digest is calculated by prefixing an arbitrary `message` with
     * `"\x19Ethereum Signed Message:\n" + len(message)` and hashing the result. It corresponds with the
     * hash signed when using the https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`] JSON-RPC method.
     *
     * See {ECDSA-recover}.
     */
    function toEthSignedMessageHash(bytes memory message) internal pure returns (bytes32) {
        return
            keccak256(bytes.concat("\x19Ethereum Signed Message:\n", bytes(Strings.toString(message.length)), message));
    }

    /**
     * @dev Returns the keccak256 digest of an EIP-191 signed data with version
     * `0x00` (data with intended validator).
     *
     * The digest is calculated by prefixing an arbitrary `data` with `"\x19\x00"` and the intended
     * `validator` address. Then hashing the result.
     *
     * See {ECDSA-recover}.
     */
    function toDataWithIntendedValidatorHash(address validator, bytes memory data) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked(hex"19_00", validator, data));
    }

    /**
     * @dev Returns the keccak256 digest of an EIP-712 typed data (EIP-191 version `0x01`).
     *
     * The digest is calculated from a `domainSeparator` and a `structHash`, by prefixing them with
     * `\x19\x01` and hashing the result. It corresponds to the hash signed by the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`] JSON-RPC method as part of EIP-712.
     *
     * See {ECDSA-recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32 digest) {
        /// @solidity memory-safe-assembly
        assembly {
            let ptr := mload(0x40)
            mstore(ptr, hex"19_01")
            mstore(add(ptr, 0x02), domainSeparator)
            mstore(add(ptr, 0x22), structHash)
            digest := keccak256(ptr, 0x42)
        }
    }
}

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


// OpenZeppelin Contracts (last updated v5.0.0) (utils/cryptography/EIP712.sol)

pragma solidity ^0.8.20;




/**
 * @dev https://eips.ethereum.org/EIPS/eip-712[EIP 712] is a standard for hashing and signing of typed structured data.
 *
 * The encoding scheme specified in the EIP requires a domain separator and a hash of the typed structured data, whose
 * encoding is very generic and therefore its implementation in Solidity is not feasible, thus this contract
 * does not implement the encoding itself. Protocols need to implement the type-specific encoding they need in order to
 * produce the hash of their typed data using a combination of `abi.encode` and `keccak256`.
 *
 * This contract implements the EIP 712 domain separator ({_domainSeparatorV4}) that is used as part of the encoding
 * scheme, and the final step of the encoding to obtain the message digest that is then signed via ECDSA
 * ({_hashTypedDataV4}).
 *
 * The implementation of the domain separator was designed to be as efficient as possible while still properly updating
 * the chain id to protect against replay attacks on an eventual fork of the chain.
 *
 * NOTE: This contract implements the version of the encoding known as "v4", as implemented by the JSON RPC method
 * https://docs.metamask.io/guide/signing-data.html[`eth_signTypedDataV4` in MetaMask].
 *
 * NOTE: In the upgradeable version of this contract, the cached values will correspond to the address, and the domain
 * separator of the implementation contract. This will cause the {_domainSeparatorV4} function to always rebuild the
 * separator from the immutable values, which is cheaper than accessing a cached version in cold storage.
 *
 * @custom:oz-upgrades-unsafe-allow state-variable-immutable
 */
abstract contract EIP712 is IERC5267 {
    using ShortStrings for *;

    bytes32 private constant TYPE_HASH =
        keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");

    // Cache the domain separator as an immutable value, but also store the chain id that it corresponds to, in order to
    // invalidate the cached domain separator if the chain id changes.
    bytes32 private immutable _cachedDomainSeparator;
    uint256 private immutable _cachedChainId;
    address private immutable _cachedThis;

    bytes32 private immutable _hashedName;
    bytes32 private immutable _hashedVersion;

    ShortString private immutable _name;
    ShortString private immutable _version;
    string private _nameFallback;
    string private _versionFallback;

    /**
     * @dev Initializes the domain separator and parameter caches.
     *
     * The meaning of `name` and `version` is specified in
     * https://eips.ethereum.org/EIPS/eip-712#definition-of-domainseparator[EIP 712]:
     *
     * - `name`: the user readable name of the signing domain, i.e. the name of the DApp or the protocol.
     * - `version`: the current major version of the signing domain.
     *
     * NOTE: These parameters cannot be changed except through a xref:learn::upgrading-smart-contracts.adoc[smart
     * contract upgrade].
     */
    constructor(string memory name, string memory version) {
        _name = name.toShortStringWithFallback(_nameFallback);
        _version = version.toShortStringWithFallback(_versionFallback);
        _hashedName = keccak256(bytes(name));
        _hashedVersion = keccak256(bytes(version));

        _cachedChainId = block.chainid;
        _cachedDomainSeparator = _buildDomainSeparator();
        _cachedThis = address(this);
    }

    /**
     * @dev Returns the domain separator for the current chain.
     */
    function _domainSeparatorV4() internal view returns (bytes32) {
        if (address(this) == _cachedThis && block.chainid == _cachedChainId) {
            return _cachedDomainSeparator;
        } else {
            return _buildDomainSeparator();
        }
    }

    function _buildDomainSeparator() private view returns (bytes32) {
        return keccak256(abi.encode(TYPE_HASH, _hashedName, _hashedVersion, block.chainid, address(this)));
    }

    /**
     * @dev Given an already https://eips.ethereum.org/EIPS/eip-712#definition-of-hashstruct[hashed struct], this
     * function returns the hash of the fully encoded EIP712 message for this domain.
     *
     * This hash can be used together with {ECDSA-recover} to obtain the signer of a message. For example:
     *
     * ```solidity
     * bytes32 digest = _hashTypedDataV4(keccak256(abi.encode(
     *     keccak256("Mail(address to,string contents)"),
     *     mailTo,
     *     keccak256(bytes(mailContents))
     * )));
     * address signer = ECDSA.recover(digest, signature);
     * ```
     */
    function _hashTypedDataV4(bytes32 structHash) internal view virtual returns (bytes32) {
        return MessageHashUtils.toTypedDataHash(_domainSeparatorV4(), structHash);
    }

    /**
     * @dev See {IERC-5267}.
     */
    function eip712Domain()
        public
        view
        virtual
        returns (
            bytes1 fields,
            string memory name,
            string memory version,
            uint256 chainId,
            address verifyingContract,
            bytes32 salt,
            uint256[] memory extensions
        )
    {
        return (
            hex"0f", // 01111
            _EIP712Name(),
            _EIP712Version(),
            block.chainid,
            address(this),
            bytes32(0),
            new uint256[](0)
        );
    }

    /**
     * @dev The name parameter for the EIP712 domain.
     *
     * NOTE: By default this function reads _name which is an immutable value.
     * It only reads from storage if necessary (in case the value is too large to fit in a ShortString).
     */
    // solhint-disable-next-line func-name-mixedcase
    function _EIP712Name() internal view returns (string memory) {
        return _name.toStringWithFallback(_nameFallback);
    }

    /**
     * @dev The version parameter for the EIP712 domain.
     *
     * NOTE: By default this function reads _version which is an immutable value.
     * It only reads from storage if necessary (in case the value is too large to fit in a ShortString).
     */
    // solhint-disable-next-line func-name-mixedcase
    function _EIP712Version() internal view returns (string memory) {
        return _version.toStringWithFallback(_versionFallback);
    }
}

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


// OpenZeppelin Contracts (last updated v5.0.1) (utils/Context.sol)

pragma solidity ^0.8.20;

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

    function _contextSuffixLength() internal view virtual returns (uint256) {
        return 0;
    }
}

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


// OpenZeppelin Contracts (last updated v5.0.0) (access/Ownable.sol)

pragma solidity ^0.8.20;


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

    /**
     * @dev The caller account is not authorized to perform an operation.
     */
    error OwnableUnauthorizedAccount(address account);

    /**
     * @dev The owner is not a valid owner account. (eg. `address(0)`)
     */
    error OwnableInvalidOwner(address owner);

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

    /**
     * @dev Initializes the contract setting the address provided by the deployer as the initial owner.
     */
    constructor(address initialOwner) {
        if (initialOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(initialOwner);
    }

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

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        if (owner() != _msgSender()) {
            revert OwnableUnauthorizedAccount(_msgSender());
        }
    }

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

    /**
     * @dev Transfers ownership of the contract to a new account (`newOwner`).
     * Can only be called by the current owner.
     */
    function transferOwnership(address newOwner) public virtual onlyOwner {
        if (newOwner == address(0)) {
            revert OwnableInvalidOwner(address(0));
        }
        _transferOwnership(newOwner);
    }

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

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


// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.20;

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

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


// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/IERC165.sol)

pragma solidity ^0.8.20;

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


// OpenZeppelin Contracts (last updated v5.0.0) (interfaces/IERC2981.sol)

pragma solidity ^0.8.20;


/**
 * @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.
 */
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 paid in that same unit of exchange.
     */
    function royaltyInfo(
        uint256 tokenId,
        uint256 salePrice
    ) external view returns (address receiver, uint256 royaltyAmount);
}

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


// OpenZeppelin Contracts (last updated v5.0.0) (utils/introspection/ERC165.sol)

pragma solidity ^0.8.20;


/**
 * @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);
 * }
 * ```
 */
abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

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


// OpenZeppelin Contracts (last updated v5.0.0) (token/common/ERC2981.sol)

pragma solidity ^0.8.20;



/**
 * @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.
 */
abstract contract ERC2981 is IERC2981, ERC165 {
    struct RoyaltyInfo {
        address receiver;
        uint96 royaltyFraction;
    }

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

    /**
     * @dev The default royalty set is invalid (eg. (numerator / denominator) >= 1).
     */
    error ERC2981InvalidDefaultRoyalty(uint256 numerator, uint256 denominator);

    /**
     * @dev The default royalty receiver is invalid.
     */
    error ERC2981InvalidDefaultRoyaltyReceiver(address receiver);

    /**
     * @dev The royalty set for an specific `tokenId` is invalid (eg. (numerator / denominator) >= 1).
     */
    error ERC2981InvalidTokenRoyalty(uint256 tokenId, uint256 numerator, uint256 denominator);

    /**
     * @dev The royalty receiver for `tokenId` is invalid.
     */
    error ERC2981InvalidTokenRoyaltyReceiver(uint256 tokenId, address receiver);

    /**
     * @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) public view virtual 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 {
        uint256 denominator = _feeDenominator();
        if (feeNumerator > denominator) {
            // Royalty fee will exceed the sale price
            revert ERC2981InvalidDefaultRoyalty(feeNumerator, denominator);
        }
        if (receiver == address(0)) {
            revert ERC2981InvalidDefaultRoyaltyReceiver(address(0));
        }

        _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:
     *
     * - `receiver` cannot be the zero address.
     * - `feeNumerator` cannot be greater than the fee denominator.
     */
    function _setTokenRoyalty(uint256 tokenId, address receiver, uint96 feeNumerator) internal virtual {
        uint256 denominator = _feeDenominator();
        if (feeNumerator > denominator) {
            // Royalty fee will exceed the sale price
            revert ERC2981InvalidTokenRoyalty(tokenId, feeNumerator, denominator);
        }
        if (receiver == address(0)) {
            revert ERC2981InvalidTokenRoyaltyReceiver(tokenId, address(0));
        }

        _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/IERC721.sol


// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.20;


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

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

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

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

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

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

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

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 tokenId) external;

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

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

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

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

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


// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.20;


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

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

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

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


// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.20;


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

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

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

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


// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/ERC721.sol)

pragma solidity ^0.8.19;








/**
 * @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}.
 */
abstract contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Errors {
    using Strings for uint256;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    mapping(uint256 tokenId => address) private _owners;

    mapping(address owner => uint256) private _balances;

    mapping(uint256 tokenId => address) private _tokenApprovals;

    mapping(address owner => mapping(address operator => 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 returns (uint256) {
        if (owner == address(0)) {
            revert ERC721InvalidOwner(address(0));
        }
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual returns (address) {
        return _requireOwned(tokenId);
    }

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

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

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual returns (string memory) {
        _requireOwned(tokenId);

        string memory baseURI = _baseURI();
        return bytes(baseURI).length > 0 ? string.concat(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 {
        _approve(to, tokenId, _msgSender());
    }

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

        return _getApproved(tokenId);
    }

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

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

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(address from, address to, uint256 tokenId) public virtual {
        if (to == address(0)) {
            revert ERC721InvalidReceiver(address(0));
        }
        // Setting an "auth" arguments enables the `_isAuthorized` check which verifies that the token exists
        // (from != 0). Therefore, it is not needed to verify that the return value is not 0 here.
        address previousOwner = _update(to, tokenId, _msgSender());
        if (previousOwner != from) {
            revert ERC721IncorrectOwner(from, tokenId, previousOwner);
        }
    }

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

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual {
        transferFrom(from, to, tokenId);
        _checkOnERC721Received(from, to, tokenId, data);
    }

    /**
     * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist
     *
     * IMPORTANT: Any overrides to this function that add ownership of tokens not tracked by the
     * core ERC721 logic MUST be matched with the use of {_increaseBalance} to keep balances
     * consistent with ownership. The invariant to preserve is that for any address `a` the value returned by
     * `balanceOf(a)` must be equal to the number of tokens such that `_ownerOf(tokenId)` is `a`.
     */
    function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
        return _owners[tokenId];
    }

    /**
     * @dev Returns the approved address for `tokenId`. Returns 0 if `tokenId` is not minted.
     */
    function _getApproved(uint256 tokenId) internal view virtual returns (address) {
        return _tokenApprovals[tokenId];
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `owner`'s tokens, or `tokenId` in
     * particular (ignoring whether it is owned by `owner`).
     *
     * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this
     * assumption.
     */
    function _isAuthorized(address owner, address spender, uint256 tokenId) internal view virtual returns (bool) {
        return
            spender != address(0) &&
            (owner == spender || isApprovedForAll(owner, spender) || _getApproved(tokenId) == spender);
    }

    /**
     * @dev Checks if `spender` can operate on `tokenId`, assuming the provided `owner` is the actual owner.
     * Reverts if `spender` does not have approval from the provided `owner` for the given token or for all its assets
     * the `spender` for the specific `tokenId`.
     *
     * WARNING: This function assumes that `owner` is the actual owner of `tokenId` and does not verify this
     * assumption.
     */
    function _checkAuthorized(address owner, address spender, uint256 tokenId) internal view virtual {
        if (!_isAuthorized(owner, spender, tokenId)) {
            if (owner == address(0)) {
                revert ERC721NonexistentToken(tokenId);
            } else {
                revert ERC721InsufficientApproval(spender, tokenId);
            }
        }
    }

    /**
     * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override.
     *
     * NOTE: the value is limited to type(uint128).max. This protect against _balance overflow. It is unrealistic that
     * a uint256 would ever overflow from increments when these increments are bounded to uint128 values.
     *
     * WARNING: Increasing an account's balance using this function tends to be paired with an override of the
     * {_ownerOf} function to resolve the ownership of the corresponding tokens so that balances and ownership
     * remain consistent with one another.
     */
    function _increaseBalance(address account, uint128 value) internal virtual {
        unchecked {
            _balances[account] += value;
        }
    }

    /**
     * @dev Transfers `tokenId` from its current owner to `to`, or alternatively mints (or burns) if the current owner
     * (or `to`) is the zero address. Returns the owner of the `tokenId` before the update.
     *
     * The `auth` argument is optional. If the value passed is non 0, then this function will check that
     * `auth` is either the owner of the token, or approved to operate on the token (by the owner).
     *
     * Emits a {Transfer} event.
     *
     * NOTE: If overriding this function in a way that tracks balances, see also {_increaseBalance}.
     */
    function _update(address to, uint256 tokenId, address auth) internal virtual returns (address) {
        address from = _ownerOf(tokenId);

        // Perform (optional) operator check
        if (auth != address(0)) {
            _checkAuthorized(from, auth, tokenId);
        }

        // Execute the update
        if (from != address(0)) {
            // Clear approval. No need to re-authorize or emit the Approval event
            _approve(address(0), tokenId, address(0), false);

            unchecked {
                _balances[from] -= 1;
            }
        }

        if (to != address(0)) {
            unchecked {
                _balances[to] += 1;
            }
        }

        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);

        return from;
    }

    /**
     * @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 {
        if (to == address(0)) {
            revert ERC721InvalidReceiver(address(0));
        }
        address previousOwner = _update(to, tokenId, address(0));
        if (previousOwner != address(0)) {
            revert ERC721InvalidSender(address(0));
        }
    }

    /**
     * @dev Mints `tokenId`, transfers it to `to` and checks for `to` acceptance.
     *
     * 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 {
        _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);
        _checkOnERC721Received(address(0), to, tokenId, data);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     * This is an internal function that does not check if the sender is authorized to operate on the token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal {
        address previousOwner = _update(address(0), tokenId, address(0));
        if (previousOwner == address(0)) {
            revert ERC721NonexistentToken(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 {
        if (to == address(0)) {
            revert ERC721InvalidReceiver(address(0));
        }
        address previousOwner = _update(to, tokenId, address(0));
        if (previousOwner == address(0)) {
            revert ERC721NonexistentToken(tokenId);
        } else if (previousOwner != from) {
            revert ERC721IncorrectOwner(from, tokenId, previousOwner);
        }
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking that contract recipients
     * are aware of the ERC721 standard 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 like {safeTransferFrom} in the sense that it invokes
     * {IERC721Receiver-onERC721Received} on the receiver, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `tokenId` token must exist and be owned by `from`.
     * - `to` cannot be the zero address.
     * - `from` cannot be the zero address.
     * - 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) internal {
        _safeTransfer(from, to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeTransfer-address-address-uint256-}[`_safeTransfer`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {
        _transfer(from, to, tokenId);
        _checkOnERC721Received(from, to, tokenId, data);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * The `auth` argument is optional. If the value passed is non 0, then this function will check that `auth` is
     * either the owner of the token, or approved to operate on all tokens held by this owner.
     *
     * Emits an {Approval} event.
     *
     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
     */
    function _approve(address to, uint256 tokenId, address auth) internal {
        _approve(to, tokenId, auth, true);
    }

    /**
     * @dev Variant of `_approve` with an optional flag to enable or disable the {Approval} event. The event is not
     * emitted in the context of transfers.
     */
    function _approve(address to, uint256 tokenId, address auth, bool emitEvent) internal virtual {
        // Avoid reading the owner unless necessary
        if (emitEvent || auth != address(0)) {
            address owner = _requireOwned(tokenId);

            // We do not use _isAuthorized because single-token approvals should not be able to call approve
            if (auth != address(0) && owner != auth && !isApprovedForAll(owner, auth)) {
                revert ERC721InvalidApprover(auth);
            }

            if (emitEvent) {
                emit Approval(owner, to, tokenId);
            }
        }

        _tokenApprovals[tokenId] = to;
    }

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Requirements:
     * - operator can't be the address zero.
     *
     * Emits an {ApprovalForAll} event.
     */
    function _setApprovalForAll(address owner, address operator, bool approved) internal virtual {
        if (operator == address(0)) {
            revert ERC721InvalidOperator(operator);
        }
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Reverts if the `tokenId` doesn't have a current owner (it hasn't been minted, or it has been burned).
     * Returns the owner.
     *
     * Overrides to ownership logic should be done to {_ownerOf}.
     */
    function _requireOwned(uint256 tokenId) internal view returns (address) {
        address owner = _ownerOf(tokenId);
        if (owner == address(0)) {
            revert ERC721NonexistentToken(tokenId);
        }
        return owner;
    }

    /**
     * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target address. This will revert if the
     * recipient doesn't accept the token transfer. 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
     */
    function _checkOnERC721Received(address from, address to, uint256 tokenId, bytes memory data) private {
        if (to.code.length > 0) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
                if (retval != IERC721Receiver.onERC721Received.selector) {
                    revert ERC721InvalidReceiver(to);
                }
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert ERC721InvalidReceiver(to);
                } else {
                    /// @solidity memory-safe-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        }
    }
}

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


// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC721/extensions/ERC721Enumerable.sol)

pragma solidity ^0.8.20;




/**
 * @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.
 *
 * CAUTION: `ERC721` extensions that implement custom `balanceOf` logic, such as `ERC721Consecutive`,
 * interfere with enumerability and should not be used together with `ERC721Enumerable`.
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    mapping(address owner => mapping(uint256 index => uint256)) private _ownedTokens;
    mapping(uint256 tokenId => uint256) private _ownedTokensIndex;

    uint256[] private _allTokens;
    mapping(uint256 tokenId => uint256) private _allTokensIndex;

    /**
     * @dev An `owner`'s token query was out of bounds for `index`.
     *
     * NOTE: The owner being `address(0)` indicates a global out of bounds index.
     */
    error ERC721OutOfBoundsIndex(address owner, uint256 index);

    /**
     * @dev Batch mint is not allowed.
     */
    error ERC721EnumerableForbiddenBatchMint();

    /**
     * @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 returns (uint256) {
        if (index >= balanceOf(owner)) {
            revert ERC721OutOfBoundsIndex(owner, index);
        }
        return _ownedTokens[owner][index];
    }

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

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual returns (uint256) {
        if (index >= totalSupply()) {
            revert ERC721OutOfBoundsIndex(address(0), index);
        }
        return _allTokens[index];
    }

    /**
     * @dev See {ERC721-_update}.
     */
    function _update(address to, uint256 tokenId, address auth) internal virtual override returns (address) {
        address previousOwner = super._update(to, tokenId, auth);

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

        return previousOwner;
    }

    /**
     * @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 = balanceOf(to) - 1;
        _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 = balanceOf(from);
        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();
    }

    /**
     * See {ERC721-_increaseBalance}. We need that to account tokens that were minted in batch
     */
    function _increaseBalance(address account, uint128 amount) internal virtual override {
        if (amount > 0) {
            revert ERC721EnumerableForbiddenBatchMint();
        }
        super._increaseBalance(account, amount);
    }
}

// File: contracts/NewNFT.sol


pragma solidity ^0.8.20;







contract Robotic_Rabbit_Syndicate is ERC721, ERC721Enumerable, Ownable, EIP712, ERC2981 {

    using Strings for uint256;

    struct EIP712Domain {
        string  name;
        string  version;
        uint256 chainId;
        address verifyingContract;
    }

    struct GameVoucher{
        uint256 mintQuantity;
        uint256 mintMode; // 1 : full fee,2 : easy mode percent,3 : hard mode percent
        uint256 mintTimestamp;
        address buyer;
        bytes signature;
        bytes validateSignature;
    }

    uint256 public cost; // wei
    uint256 public gameNFTCost;
    uint256 public maxSupply;
    uint256 public totalNftMinted;
    uint256 public easyModeGamePercent = 20;
    uint256 public hardModeGamePercent = 40;
    
    string public baseURI;
    string public notRevealedUri;
    string public contractUri;
	string public baseExtension = ".json";
    string private constant SIGNING_DOMAIN = "Robotic_Rabbit_Syndicate";
    string private constant SIGNATURE_VERSION = "1";
	bool public revealed;
    bool public isMintActive;
    bool public isGameMintActive;
    mapping(uint256 => bool) public gameMintTime;
    mapping(address => bool) public isMartekplaceBlacklist; // add the address to blocklist the martekplace for not to trade 

    address public constant validateWallet = 0x544D03809749aC19EbcAD183eA43eC677680F1a9;
    address public immutable funderWallet;
    bytes32 constant EIP712DOMAIN_TYPEHASH = keccak256("EIP712Domain(string name,string version,uint256 chainId,address verifyingContract)");
    bytes32 constant GAME_VOUCHER = keccak256("GameVoucher(uint256 mintQuantity,uint256 mintMode,uint256 mintTimestamp,address buyer)");
    bytes32 public DOMAIN_SEPARATOR;

    modifier mintActive() {
        require(isMintActive, "Mint sale is paused.");
        _;
    }
    
    modifier gameMintActive() {
        require(isGameMintActive, "Game mint sale is paused.");
        _;
    }

    modifier checkSupply(uint256 mintQuantity) {
        require(totalNftMinted + mintQuantity <= maxSupply, "Max supply exceeds!");
        _;
    }

    modifier checkMintQuantity(uint256 mintQuantity) {
        require(mintQuantity !=0, "Invalid mint quantity");
        _;
    }

    event Mint(address indexed user, uint256 quantity, uint256 price);
    event ToggleMintSale();
    event ToggleGameMintSale();
    
    // Funder wallet: 0x9551297cb58ad5EBC027deEb7FF3590fb80AcE2F
    /// @param _maxSupply The totalSupply of nft
    /// @param nftCost The nft price in wei
    /// @param gameNFTPrice The game nft price in wei
    constructor(address _funderWallet, uint256 _maxSupply, uint256 nftCost, uint256 gameNFTPrice, uint256 networkChainId, uint96 feeNumerator) ERC721("Robotic_Rabbit_Syndicate", "Robotic Rabbit Syndicate") EIP712(SIGNING_DOMAIN, SIGNATURE_VERSION) Ownable(msg.sender){
        isMintActive = false;
        isGameMintActive = false;
        funderWallet = _funderWallet;
        maxSupply = _maxSupply;
        cost = nftCost;
        gameNFTCost = gameNFTPrice;
        revealed = false;
        _setDefaultRoyalty(_funderWallet, feeNumerator);
        DOMAIN_SEPARATOR = hash(EIP712Domain({
            name: SIGNING_DOMAIN,
            version: SIGNATURE_VERSION,
            chainId: networkChainId,
            verifyingContract: address(this)
        }));
    }

    function contractURI() public view returns (string memory) {
		return contractUri;
	}

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

    function totalSupply() public override view returns(uint256){
        return maxSupply;
    }

    /*** OnlyOwner ***/

    function setDefaultRoyalty(uint96 feeNumerator) external onlyOwner {
        _setDefaultRoyalty(funderWallet, feeNumerator);
    }

    function setBlacklistMarketplace(address _marketplaceAddress) external onlyOwner {
        isMartekplaceBlacklist[_marketplaceAddress] = true;
    }

    function removeBlacklistMarketplace(address _marketplaceAddress) external onlyOwner {
        isMartekplaceBlacklist[_marketplaceAddress] = false;
    }

    function setEasyModePercent(uint256 _easyModePercent) external checkMintQuantity(_easyModePercent) onlyOwner {
        easyModeGamePercent = _easyModePercent;
    }

    function setHardModePercent(uint256 _hardModePercent) external checkMintQuantity(_hardModePercent) onlyOwner {
        hardModeGamePercent = _hardModePercent;
    }

    /// @notice Function to toggle sale if needed only by owner
    function toggleMintSale() external onlyOwner {
        isMintActive = !isMintActive;
        emit ToggleMintSale();
    }
    
    function toggleGameMintSale() external onlyOwner {
        isGameMintActive = !isGameMintActive;
        emit ToggleGameMintSale();
    }

    function toggleNonReveal() external onlyOwner {
        revealed = !revealed;
    }

    function setMaxSupply(uint256 _maxSupply) external onlyOwner {
		maxSupply = _maxSupply;
	}

    function setCost(uint256 _newCost) external onlyOwner {
		cost = _newCost;
	}
    
    function setGameNFTCost(uint256 newGameNFTCost) external onlyOwner {
	    gameNFTCost = newGameNFTCost;
    }

    function setNotRevealedURI(string memory _notRevealedURI) external onlyOwner {
		notRevealedUri = _notRevealedURI;
	}
    
    function reveal(string memory _newBaseURI) external onlyOwner {
		baseURI = _newBaseURI;
		revealed = true;
	}
    
    function setContractURI(string memory _contractURI) external onlyOwner {
		contractUri = _contractURI;
	}


    function setBaseExtension(string memory _newBaseExtension) external onlyOwner {
		baseExtension = _newBaseExtension;
	}

    /// @notice Function to mint nft by only owner
    /// @param mintQuantity The number of nft want to mint at a time
    function ownerMint(uint256 mintQuantity) external checkSupply(mintQuantity) checkMintQuantity(mintQuantity) onlyOwner {
        internalMint(msg.sender, mintQuantity);
    }

    function estimateForFixPrice(uint256 mintQuantity) public view returns(uint256){
        uint256 price = cost * mintQuantity;
        return price;
    }

    function estimateForGame(uint256 mintQuantity, uint256 _mintModeType) public view returns(uint256){
        uint256 price = gameNFTCost * mintQuantity;
        if(_mintModeType == 2){
            uint256 easyModeDiscountAmount = (price * easyModeGamePercent)/100;
            return (price - easyModeDiscountAmount );
        }
        if(_mintModeType == 3){
            uint256 hardModeDiscountAmount = (price * hardModeGamePercent)/100;
            return (price - hardModeDiscountAmount);
        }
        return price;
    }

    /// @notice Function to mint with fix price
    /// @param mintQuantity The number of nft want to mint at a time
    function mint(uint256 mintQuantity) external mintActive checkSupply(mintQuantity) checkMintQuantity(mintQuantity) payable {
        uint256 nftPrice = estimateForFixPrice(mintQuantity);
        require(msg.value >= nftPrice, "Insufficient nft price");
        Address.sendValue(payable(funderWallet), msg.value);
        internalMint(msg.sender, mintQuantity);
    }
    
    /// @notice Function to mint nft in game
    function mintForGame(uint256 mintQuantity, uint256 mintMode, uint256 mintTimestamp, address buyer, bytes memory signature, bytes memory validateSignature) external gameMintActive payable {
        (address signer, address validateSinger) = verify( mintQuantity,  mintMode,  mintTimestamp,  buyer,   signature,   validateSignature);
        uint256 mintQty = mintQuantity;
        uint256 mintModeType = mintMode;
        uint256 mintIds = mintTimestamp;
        require(!gameMintTime[mintIds], "Game mint time is already used");
        uint256 payablePrice = estimateForGame(mintQty, mintModeType);
        require(msg.sender == signer, "Invalid caller");
        require(validateWallet == validateSinger, "Invalid validate signature");
        require(totalNftMinted + mintQty <= maxSupply, "Max supply exceeds!");
        require(msg.value >= payablePrice, "Insufficient nft price in game");
        Address.sendValue(payable(funderWallet), msg.value);
        internalMint(msg.sender, mintQty);
        gameMintTime[mintIds]= true;
    }

    function internalMint(address user, uint256 mintQuantity) internal {
        uint256 mintedNFT = totalNftMinted;
        for (uint256 i = 1; i <= mintQuantity; i++) {
            uint256 ids = mintedNFT + i;
            _safeMint(user, ids);
            totalNftMinted++;
        }
    }

    function tokenURI(uint256 tokenId)
        public
        view
        virtual
        override
        returns (string memory)
        {
        _requireOwned(tokenId);
        if (!revealed) {
            return notRevealedUri;
        }

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

    function walletOfOwner(address _owner) public view returns (uint256[] memory) {
		uint256 ownerTokenCount = balanceOf(_owner);
		uint256[] memory tokenIds = new uint256[](ownerTokenCount);

		for (uint256 i; i < ownerTokenCount; i++) {
			tokenIds[i] = tokenOfOwnerByIndex(_owner, i);
		}

		return tokenIds;
	}

    function airdropNFT(address[] calldata userAddress) external onlyOwner {
        require(totalNftMinted + userAddress.length <= maxSupply, "Max supply exceeds!");
        for (uint256 i=0; i< userAddress.length; i++) 
        {
            internalMint(userAddress[i], 1);
        }
    }

    function _update(address to, uint256 tokenId, address auth) internal override(ERC721, ERC721Enumerable) returns (address)
    {
        return super._update(to, tokenId, auth);
    }

    function _increaseBalance(address account, uint128 value) internal override(ERC721, ERC721Enumerable)
    {
        super._increaseBalance(account, value);
    }

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

    function hash(EIP712Domain memory eip712Domain) internal pure returns (bytes32) {
        return keccak256(abi.encode(
            EIP712DOMAIN_TYPEHASH,
            keccak256(bytes(eip712Domain.name)),
            keccak256(bytes(eip712Domain.version)),
            eip712Domain.chainId,
            eip712Domain.verifyingContract
        ));
    }

    function hash(GameVoucher memory gameVoucher) internal pure returns (bytes32) {
        return keccak256(abi.encode(
            GAME_VOUCHER,
            gameVoucher.mintQuantity,
            gameVoucher.mintMode,
            gameVoucher.mintTimestamp,
            gameVoucher.buyer
        ));
    }

    function verify(uint256 mintQuantity, uint256 mintMode, uint256 mintTimestamp, address buyer, bytes memory signature, bytes memory validateSignature) public view returns (address, address) {
        // Note: we need to use `encodePacked` here instead of `encode`.
        bytes32 gameHash = keccak256(abi.encode(
            GAME_VOUCHER,
            mintQuantity,
            mintMode,
            mintTimestamp,
            buyer
        ));
        bytes32 digest = keccak256(abi.encodePacked(
            "\x19\x01",
            DOMAIN_SEPARATOR,
            gameHash
        ));
        bytes memory callerSign = signature;
        bytes memory validatorSign = validateSignature;
        uint8 v;
        bytes32 r;
        bytes32 s;
        uint8 v_v;
        bytes32 v_r;
        bytes32 v_s;

        assembly {
            r := mload(add(callerSign, 0x20))
            s := mload(add(callerSign, 0x40))
            v := byte(0, mload(add(callerSign, 0x60)))
        }

        assembly {
            v_r := mload(add(validatorSign, 0x20))
            v_s := mload(add(validatorSign, 0x40))
            v_v := byte(0, mload(add(validatorSign, 0x60)))
        }
        return (ecrecover(digest, v, r, s), ecrecover(digest, v_v, v_r, v_s));
    }  

    function approve(address to, uint256 tokenId) public override(ERC721, IERC721) {
        require(!isMartekplaceBlacklist[to], "Can't approve because Marketplace trade is disable");
        _approve(to, tokenId, _msgSender());
    }

    function setApprovalForAll(address operator, bool approved) public override(ERC721, IERC721){
        require(!isMartekplaceBlacklist[operator], "Marketplace trade is disable");
        _setApprovalForAll(_msgSender(), operator, approved);
    } 
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_funderWallet","type":"address"},{"internalType":"uint256","name":"_maxSupply","type":"uint256"},{"internalType":"uint256","name":"nftCost","type":"uint256"},{"internalType":"uint256","name":"gameNFTPrice","type":"uint256"},{"internalType":"uint256","name":"networkChainId","type":"uint256"},{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"AddressInsufficientBalance","type":"error"},{"inputs":[{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"ERC2981InvalidDefaultRoyalty","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC2981InvalidDefaultRoyaltyReceiver","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"uint256","name":"numerator","type":"uint256"},{"internalType":"uint256","name":"denominator","type":"uint256"}],"name":"ERC2981InvalidTokenRoyalty","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC2981InvalidTokenRoyaltyReceiver","type":"error"},{"inputs":[],"name":"ERC721EnumerableForbiddenBatchMint","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721IncorrectOwner","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721InsufficientApproval","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC721InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"ERC721InvalidOperator","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"ERC721InvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC721InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC721InvalidSender","type":"error"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ERC721NonexistentToken","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"ERC721OutOfBoundsIndex","type":"error"},{"inputs":[],"name":"FailedInnerCall","type":"error"},{"inputs":[],"name":"InvalidShortString","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"StringTooLong","type":"error"},{"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":[],"name":"EIP712DomainChanged","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":false,"internalType":"uint256","name":"quantity","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"price","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[],"name":"ToggleGameMintSale","type":"event"},{"anonymous":false,"inputs":[],"name":"ToggleMintSale","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"userAddress","type":"address[]"}],"name":"airdropNFT","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseExtension","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contractUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"easyModeGamePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"mintQuantity","type":"uint256"}],"name":"estimateForFixPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"mintQuantity","type":"uint256"},{"internalType":"uint256","name":"_mintModeType","type":"uint256"}],"name":"estimateForGame","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"funderWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"gameMintTime","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"gameNFTCost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"hardModeGamePercent","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":[],"name":"isGameMintActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"isMartekplaceBlacklist","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isMintActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"mintQuantity","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"mintQuantity","type":"uint256"},{"internalType":"uint256","name":"mintMode","type":"uint256"},{"internalType":"uint256","name":"mintTimestamp","type":"uint256"},{"internalType":"address","name":"buyer","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"bytes","name":"validateSignature","type":"bytes"}],"name":"mintForGame","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"notRevealedUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"mintQuantity","type":"uint256"}],"name":"ownerMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_marketplaceAddress","type":"address"}],"name":"removeBlacklistMarketplace","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"reveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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":"_newBaseExtension","type":"string"}],"name":"setBaseExtension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_marketplaceAddress","type":"address"}],"name":"setBlacklistMarketplace","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_contractURI","type":"string"}],"name":"setContractURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_newCost","type":"uint256"}],"name":"setCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint96","name":"feeNumerator","type":"uint96"}],"name":"setDefaultRoyalty","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_easyModePercent","type":"uint256"}],"name":"setEasyModePercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"newGameNFTCost","type":"uint256"}],"name":"setGameNFTCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_hardModePercent","type":"uint256"}],"name":"setHardModePercent","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxSupply","type":"uint256"}],"name":"setMaxSupply","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_notRevealedURI","type":"string"}],"name":"setNotRevealedURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"toggleGameMintSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleMintSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"toggleNonReveal","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalNftMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"validateWallet","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"mintQuantity","type":"uint256"},{"internalType":"uint256","name":"mintMode","type":"uint256"},{"internalType":"uint256","name":"mintTimestamp","type":"uint256"},{"internalType":"address","name":"buyer","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"bytes","name":"validateSignature","type":"bytes"}],"name":"verify","outputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"walletOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"}]

610180604052601460135560286014556040518060400160405280600581526020017f2e6a736f6e0000000000000000000000000000000000000000000000000000008152506018908162000055919062000acd565b503480156200006357600080fd5b5060405162006c1838038062006c18833981810160405281019062000089919062000c98565b6040518060400160405280601881526020017f526f626f7469635f5261626269745f53796e64696361746500000000000000008152506040518060400160405280600181526020017f3100000000000000000000000000000000000000000000000000000000000000815250336040518060400160405280601881526020017f526f626f7469635f5261626269745f53796e64696361746500000000000000008152506040518060400160405280601881526020017f526f626f746963205261626269742053796e6469636174650000000000000000815250816000908162000173919062000acd565b50806001908162000185919062000acd565b505050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603620001fd5760006040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401620001f4919062000d45565b60405180910390fd5b6200020e816200042f60201b60201c565b5062000225600b83620004f560201b90919060201c565b610120818152505062000243600c82620004f560201b90919060201c565b6101408181525050818051906020012060e08181525050808051906020012061010081815250504660a08181525050620002826200054d60201b60201c565b608081815250503073ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff168152505050506000601960016101000a81548160ff0219169083151502179055506000601960026101000a81548160ff0219169083151502179055508573ffffffffffffffffffffffffffffffffffffffff166101608173ffffffffffffffffffffffffffffffffffffffff16815250508460118190555083600f81905550826010819055506000601960006101000a81548160ff0219169083151502179055506200036c8682620005aa60201b60201c565b6200041d60405180608001604052806040518060400160405280601881526020017f526f626f7469635f5261626269745f53796e646963617465000000000000000081525081526020016040518060400160405280600181526020017f310000000000000000000000000000000000000000000000000000000000000081525081526020018481526020013073ffffffffffffffffffffffffffffffffffffffff168152506200075a60201b60201c565b601c8190555050505050505062000fa6565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006020835110156200051b576200051383620007d260201b60201c565b905062000547565b826200052d836200083f60201b60201c565b60000190816200053e919062000acd565b5060ff60001b90505b92915050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60e0516101005146306040516020016200058f95949392919062000d8e565b60405160208183030381529060405280519060200120905090565b6000620005bc6200084960201b60201c565b6bffffffffffffffffffffffff16905080826bffffffffffffffffffffffff161115620006245781816040517f6f483d090000000000000000000000000000000000000000000000000000000081526004016200061b92919062000e24565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603620006995760006040517fb6d9900a00000000000000000000000000000000000000000000000000000000815260040162000690919062000d45565b60405180910390fd5b60405180604001604052808473ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff16815250600d60008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550905050505050565b60007f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f82600001518051906020012083602001518051906020012084604001518560600151604051602001620007b595949392919062000d8e565b604051602081830303815290604052805190602001209050919050565b600080829050601f815111156200082257826040517f305a27a900000000000000000000000000000000000000000000000000000000815260040162000819919062000ee0565b60405180910390fd5b805181620008309062000f36565b60001c1760001b915050919050565b6000819050919050565b6000612710905090565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620008d557607f821691505b602082108103620008eb57620008ea6200088d565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620009557fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000916565b62000961868362000916565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620009ae620009a8620009a28462000979565b62000983565b62000979565b9050919050565b6000819050919050565b620009ca836200098d565b620009e2620009d982620009b5565b84845462000923565b825550505050565b600090565b620009f9620009ea565b62000a06818484620009bf565b505050565b5b8181101562000a2e5762000a22600082620009ef565b60018101905062000a0c565b5050565b601f82111562000a7d5762000a4781620008f1565b62000a528462000906565b8101602085101562000a62578190505b62000a7a62000a718562000906565b83018262000a0b565b50505b505050565b600082821c905092915050565b600062000aa26000198460080262000a82565b1980831691505092915050565b600062000abd838362000a8f565b9150826002028217905092915050565b62000ad88262000853565b67ffffffffffffffff81111562000af45762000af36200085e565b5b62000b008254620008bc565b62000b0d82828562000a32565b600060209050601f83116001811462000b45576000841562000b30578287015190505b62000b3c858262000aaf565b86555062000bac565b601f19841662000b5586620008f1565b60005b8281101562000b7f5784890151825560018201915060208501945060208101905062000b58565b8683101562000b9f578489015162000b9b601f89168262000a8f565b8355505b6001600288020188555050505b505050505050565b600080fd5b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b600062000be68262000bb9565b9050919050565b62000bf88162000bd9565b811462000c0457600080fd5b50565b60008151905062000c188162000bed565b92915050565b62000c298162000979565b811462000c3557600080fd5b50565b60008151905062000c498162000c1e565b92915050565b60006bffffffffffffffffffffffff82169050919050565b62000c728162000c4f565b811462000c7e57600080fd5b50565b60008151905062000c928162000c67565b92915050565b60008060008060008060c0878903121562000cb85762000cb762000bb4565b5b600062000cc889828a0162000c07565b965050602062000cdb89828a0162000c38565b955050604062000cee89828a0162000c38565b945050606062000d0189828a0162000c38565b935050608062000d1489828a0162000c38565b92505060a062000d2789828a0162000c81565b9150509295509295509295565b62000d3f8162000bd9565b82525050565b600060208201905062000d5c600083018462000d34565b92915050565b6000819050919050565b62000d778162000d62565b82525050565b62000d888162000979565b82525050565b600060a08201905062000da5600083018862000d6c565b62000db4602083018762000d6c565b62000dc3604083018662000d6c565b62000dd2606083018562000d7d565b62000de1608083018462000d34565b9695505050505050565b600062000e0c62000e0662000e008462000c4f565b62000983565b62000979565b9050919050565b62000e1e8162000deb565b82525050565b600060408201905062000e3b600083018562000e13565b62000e4a602083018462000d7d565b9392505050565b600082825260208201905092915050565b60005b8381101562000e8257808201518184015260208101905062000e65565b60008484015250505050565b6000601f19601f8301169050919050565b600062000eac8262000853565b62000eb8818562000e51565b935062000eca81856020860162000e62565b62000ed58162000e8e565b840191505092915050565b6000602082019050818103600083015262000efc818462000e9f565b905092915050565b600081519050919050565b6000819050602082019050919050565b600062000f2d825162000d62565b80915050919050565b600062000f438262000f04565b8262000f4f8462000f0f565b905062000f5c8162000f1f565b9250602082101562000f9f5762000f9a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8360200360080262000916565b831692505b5050919050565b60805160a05160c05160e05161010051610120516101405161016051615c06620010126000396000818161110d01528181611e83015281816120d4015261240b01526000612c9001526000612c5501526000505060005050600050506000505060005050615c066000f3fe6080604052600436106103b85760003560e01c806365b773be116101f2578063c66828621161010d578063e01cfac7116100a0578063f19e75d41161006f578063f19e75d414610e19578063f2c4ce1e14610e42578063f2fde38b14610e6b578063f398334214610e94576103b8565b8063e01cfac714610d5b578063e8a3d48514610d86578063e985e9c514610db1578063ec62aaa414610dee576103b8565b8063d8fb4bd2116100dc578063d8fb4bd214610cb5578063d9dc31b814610cf2578063da3ef23f14610d1b578063dc3cf1d214610d44576103b8565b8063c668286214610bf9578063c87b56dd14610c24578063d5abeb0114610c61578063d6948b7514610c8c576103b8565b80638da5cb5b11610185578063a0712d6811610154578063a0712d6814610b60578063a22cb46514610b7c578063b88d4fde14610ba5578063c0e24d5e14610bce576103b8565b80638da5cb5b14610ac5578063919ce0e314610af0578063938e3d7b14610b0c57806395d89b4114610b35576103b8565b806370a08231116101c157806370a0823114610a17578063715018a614610a54578063818a08b014610a6b57806384b0196e14610a94576103b8565b806365b773be1461096f5780636c0360eb146109985780636f08f6c7146109c35780636f8b44b0146109ee576103b8565b8063341d95df116102e257806351830227116102755780635bc00f41116102445780635bc00f41146108b557806360be7a01146108de5780636352211e146108f55780636562105d14610932576103b8565b806351830227146107f957806354c4eed914610824578063555d400a1461084d5780635b92ac0d1461088a576103b8565b806344a0d68a116102b157806344a0d68a1461073f5780634c261247146107685780634d15d24b146107915780634f6ccce7146107bc576103b8565b8063341d95df146106855780633644e515146106ae57806342842e0e146106d9578063438b630014610702576103b8565b806313faede61161035a57806323b872dd1161032957806323b872dd146105ca57806328bbd5b5146105f35780632a55205a1461060a5780632f745c5914610648576103b8565b806313faede61461051e57806318160ddd146105495780631eba8da0146105745780631ebfcc551461059f576103b8565b806307569375116103965780630756937514610450578063081812fc1461048d578063081c8c44146104ca578063095ea7b3146104f5576103b8565b806301bc4e3c146103bd57806301ffc9a7146103e857806306fdde0314610425575b600080fd5b3480156103c957600080fd5b506103d2610ed2565b6040516103df919061439c565b60405180910390f35b3480156103f457600080fd5b5061040f600480360381019061040a9190614423565b610eea565b60405161041c919061446b565b60405180910390f35b34801561043157600080fd5b5061043a610efc565b6040516104479190614516565b60405180910390f35b34801561045c57600080fd5b5061047760048036038101906104729190614564565b610f8e565b604051610484919061446b565b60405180910390f35b34801561049957600080fd5b506104b460048036038101906104af91906145c7565b610fae565b6040516104c1919061439c565b60405180910390f35b3480156104d657600080fd5b506104df610fca565b6040516104ec9190614516565b60405180910390f35b34801561050157600080fd5b5061051c600480360381019061051791906145f4565b611058565b005b34801561052a57600080fd5b506105336110fb565b6040516105409190614643565b60405180910390f35b34801561055557600080fd5b5061055e611101565b60405161056b9190614643565b60405180910390f35b34801561058057600080fd5b5061058961110b565b604051610596919061439c565b60405180910390f35b3480156105ab57600080fd5b506105b461112f565b6040516105c19190614643565b60405180910390f35b3480156105d657600080fd5b506105f160048036038101906105ec919061465e565b611135565b005b3480156105ff57600080fd5b50610608611237565b005b34801561061657600080fd5b50610631600480360381019061062c91906146b1565b611297565b60405161063f9291906146f1565b60405180910390f35b34801561065457600080fd5b5061066f600480360381019061066a91906145f4565b611481565b60405161067c9190614643565b60405180910390f35b34801561069157600080fd5b506106ac60048036038101906106a791906145c7565b61152a565b005b3480156106ba57600080fd5b506106c3611581565b6040516106d09190614733565b60405180910390f35b3480156106e557600080fd5b5061070060048036038101906106fb919061465e565b611587565b005b34801561070e57600080fd5b5061072960048036038101906107249190614564565b6115a7565b604051610736919061480c565b60405180910390f35b34801561074b57600080fd5b50610766600480360381019061076191906145c7565b611655565b005b34801561077457600080fd5b5061078f600480360381019061078a9190614963565b611667565b005b34801561079d57600080fd5b506107a661169d565b6040516107b3919061446b565b60405180910390f35b3480156107c857600080fd5b506107e360048036038101906107de91906145c7565b6116b0565b6040516107f09190614643565b60405180910390f35b34801561080557600080fd5b5061080e611726565b60405161081b919061446b565b60405180910390f35b34801561083057600080fd5b5061084b60048036038101906108469190614564565b611739565b005b34801561085957600080fd5b50610874600480360381019061086f91906145c7565b61179c565b6040516108819190614643565b60405180910390f35b34801561089657600080fd5b5061089f6117b8565b6040516108ac919061446b565b60405180910390f35b3480156108c157600080fd5b506108dc60048036038101906108d79190614a0c565b6117cb565b005b3480156108ea57600080fd5b506108f3611880565b005b34801561090157600080fd5b5061091c600480360381019061091791906145c7565b6118b4565b604051610929919061439c565b60405180910390f35b34801561093e57600080fd5b50610959600480360381019061095491906146b1565b6118c6565b6040516109669190614643565b60405180910390f35b34801561097b57600080fd5b5061099660048036038101906109919190614564565b61195a565b005b3480156109a457600080fd5b506109ad6119bd565b6040516109ba9190614516565b60405180910390f35b3480156109cf57600080fd5b506109d8611a4b565b6040516109e59190614643565b60405180910390f35b3480156109fa57600080fd5b50610a156004803603810190610a1091906145c7565b611a51565b005b348015610a2357600080fd5b50610a3e6004803603810190610a399190614564565b611a63565b604051610a4b9190614643565b60405180910390f35b348015610a6057600080fd5b50610a69611b1d565b005b348015610a7757600080fd5b50610a926004803603810190610a8d91906145c7565b611b31565b005b348015610aa057600080fd5b50610aa9611b43565b604051610abc9796959493929190614a94565b60405180910390f35b348015610ad157600080fd5b50610ada611bed565b604051610ae7919061439c565b60405180910390f35b610b0a6004803603810190610b059190614bb9565b611c17565b005b348015610b1857600080fd5b50610b336004803603810190610b2e9190614963565b611eec565b005b348015610b4157600080fd5b50610b4a611f07565b604051610b579190614516565b60405180910390f35b610b7a6004803603810190610b7591906145c7565b611f99565b005b348015610b8857600080fd5b50610ba36004803603810190610b9e9190614caa565b612109565b005b348015610bb157600080fd5b50610bcc6004803603810190610bc79190614cea565b6121ac565b005b348015610bda57600080fd5b50610be36121c9565b604051610bf09190614516565b60405180910390f35b348015610c0557600080fd5b50610c0e612257565b604051610c1b9190614516565b60405180910390f35b348015610c3057600080fd5b50610c4b6004803603810190610c4691906145c7565b6122e5565b604051610c589190614516565b60405180910390f35b348015610c6d57600080fd5b50610c766123f8565b604051610c839190614643565b60405180910390f35b348015610c9857600080fd5b50610cb36004803603810190610cae9190614db1565b6123fe565b005b348015610cc157600080fd5b50610cdc6004803603810190610cd791906145c7565b612433565b604051610ce9919061446b565b60405180910390f35b348015610cfe57600080fd5b50610d196004803603810190610d1491906145c7565b612453565b005b348015610d2757600080fd5b50610d426004803603810190610d3d9190614963565b6124aa565b005b348015610d5057600080fd5b50610d596124c5565b005b348015610d6757600080fd5b50610d70612525565b604051610d7d9190614643565b60405180910390f35b348015610d9257600080fd5b50610d9b61252b565b604051610da89190614516565b60405180910390f35b348015610dbd57600080fd5b50610dd86004803603810190610dd39190614dde565b6125bd565b604051610de5919061446b565b60405180910390f35b348015610dfa57600080fd5b50610e03612651565b604051610e109190614643565b60405180910390f35b348015610e2557600080fd5b50610e406004803603810190610e3b91906145c7565b612657565b005b348015610e4e57600080fd5b50610e696004803603810190610e649190614963565b612705565b005b348015610e7757600080fd5b50610e926004803603810190610e8d9190614564565b612720565b005b348015610ea057600080fd5b50610ebb6004803603810190610eb69190614bb9565b6127a6565b604051610ec9929190614e1e565b60405180910390f35b73544d03809749ac19ebcad183ea43ec677680f1a981565b6000610ef582612925565b9050919050565b606060008054610f0b90614e76565b80601f0160208091040260200160405190810160405280929190818152602001828054610f3790614e76565b8015610f845780601f10610f5957610100808354040283529160200191610f84565b820191906000526020600020905b815481529060010190602001808311610f6757829003601f168201915b5050505050905090565b601b6020528060005260406000206000915054906101000a900460ff1681565b6000610fb98261299f565b50610fc382612a27565b9050919050565b60168054610fd790614e76565b80601f016020809104026020016040519081016040528092919081815260200182805461100390614e76565b80156110505780601f1061102557610100808354040283529160200191611050565b820191906000526020600020905b81548152906001019060200180831161103357829003601f168201915b505050505081565b601b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156110e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110dc90614f19565b60405180910390fd5b6110f782826110f2612a64565b612a6c565b5050565b600f5481565b6000601154905090565b7f000000000000000000000000000000000000000000000000000000000000000081565b60145481565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036111a75760006040517f64a0ae9200000000000000000000000000000000000000000000000000000000815260040161119e919061439c565b60405180910390fd5b60006111bb83836111b6612a64565b612a7e565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611231578382826040517f64283d7b00000000000000000000000000000000000000000000000000000000815260040161122893929190614f39565b60405180910390fd5b50505050565b61123f612a94565b601960019054906101000a900460ff1615601960016101000a81548160ff0219169083151502179055507f47454be5142f3f532f331b9ec1f20fdd8ef744c8f8d7c7899479d9f0091ef9ca60405160405180910390a1565b6000806000600e60008681526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff160361142c57600d6040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505b6000611436612b1b565b6bffffffffffffffffffffffff1682602001516bffffffffffffffffffffffff16866114629190614f9f565b61146c9190615010565b90508160000151819350935050509250929050565b600061148c83611a63565b82106114d15782826040517fa57d13dc0000000000000000000000000000000000000000000000000000000081526004016114c89291906146f1565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b806000810361156e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115659061508d565b60405180910390fd5b611576612a94565b816013819055505050565b601c5481565b6115a2838383604051806020016040528060008152506121ac565b505050565b606060006115b483611a63565b905060008167ffffffffffffffff8111156115d2576115d1614838565b5b6040519080825280602002602001820160405280156116005781602001602082028036833780820191505090505b50905060005b8281101561164a576116188582611481565b82828151811061162b5761162a6150ad565b5b6020026020010181815250508080611642906150dc565b915050611606565b508092505050919050565b61165d612a94565b80600f8190555050565b61166f612a94565b806015908161167e91906152d0565b506001601960006101000a81548160ff02191690831515021790555050565b601960029054906101000a900460ff1681565b60006116ba611101565b8210611700576000826040517fa57d13dc0000000000000000000000000000000000000000000000000000000081526004016116f79291906146f1565b60405180910390fd5b60088281548110611714576117136150ad565b5b90600052602060002001549050919050565b601960009054906101000a900460ff1681565b611741612a94565b6001601b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60008082600f546117ad9190614f9f565b905080915050919050565b601960019054906101000a900460ff1681565b6117d3612a94565b601154828290506012546117e791906153a2565b1115611828576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161181f90615422565b60405180910390fd5b60005b8282905081101561187b5761186883838381811061184c5761184b6150ad565b5b90506020020160208101906118619190614564565b6001612b25565b8080611873906150dc565b91505061182b565b505050565b611888612a94565b601960009054906101000a900460ff1615601960006101000a81548160ff021916908315150217905550565b60006118bf8261299f565b9050919050565b600080836010546118d79190614f9f565b9050600283036119145760006064601354836118f39190614f9f565b6118fd9190615010565b9050808261190b9190615442565b92505050611954565b6003830361194f57600060646014548361192e9190614f9f565b6119389190615010565b905080826119469190615442565b92505050611954565b809150505b92915050565b611962612a94565b6000601b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b601580546119ca90614e76565b80601f01602080910402602001604051908101604052809291908181526020018280546119f690614e76565b8015611a435780601f10611a1857610100808354040283529160200191611a43565b820191906000526020600020905b815481529060010190602001808311611a2657829003601f168201915b505050505081565b60105481565b611a59612a94565b8060118190555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611ad65760006040517f89c62b64000000000000000000000000000000000000000000000000000000008152600401611acd919061439c565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611b25612a94565b611b2f6000612b86565b565b611b39612a94565b8060108190555050565b600060608060008060006060611b57612c4c565b611b5f612c87565b46306000801b600067ffffffffffffffff811115611b8057611b7f614838565b5b604051908082528060200260200182016040528015611bae5781602001602082028036833780820191505090505b507f0f00000000000000000000000000000000000000000000000000000000000000959493929190965096509650965096509650965090919293949596565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b601960029054906101000a900460ff16611c66576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c5d906154c2565b60405180910390fd5b600080611c778888888888886127a6565b91509150600088905060008890506000889050601a600082815260200190815260200160002060009054906101000a900460ff1615611ceb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ce29061552e565b60405180910390fd5b6000611cf784846118c6565b90508573ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611d67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d5e9061559a565b60405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff1673544d03809749ac19ebcad183ea43ec677680f1a973ffffffffffffffffffffffffffffffffffffffff1614611de9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611de090615606565b60405180910390fd5b60115484601254611dfa91906153a2565b1115611e3b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e3290615422565b60405180910390fd5b80341015611e7e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e7590615672565b60405180910390fd5b611ea87f000000000000000000000000000000000000000000000000000000000000000034612cc2565b611eb23385612b25565b6001601a600084815260200190815260200160002060006101000a81548160ff021916908315150217905550505050505050505050505050565b611ef4612a94565b8060179081611f0391906152d0565b5050565b606060018054611f1690614e76565b80601f0160208091040260200160405190810160405280929190818152602001828054611f4290614e76565b8015611f8f5780601f10611f6457610100808354040283529160200191611f8f565b820191906000526020600020905b815481529060010190602001808311611f7257829003601f168201915b5050505050905090565b601960019054906101000a900460ff16611fe8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fdf906156de565b60405180910390fd5b8060115481601254611ffa91906153a2565b111561203b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161203290615422565b60405180910390fd5b816000810361207f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120769061508d565b60405180910390fd5b600061208a8461179c565b9050803410156120cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120c69061574a565b60405180910390fd5b6120f97f000000000000000000000000000000000000000000000000000000000000000034612cc2565b6121033385612b25565b50505050565b601b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615612196576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161218d906157b6565b60405180910390fd5b6121a86121a1612a64565b8383612daf565b5050565b6121b7848484611135565b6121c384848484612f1e565b50505050565b601780546121d690614e76565b80601f016020809104026020016040519081016040528092919081815260200182805461220290614e76565b801561224f5780601f106122245761010080835404028352916020019161224f565b820191906000526020600020905b81548152906001019060200180831161223257829003601f168201915b505050505081565b6018805461226490614e76565b80601f016020809104026020016040519081016040528092919081815260200182805461229090614e76565b80156122dd5780601f106122b2576101008083540402835291602001916122dd565b820191906000526020600020905b8154815290600101906020018083116122c057829003601f168201915b505050505081565b60606122f08261299f565b50601960009054906101000a900460ff16612397576016805461231290614e76565b80601f016020809104026020016040519081016040528092919081815260200182805461233e90614e76565b801561238b5780601f106123605761010080835404028352916020019161238b565b820191906000526020600020905b81548152906001019060200180831161236e57829003601f168201915b505050505090506123f3565b60006123a16130d5565b905060008151116123c157604051806020016040528060008152506123ef565b806123cb84613167565b60186040516020016123df93929190615895565b6040516020818303038152906040525b9150505b919050565b60115481565b612406612a94565b6124307f000000000000000000000000000000000000000000000000000000000000000082613235565b50565b601a6020528060005260406000206000915054906101000a900460ff1681565b8060008103612497576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161248e9061508d565b60405180910390fd5b61249f612a94565b816014819055505050565b6124b2612a94565b80601890816124c191906152d0565b5050565b6124cd612a94565b601960029054906101000a900460ff1615601960026101000a81548160ff0219169083151502179055507f698f081bc2bc3bb8fb99640e2449bb53017ffbfcc3527eeca69d11fa062e622b60405160405180910390a1565b60125481565b60606017805461253a90614e76565b80601f016020809104026020016040519081016040528092919081815260200182805461256690614e76565b80156125b35780601f10612588576101008083540402835291602001916125b3565b820191906000526020600020905b81548152906001019060200180831161259657829003601f168201915b5050505050905090565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60135481565b806011548160125461266991906153a2565b11156126aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126a190615422565b60405180910390fd5b81600081036126ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126e59061508d565b60405180910390fd5b6126f6612a94565b6127003384612b25565b505050565b61270d612a94565b806016908161271c91906152d0565b5050565b612728612a94565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361279a5760006040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401612791919061439c565b60405180910390fd5b6127a381612b86565b50565b60008060007fed0fa1e9b989750cf9cde1388a443b6961142fb88b40fb220f499cfac5ebd229898989896040516020016127e49594939291906158c6565b6040516020818303038152906040528051906020012090506000601c5482604051602001612813929190615986565b604051602081830303815290604052805190602001209050600086905060008690506000806000806000806020880151945060408801519350606088015160001a95506020870151915060408701519050606087015160001a92506001898787876040516000815260200160405260405161289194939291906159d9565b6020604051602081039080840390855afa1580156128b3573d6000803e3d6000fd5b5050506020604051035160018a858585604051600081526020016040526040516128e094939291906159d9565b6020604051602081039080840390855afa158015612902573d6000803e3d6000fd5b505050602060405103519b509b5050505050505050505050965096945050505050565b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806129985750612997826133d7565b5b9050919050565b6000806129ab83613451565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612a1e57826040517f7e273289000000000000000000000000000000000000000000000000000000008152600401612a159190614643565b60405180910390fd5b80915050919050565b60006004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600033905090565b612a79838383600161348e565b505050565b6000612a8b848484613653565b90509392505050565b612a9c612a64565b73ffffffffffffffffffffffffffffffffffffffff16612aba611bed565b73ffffffffffffffffffffffffffffffffffffffff1614612b1957612add612a64565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401612b10919061439c565b60405180910390fd5b565b6000612710905090565b600060125490506000600190505b828111612b805760008183612b4891906153a2565b9050612b548582613770565b60126000815480929190612b67906150dc565b9190505550508080612b78906150dc565b915050612b33565b50505050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6060612c82600b7f000000000000000000000000000000000000000000000000000000000000000061378e90919063ffffffff16565b905090565b6060612cbd600c7f000000000000000000000000000000000000000000000000000000000000000061378e90919063ffffffff16565b905090565b80471015612d0757306040517fcd786059000000000000000000000000000000000000000000000000000000008152600401612cfe919061439c565b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff1682604051612d2d90615a4f565b60006040518083038185875af1925050503d8060008114612d6a576040519150601f19603f3d011682016040523d82523d6000602084013e612d6f565b606091505b5050905080612daa576040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612e2057816040517f5b08ba18000000000000000000000000000000000000000000000000000000008152600401612e17919061439c565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612f11919061446b565b60405180910390a3505050565b60008373ffffffffffffffffffffffffffffffffffffffff163b11156130cf578273ffffffffffffffffffffffffffffffffffffffff1663150b7a02612f62612a64565b8685856040518563ffffffff1660e01b8152600401612f849493929190615ab9565b6020604051808303816000875af1925050508015612fc057506040513d601f19601f82011682018060405250810190612fbd9190615b1a565b60015b613044573d8060008114612ff0576040519150601f19603f3d011682016040523d82523d6000602084013e612ff5565b606091505b50600081510361303c57836040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401613033919061439c565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146130cd57836040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016130c4919061439c565b60405180910390fd5b505b50505050565b6060601580546130e490614e76565b80601f016020809104026020016040519081016040528092919081815260200182805461311090614e76565b801561315d5780601f106131325761010080835404028352916020019161315d565b820191906000526020600020905b81548152906001019060200180831161314057829003601f168201915b5050505050905090565b6060600060016131768461383e565b01905060008167ffffffffffffffff81111561319557613194614838565b5b6040519080825280601f01601f1916602001820160405280156131c75781602001600182028036833780820191505090505b509050600082602001820190505b60011561322a578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161321e5761321d614fe1565b5b049450600085036131d5575b819350505050919050565b600061323f612b1b565b6bffffffffffffffffffffffff16905080826bffffffffffffffffffffffff1611156132a45781816040517f6f483d0900000000000000000000000000000000000000000000000000000000815260040161329b929190615b78565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036133165760006040517fb6d9900a00000000000000000000000000000000000000000000000000000000815260040161330d919061439c565b60405180910390fd5b60405180604001604052808473ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff16815250600d60008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550905050505050565b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061344a575061344982613991565b5b9050919050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b80806134c75750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b156135fb5760006134d78461299f565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561354257508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015613555575061355381846125bd565b155b1561359757826040517fa9fbf51f00000000000000000000000000000000000000000000000000000000815260040161358e919061439c565b60405180910390fd5b81156135f957838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b836004600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b600080613661858585613a73565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036136a5576136a084613c8d565b6136e4565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146136e3576136e28185613cd6565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036137265761372184613e37565b613765565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613764576137638585613f08565b5b5b809150509392505050565b61378a828260405180602001604052806000815250613f93565b5050565b606060ff60001b83146137ab576137a483613faf565b9050613838565b8180546137b790614e76565b80601f01602080910402602001604051908101604052809291908181526020018280546137e390614e76565b80156138305780601f1061380557610100808354040283529160200191613830565b820191906000526020600020905b81548152906001019060200180831161381357829003601f168201915b505050505090505b92915050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000831061389c577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161389257613891614fe1565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106138d9576d04ee2d6d415b85acef810000000083816138cf576138ce614fe1565b5b0492506020810190505b662386f26fc10000831061390857662386f26fc1000083816138fe576138fd614fe1565b5b0492506010810190505b6305f5e1008310613931576305f5e100838161392757613926614fe1565b5b0492506008810190505b612710831061395657612710838161394c5761394b614fe1565b5b0492506004810190505b60648310613979576064838161396f5761396e614fe1565b5b0492506002810190505b600a8310613988576001810190505b80915050919050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480613a5c57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80613a6c5750613a6b82614023565b5b9050919050565b600080613a7f84613451565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614613ac157613ac081848661408d565b5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613b5257613b0360008560008061348e565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614613bd5576001600360008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505b846002600086815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b6008805490506009600083815260200190815260200160002081905550600881908060018154018082558091505060019003906000526020600020016000909190919091505550565b6000613ce183611a63565b9050600060076000848152602001908152602001600020549050818114613dc6576000600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816007600083815260200190815260200160002081905550505b6007600084815260200190815260200160002060009055600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b60006001600880549050613e4b9190615442565b9050600060096000848152602001908152602001600020549050600060088381548110613e7b57613e7a6150ad565b5b906000526020600020015490508060088381548110613e9d57613e9c6150ad565b5b906000526020600020018190555081600960008381526020019081526020016000208190555060096000858152602001908152602001600020600090556008805480613eec57613eeb615ba1565b5b6001900381819060005260206000200160009055905550505050565b60006001613f1584611a63565b613f1f9190615442565b905081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806007600084815260200190815260200160002081905550505050565b613f9d8383614151565b613faa6000848484612f1e565b505050565b60606000613fbc8361424a565b90506000602067ffffffffffffffff811115613fdb57613fda614838565b5b6040519080825280601f01601f19166020018201604052801561400d5781602001600182028036833780820191505090505b5090508181528360208201528092505050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b61409883838361429a565b61414c57600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361410d57806040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016141049190614643565b60405180910390fd5b81816040517f177e802f0000000000000000000000000000000000000000000000000000000081526004016141439291906146f1565b60405180910390fd5b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036141c35760006040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016141ba919061439c565b60405180910390fd5b60006141d183836000612a7e565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146142455760006040517f73c6ac6e00000000000000000000000000000000000000000000000000000000815260040161423c919061439c565b60405180910390fd5b505050565b60008060ff8360001c169050601f811115614291576040517fb3512b0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561435257508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480614313575061431284846125bd565b5b8061435157508273ffffffffffffffffffffffffffffffffffffffff1661433983612a27565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006143868261435b565b9050919050565b6143968161437b565b82525050565b60006020820190506143b1600083018461438d565b92915050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b614400816143cb565b811461440b57600080fd5b50565b60008135905061441d816143f7565b92915050565b600060208284031215614439576144386143c1565b5b60006144478482850161440e565b91505092915050565b60008115159050919050565b61446581614450565b82525050565b6000602082019050614480600083018461445c565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156144c05780820151818401526020810190506144a5565b60008484015250505050565b6000601f19601f8301169050919050565b60006144e882614486565b6144f28185614491565b93506145028185602086016144a2565b61450b816144cc565b840191505092915050565b6000602082019050818103600083015261453081846144dd565b905092915050565b6145418161437b565b811461454c57600080fd5b50565b60008135905061455e81614538565b92915050565b60006020828403121561457a576145796143c1565b5b60006145888482850161454f565b91505092915050565b6000819050919050565b6145a481614591565b81146145af57600080fd5b50565b6000813590506145c18161459b565b92915050565b6000602082840312156145dd576145dc6143c1565b5b60006145eb848285016145b2565b91505092915050565b6000806040838503121561460b5761460a6143c1565b5b60006146198582860161454f565b925050602061462a858286016145b2565b9150509250929050565b61463d81614591565b82525050565b60006020820190506146586000830184614634565b92915050565b600080600060608486031215614677576146766143c1565b5b60006146858682870161454f565b93505060206146968682870161454f565b92505060406146a7868287016145b2565b9150509250925092565b600080604083850312156146c8576146c76143c1565b5b60006146d6858286016145b2565b92505060206146e7858286016145b2565b9150509250929050565b6000604082019050614706600083018561438d565b6147136020830184614634565b9392505050565b6000819050919050565b61472d8161471a565b82525050565b60006020820190506147486000830184614724565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61478381614591565b82525050565b6000614795838361477a565b60208301905092915050565b6000602082019050919050565b60006147b98261474e565b6147c38185614759565b93506147ce8361476a565b8060005b838110156147ff5781516147e68882614789565b97506147f1836147a1565b9250506001810190506147d2565b5085935050505092915050565b6000602082019050818103600083015261482681846147ae565b905092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b614870826144cc565b810181811067ffffffffffffffff8211171561488f5761488e614838565b5b80604052505050565b60006148a26143b7565b90506148ae8282614867565b919050565b600067ffffffffffffffff8211156148ce576148cd614838565b5b6148d7826144cc565b9050602081019050919050565b82818337600083830152505050565b6000614906614901846148b3565b614898565b90508281526020810184848401111561492257614921614833565b5b61492d8482856148e4565b509392505050565b600082601f83011261494a5761494961482e565b5b813561495a8482602086016148f3565b91505092915050565b600060208284031215614979576149786143c1565b5b600082013567ffffffffffffffff811115614997576149966143c6565b5b6149a384828501614935565b91505092915050565b600080fd5b600080fd5b60008083601f8401126149cc576149cb61482e565b5b8235905067ffffffffffffffff8111156149e9576149e86149ac565b5b602083019150836020820283011115614a0557614a046149b1565b5b9250929050565b60008060208385031215614a2357614a226143c1565b5b600083013567ffffffffffffffff811115614a4157614a406143c6565b5b614a4d858286016149b6565b92509250509250929050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b614a8e81614a59565b82525050565b600060e082019050614aa9600083018a614a85565b8181036020830152614abb81896144dd565b90508181036040830152614acf81886144dd565b9050614ade6060830187614634565b614aeb608083018661438d565b614af860a0830185614724565b81810360c0830152614b0a81846147ae565b905098975050505050505050565b600067ffffffffffffffff821115614b3357614b32614838565b5b614b3c826144cc565b9050602081019050919050565b6000614b5c614b5784614b18565b614898565b905082815260208101848484011115614b7857614b77614833565b5b614b838482856148e4565b509392505050565b600082601f830112614ba057614b9f61482e565b5b8135614bb0848260208601614b49565b91505092915050565b60008060008060008060c08789031215614bd657614bd56143c1565b5b6000614be489828a016145b2565b9650506020614bf589828a016145b2565b9550506040614c0689828a016145b2565b9450506060614c1789828a0161454f565b935050608087013567ffffffffffffffff811115614c3857614c376143c6565b5b614c4489828a01614b8b565b92505060a087013567ffffffffffffffff811115614c6557614c646143c6565b5b614c7189828a01614b8b565b9150509295509295509295565b614c8781614450565b8114614c9257600080fd5b50565b600081359050614ca481614c7e565b92915050565b60008060408385031215614cc157614cc06143c1565b5b6000614ccf8582860161454f565b9250506020614ce085828601614c95565b9150509250929050565b60008060008060808587031215614d0457614d036143c1565b5b6000614d128782880161454f565b9450506020614d238782880161454f565b9350506040614d34878288016145b2565b925050606085013567ffffffffffffffff811115614d5557614d546143c6565b5b614d6187828801614b8b565b91505092959194509250565b60006bffffffffffffffffffffffff82169050919050565b614d8e81614d6d565b8114614d9957600080fd5b50565b600081359050614dab81614d85565b92915050565b600060208284031215614dc757614dc66143c1565b5b6000614dd584828501614d9c565b91505092915050565b60008060408385031215614df557614df46143c1565b5b6000614e038582860161454f565b9250506020614e148582860161454f565b9150509250929050565b6000604082019050614e33600083018561438d565b614e40602083018461438d565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680614e8e57607f821691505b602082108103614ea157614ea0614e47565b5b50919050565b7f43616e277420617070726f76652062656361757365204d61726b6574706c616360008201527f652074726164652069732064697361626c650000000000000000000000000000602082015250565b6000614f03603283614491565b9150614f0e82614ea7565b604082019050919050565b60006020820190508181036000830152614f3281614ef6565b9050919050565b6000606082019050614f4e600083018661438d565b614f5b6020830185614634565b614f68604083018461438d565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614faa82614591565b9150614fb583614591565b9250828202614fc381614591565b91508282048414831517614fda57614fd9614f70565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061501b82614591565b915061502683614591565b92508261503657615035614fe1565b5b828204905092915050565b7f496e76616c6964206d696e74207175616e746974790000000000000000000000600082015250565b6000615077601583614491565b915061508282615041565b602082019050919050565b600060208201905081810360008301526150a68161506a565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006150e782614591565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361511957615118614f70565b5b600182019050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026151867fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82615149565b6151908683615149565b95508019841693508086168417925050509392505050565b6000819050919050565b60006151cd6151c86151c384614591565b6151a8565b614591565b9050919050565b6000819050919050565b6151e7836151b2565b6151fb6151f3826151d4565b848454615156565b825550505050565b600090565b615210615203565b61521b8184846151de565b505050565b5b8181101561523f57615234600082615208565b600181019050615221565b5050565b601f8211156152845761525581615124565b61525e84615139565b8101602085101561526d578190505b61528161527985615139565b830182615220565b50505b505050565b600082821c905092915050565b60006152a760001984600802615289565b1980831691505092915050565b60006152c08383615296565b9150826002028217905092915050565b6152d982614486565b67ffffffffffffffff8111156152f2576152f1614838565b5b6152fc8254614e76565b615307828285615243565b600060209050601f83116001811461533a5760008415615328578287015190505b61533285826152b4565b86555061539a565b601f19841661534886615124565b60005b828110156153705784890151825560018201915060208501945060208101905061534b565b8683101561538d5784890151615389601f891682615296565b8355505b6001600288020188555050505b505050505050565b60006153ad82614591565b91506153b883614591565b92508282019050808211156153d0576153cf614f70565b5b92915050565b7f4d617820737570706c7920657863656564732100000000000000000000000000600082015250565b600061540c601383614491565b9150615417826153d6565b602082019050919050565b6000602082019050818103600083015261543b816153ff565b9050919050565b600061544d82614591565b915061545883614591565b92508282039050818111156154705761546f614f70565b5b92915050565b7f47616d65206d696e742073616c65206973207061757365642e00000000000000600082015250565b60006154ac601983614491565b91506154b782615476565b602082019050919050565b600060208201905081810360008301526154db8161549f565b9050919050565b7f47616d65206d696e742074696d6520697320616c726561647920757365640000600082015250565b6000615518601e83614491565b9150615523826154e2565b602082019050919050565b600060208201905081810360008301526155478161550b565b9050919050565b7f496e76616c69642063616c6c6572000000000000000000000000000000000000600082015250565b6000615584600e83614491565b915061558f8261554e565b602082019050919050565b600060208201905081810360008301526155b381615577565b9050919050565b7f496e76616c69642076616c6964617465207369676e6174757265000000000000600082015250565b60006155f0601a83614491565b91506155fb826155ba565b602082019050919050565b6000602082019050818103600083015261561f816155e3565b9050919050565b7f496e73756666696369656e74206e667420707269636520696e2067616d650000600082015250565b600061565c601e83614491565b915061566782615626565b602082019050919050565b6000602082019050818103600083015261568b8161564f565b9050919050565b7f4d696e742073616c65206973207061757365642e000000000000000000000000600082015250565b60006156c8601483614491565b91506156d382615692565b602082019050919050565b600060208201905081810360008301526156f7816156bb565b9050919050565b7f496e73756666696369656e74206e667420707269636500000000000000000000600082015250565b6000615734601683614491565b915061573f826156fe565b602082019050919050565b6000602082019050818103600083015261576381615727565b9050919050565b7f4d61726b6574706c6163652074726164652069732064697361626c6500000000600082015250565b60006157a0601c83614491565b91506157ab8261576a565b602082019050919050565b600060208201905081810360008301526157cf81615793565b9050919050565b600081905092915050565b60006157ec82614486565b6157f681856157d6565b93506158068185602086016144a2565b80840191505092915050565b6000815461581f81614e76565b61582981866157d6565b9450600182166000811461584457600181146158595761588c565b60ff198316865281151582028601935061588c565b61586285615124565b60005b8381101561588457815481890152600182019150602081019050615865565b838801955050505b50505092915050565b60006158a182866157e1565b91506158ad82856157e1565b91506158b98284615812565b9150819050949350505050565b600060a0820190506158db6000830188614724565b6158e86020830187614634565b6158f56040830186614634565b6159026060830185614634565b61590f608083018461438d565b9695505050505050565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b600061594f6002836157d6565b915061595a82615919565b600282019050919050565b6000819050919050565b61598061597b8261471a565b615965565b82525050565b600061599182615942565b915061599d828561596f565b6020820191506159ad828461596f565b6020820191508190509392505050565b600060ff82169050919050565b6159d3816159bd565b82525050565b60006080820190506159ee6000830187614724565b6159fb60208301866159ca565b615a086040830185614724565b615a156060830184614724565b95945050505050565b600081905092915050565b50565b6000615a39600083615a1e565b9150615a4482615a29565b600082019050919050565b6000615a5a82615a2c565b9150819050919050565b600081519050919050565b600082825260208201905092915050565b6000615a8b82615a64565b615a958185615a6f565b9350615aa58185602086016144a2565b615aae816144cc565b840191505092915050565b6000608082019050615ace600083018761438d565b615adb602083018661438d565b615ae86040830185614634565b8181036060830152615afa8184615a80565b905095945050505050565b600081519050615b14816143f7565b92915050565b600060208284031215615b3057615b2f6143c1565b5b6000615b3e84828501615b05565b91505092915050565b6000615b62615b5d615b5884614d6d565b6151a8565b614591565b9050919050565b615b7281615b47565b82525050565b6000604082019050615b8d6000830185615b69565b615b9a6020830184614634565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea2646970667358221220436cef156d0e0dce4745a9f99575daf855f092add0339ccdb7dd6bbcd5a41cf864736f6c634300081400330000000000000000000000009551297cb58ad5ebc027deeb7ff3590fb80ace2f0000000000000000000000000000000000000000000000000000000000000d0500000000000000000000000000000000000000000000000000d529ae9e86000000000000000000000000000000000000000000000000000000b1a2bc2ec500000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000028a

Deployed Bytecode

0x6080604052600436106103b85760003560e01c806365b773be116101f2578063c66828621161010d578063e01cfac7116100a0578063f19e75d41161006f578063f19e75d414610e19578063f2c4ce1e14610e42578063f2fde38b14610e6b578063f398334214610e94576103b8565b8063e01cfac714610d5b578063e8a3d48514610d86578063e985e9c514610db1578063ec62aaa414610dee576103b8565b8063d8fb4bd2116100dc578063d8fb4bd214610cb5578063d9dc31b814610cf2578063da3ef23f14610d1b578063dc3cf1d214610d44576103b8565b8063c668286214610bf9578063c87b56dd14610c24578063d5abeb0114610c61578063d6948b7514610c8c576103b8565b80638da5cb5b11610185578063a0712d6811610154578063a0712d6814610b60578063a22cb46514610b7c578063b88d4fde14610ba5578063c0e24d5e14610bce576103b8565b80638da5cb5b14610ac5578063919ce0e314610af0578063938e3d7b14610b0c57806395d89b4114610b35576103b8565b806370a08231116101c157806370a0823114610a17578063715018a614610a54578063818a08b014610a6b57806384b0196e14610a94576103b8565b806365b773be1461096f5780636c0360eb146109985780636f08f6c7146109c35780636f8b44b0146109ee576103b8565b8063341d95df116102e257806351830227116102755780635bc00f41116102445780635bc00f41146108b557806360be7a01146108de5780636352211e146108f55780636562105d14610932576103b8565b806351830227146107f957806354c4eed914610824578063555d400a1461084d5780635b92ac0d1461088a576103b8565b806344a0d68a116102b157806344a0d68a1461073f5780634c261247146107685780634d15d24b146107915780634f6ccce7146107bc576103b8565b8063341d95df146106855780633644e515146106ae57806342842e0e146106d9578063438b630014610702576103b8565b806313faede61161035a57806323b872dd1161032957806323b872dd146105ca57806328bbd5b5146105f35780632a55205a1461060a5780632f745c5914610648576103b8565b806313faede61461051e57806318160ddd146105495780631eba8da0146105745780631ebfcc551461059f576103b8565b806307569375116103965780630756937514610450578063081812fc1461048d578063081c8c44146104ca578063095ea7b3146104f5576103b8565b806301bc4e3c146103bd57806301ffc9a7146103e857806306fdde0314610425575b600080fd5b3480156103c957600080fd5b506103d2610ed2565b6040516103df919061439c565b60405180910390f35b3480156103f457600080fd5b5061040f600480360381019061040a9190614423565b610eea565b60405161041c919061446b565b60405180910390f35b34801561043157600080fd5b5061043a610efc565b6040516104479190614516565b60405180910390f35b34801561045c57600080fd5b5061047760048036038101906104729190614564565b610f8e565b604051610484919061446b565b60405180910390f35b34801561049957600080fd5b506104b460048036038101906104af91906145c7565b610fae565b6040516104c1919061439c565b60405180910390f35b3480156104d657600080fd5b506104df610fca565b6040516104ec9190614516565b60405180910390f35b34801561050157600080fd5b5061051c600480360381019061051791906145f4565b611058565b005b34801561052a57600080fd5b506105336110fb565b6040516105409190614643565b60405180910390f35b34801561055557600080fd5b5061055e611101565b60405161056b9190614643565b60405180910390f35b34801561058057600080fd5b5061058961110b565b604051610596919061439c565b60405180910390f35b3480156105ab57600080fd5b506105b461112f565b6040516105c19190614643565b60405180910390f35b3480156105d657600080fd5b506105f160048036038101906105ec919061465e565b611135565b005b3480156105ff57600080fd5b50610608611237565b005b34801561061657600080fd5b50610631600480360381019061062c91906146b1565b611297565b60405161063f9291906146f1565b60405180910390f35b34801561065457600080fd5b5061066f600480360381019061066a91906145f4565b611481565b60405161067c9190614643565b60405180910390f35b34801561069157600080fd5b506106ac60048036038101906106a791906145c7565b61152a565b005b3480156106ba57600080fd5b506106c3611581565b6040516106d09190614733565b60405180910390f35b3480156106e557600080fd5b5061070060048036038101906106fb919061465e565b611587565b005b34801561070e57600080fd5b5061072960048036038101906107249190614564565b6115a7565b604051610736919061480c565b60405180910390f35b34801561074b57600080fd5b50610766600480360381019061076191906145c7565b611655565b005b34801561077457600080fd5b5061078f600480360381019061078a9190614963565b611667565b005b34801561079d57600080fd5b506107a661169d565b6040516107b3919061446b565b60405180910390f35b3480156107c857600080fd5b506107e360048036038101906107de91906145c7565b6116b0565b6040516107f09190614643565b60405180910390f35b34801561080557600080fd5b5061080e611726565b60405161081b919061446b565b60405180910390f35b34801561083057600080fd5b5061084b60048036038101906108469190614564565b611739565b005b34801561085957600080fd5b50610874600480360381019061086f91906145c7565b61179c565b6040516108819190614643565b60405180910390f35b34801561089657600080fd5b5061089f6117b8565b6040516108ac919061446b565b60405180910390f35b3480156108c157600080fd5b506108dc60048036038101906108d79190614a0c565b6117cb565b005b3480156108ea57600080fd5b506108f3611880565b005b34801561090157600080fd5b5061091c600480360381019061091791906145c7565b6118b4565b604051610929919061439c565b60405180910390f35b34801561093e57600080fd5b50610959600480360381019061095491906146b1565b6118c6565b6040516109669190614643565b60405180910390f35b34801561097b57600080fd5b5061099660048036038101906109919190614564565b61195a565b005b3480156109a457600080fd5b506109ad6119bd565b6040516109ba9190614516565b60405180910390f35b3480156109cf57600080fd5b506109d8611a4b565b6040516109e59190614643565b60405180910390f35b3480156109fa57600080fd5b50610a156004803603810190610a1091906145c7565b611a51565b005b348015610a2357600080fd5b50610a3e6004803603810190610a399190614564565b611a63565b604051610a4b9190614643565b60405180910390f35b348015610a6057600080fd5b50610a69611b1d565b005b348015610a7757600080fd5b50610a926004803603810190610a8d91906145c7565b611b31565b005b348015610aa057600080fd5b50610aa9611b43565b604051610abc9796959493929190614a94565b60405180910390f35b348015610ad157600080fd5b50610ada611bed565b604051610ae7919061439c565b60405180910390f35b610b0a6004803603810190610b059190614bb9565b611c17565b005b348015610b1857600080fd5b50610b336004803603810190610b2e9190614963565b611eec565b005b348015610b4157600080fd5b50610b4a611f07565b604051610b579190614516565b60405180910390f35b610b7a6004803603810190610b7591906145c7565b611f99565b005b348015610b8857600080fd5b50610ba36004803603810190610b9e9190614caa565b612109565b005b348015610bb157600080fd5b50610bcc6004803603810190610bc79190614cea565b6121ac565b005b348015610bda57600080fd5b50610be36121c9565b604051610bf09190614516565b60405180910390f35b348015610c0557600080fd5b50610c0e612257565b604051610c1b9190614516565b60405180910390f35b348015610c3057600080fd5b50610c4b6004803603810190610c4691906145c7565b6122e5565b604051610c589190614516565b60405180910390f35b348015610c6d57600080fd5b50610c766123f8565b604051610c839190614643565b60405180910390f35b348015610c9857600080fd5b50610cb36004803603810190610cae9190614db1565b6123fe565b005b348015610cc157600080fd5b50610cdc6004803603810190610cd791906145c7565b612433565b604051610ce9919061446b565b60405180910390f35b348015610cfe57600080fd5b50610d196004803603810190610d1491906145c7565b612453565b005b348015610d2757600080fd5b50610d426004803603810190610d3d9190614963565b6124aa565b005b348015610d5057600080fd5b50610d596124c5565b005b348015610d6757600080fd5b50610d70612525565b604051610d7d9190614643565b60405180910390f35b348015610d9257600080fd5b50610d9b61252b565b604051610da89190614516565b60405180910390f35b348015610dbd57600080fd5b50610dd86004803603810190610dd39190614dde565b6125bd565b604051610de5919061446b565b60405180910390f35b348015610dfa57600080fd5b50610e03612651565b604051610e109190614643565b60405180910390f35b348015610e2557600080fd5b50610e406004803603810190610e3b91906145c7565b612657565b005b348015610e4e57600080fd5b50610e696004803603810190610e649190614963565b612705565b005b348015610e7757600080fd5b50610e926004803603810190610e8d9190614564565b612720565b005b348015610ea057600080fd5b50610ebb6004803603810190610eb69190614bb9565b6127a6565b604051610ec9929190614e1e565b60405180910390f35b73544d03809749ac19ebcad183ea43ec677680f1a981565b6000610ef582612925565b9050919050565b606060008054610f0b90614e76565b80601f0160208091040260200160405190810160405280929190818152602001828054610f3790614e76565b8015610f845780601f10610f5957610100808354040283529160200191610f84565b820191906000526020600020905b815481529060010190602001808311610f6757829003601f168201915b5050505050905090565b601b6020528060005260406000206000915054906101000a900460ff1681565b6000610fb98261299f565b50610fc382612a27565b9050919050565b60168054610fd790614e76565b80601f016020809104026020016040519081016040528092919081815260200182805461100390614e76565b80156110505780601f1061102557610100808354040283529160200191611050565b820191906000526020600020905b81548152906001019060200180831161103357829003601f168201915b505050505081565b601b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16156110e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110dc90614f19565b60405180910390fd5b6110f782826110f2612a64565b612a6c565b5050565b600f5481565b6000601154905090565b7f0000000000000000000000009551297cb58ad5ebc027deeb7ff3590fb80ace2f81565b60145481565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036111a75760006040517f64a0ae9200000000000000000000000000000000000000000000000000000000815260040161119e919061439c565b60405180910390fd5b60006111bb83836111b6612a64565b612a7e565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611231578382826040517f64283d7b00000000000000000000000000000000000000000000000000000000815260040161122893929190614f39565b60405180910390fd5b50505050565b61123f612a94565b601960019054906101000a900460ff1615601960016101000a81548160ff0219169083151502179055507f47454be5142f3f532f331b9ec1f20fdd8ef744c8f8d7c7899479d9f0091ef9ca60405160405180910390a1565b6000806000600e60008681526020019081526020016000206040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff16815250509050600073ffffffffffffffffffffffffffffffffffffffff16816000015173ffffffffffffffffffffffffffffffffffffffff160361142c57600d6040518060400160405290816000820160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020016000820160149054906101000a90046bffffffffffffffffffffffff166bffffffffffffffffffffffff166bffffffffffffffffffffffff168152505090505b6000611436612b1b565b6bffffffffffffffffffffffff1682602001516bffffffffffffffffffffffff16866114629190614f9f565b61146c9190615010565b90508160000151819350935050509250929050565b600061148c83611a63565b82106114d15782826040517fa57d13dc0000000000000000000000000000000000000000000000000000000081526004016114c89291906146f1565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b806000810361156e576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115659061508d565b60405180910390fd5b611576612a94565b816013819055505050565b601c5481565b6115a2838383604051806020016040528060008152506121ac565b505050565b606060006115b483611a63565b905060008167ffffffffffffffff8111156115d2576115d1614838565b5b6040519080825280602002602001820160405280156116005781602001602082028036833780820191505090505b50905060005b8281101561164a576116188582611481565b82828151811061162b5761162a6150ad565b5b6020026020010181815250508080611642906150dc565b915050611606565b508092505050919050565b61165d612a94565b80600f8190555050565b61166f612a94565b806015908161167e91906152d0565b506001601960006101000a81548160ff02191690831515021790555050565b601960029054906101000a900460ff1681565b60006116ba611101565b8210611700576000826040517fa57d13dc0000000000000000000000000000000000000000000000000000000081526004016116f79291906146f1565b60405180910390fd5b60088281548110611714576117136150ad565b5b90600052602060002001549050919050565b601960009054906101000a900460ff1681565b611741612a94565b6001601b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60008082600f546117ad9190614f9f565b905080915050919050565b601960019054906101000a900460ff1681565b6117d3612a94565b601154828290506012546117e791906153a2565b1115611828576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161181f90615422565b60405180910390fd5b60005b8282905081101561187b5761186883838381811061184c5761184b6150ad565b5b90506020020160208101906118619190614564565b6001612b25565b8080611873906150dc565b91505061182b565b505050565b611888612a94565b601960009054906101000a900460ff1615601960006101000a81548160ff021916908315150217905550565b60006118bf8261299f565b9050919050565b600080836010546118d79190614f9f565b9050600283036119145760006064601354836118f39190614f9f565b6118fd9190615010565b9050808261190b9190615442565b92505050611954565b6003830361194f57600060646014548361192e9190614f9f565b6119389190615010565b905080826119469190615442565b92505050611954565b809150505b92915050565b611962612a94565b6000601b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b601580546119ca90614e76565b80601f01602080910402602001604051908101604052809291908181526020018280546119f690614e76565b8015611a435780601f10611a1857610100808354040283529160200191611a43565b820191906000526020600020905b815481529060010190602001808311611a2657829003601f168201915b505050505081565b60105481565b611a59612a94565b8060118190555050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611ad65760006040517f89c62b64000000000000000000000000000000000000000000000000000000008152600401611acd919061439c565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611b25612a94565b611b2f6000612b86565b565b611b39612a94565b8060108190555050565b600060608060008060006060611b57612c4c565b611b5f612c87565b46306000801b600067ffffffffffffffff811115611b8057611b7f614838565b5b604051908082528060200260200182016040528015611bae5781602001602082028036833780820191505090505b507f0f00000000000000000000000000000000000000000000000000000000000000959493929190965096509650965096509650965090919293949596565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b601960029054906101000a900460ff16611c66576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c5d906154c2565b60405180910390fd5b600080611c778888888888886127a6565b91509150600088905060008890506000889050601a600082815260200190815260200160002060009054906101000a900460ff1615611ceb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ce29061552e565b60405180910390fd5b6000611cf784846118c6565b90508573ffffffffffffffffffffffffffffffffffffffff163373ffffffffffffffffffffffffffffffffffffffff1614611d67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d5e9061559a565b60405180910390fd5b8473ffffffffffffffffffffffffffffffffffffffff1673544d03809749ac19ebcad183ea43ec677680f1a973ffffffffffffffffffffffffffffffffffffffff1614611de9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611de090615606565b60405180910390fd5b60115484601254611dfa91906153a2565b1115611e3b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e3290615422565b60405180910390fd5b80341015611e7e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e7590615672565b60405180910390fd5b611ea87f0000000000000000000000009551297cb58ad5ebc027deeb7ff3590fb80ace2f34612cc2565b611eb23385612b25565b6001601a600084815260200190815260200160002060006101000a81548160ff021916908315150217905550505050505050505050505050565b611ef4612a94565b8060179081611f0391906152d0565b5050565b606060018054611f1690614e76565b80601f0160208091040260200160405190810160405280929190818152602001828054611f4290614e76565b8015611f8f5780601f10611f6457610100808354040283529160200191611f8f565b820191906000526020600020905b815481529060010190602001808311611f7257829003601f168201915b5050505050905090565b601960019054906101000a900460ff16611fe8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611fdf906156de565b60405180910390fd5b8060115481601254611ffa91906153a2565b111561203b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161203290615422565b60405180910390fd5b816000810361207f576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120769061508d565b60405180910390fd5b600061208a8461179c565b9050803410156120cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120c69061574a565b60405180910390fd5b6120f97f0000000000000000000000009551297cb58ad5ebc027deeb7ff3590fb80ace2f34612cc2565b6121033385612b25565b50505050565b601b60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1615612196576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161218d906157b6565b60405180910390fd5b6121a86121a1612a64565b8383612daf565b5050565b6121b7848484611135565b6121c384848484612f1e565b50505050565b601780546121d690614e76565b80601f016020809104026020016040519081016040528092919081815260200182805461220290614e76565b801561224f5780601f106122245761010080835404028352916020019161224f565b820191906000526020600020905b81548152906001019060200180831161223257829003601f168201915b505050505081565b6018805461226490614e76565b80601f016020809104026020016040519081016040528092919081815260200182805461229090614e76565b80156122dd5780601f106122b2576101008083540402835291602001916122dd565b820191906000526020600020905b8154815290600101906020018083116122c057829003601f168201915b505050505081565b60606122f08261299f565b50601960009054906101000a900460ff16612397576016805461231290614e76565b80601f016020809104026020016040519081016040528092919081815260200182805461233e90614e76565b801561238b5780601f106123605761010080835404028352916020019161238b565b820191906000526020600020905b81548152906001019060200180831161236e57829003601f168201915b505050505090506123f3565b60006123a16130d5565b905060008151116123c157604051806020016040528060008152506123ef565b806123cb84613167565b60186040516020016123df93929190615895565b6040516020818303038152906040525b9150505b919050565b60115481565b612406612a94565b6124307f0000000000000000000000009551297cb58ad5ebc027deeb7ff3590fb80ace2f82613235565b50565b601a6020528060005260406000206000915054906101000a900460ff1681565b8060008103612497576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161248e9061508d565b60405180910390fd5b61249f612a94565b816014819055505050565b6124b2612a94565b80601890816124c191906152d0565b5050565b6124cd612a94565b601960029054906101000a900460ff1615601960026101000a81548160ff0219169083151502179055507f698f081bc2bc3bb8fb99640e2449bb53017ffbfcc3527eeca69d11fa062e622b60405160405180910390a1565b60125481565b60606017805461253a90614e76565b80601f016020809104026020016040519081016040528092919081815260200182805461256690614e76565b80156125b35780601f10612588576101008083540402835291602001916125b3565b820191906000526020600020905b81548152906001019060200180831161259657829003601f168201915b5050505050905090565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60135481565b806011548160125461266991906153a2565b11156126aa576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126a190615422565b60405180910390fd5b81600081036126ee576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126e59061508d565b60405180910390fd5b6126f6612a94565b6127003384612b25565b505050565b61270d612a94565b806016908161271c91906152d0565b5050565b612728612a94565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361279a5760006040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401612791919061439c565b60405180910390fd5b6127a381612b86565b50565b60008060007fed0fa1e9b989750cf9cde1388a443b6961142fb88b40fb220f499cfac5ebd229898989896040516020016127e49594939291906158c6565b6040516020818303038152906040528051906020012090506000601c5482604051602001612813929190615986565b604051602081830303815290604052805190602001209050600086905060008690506000806000806000806020880151945060408801519350606088015160001a95506020870151915060408701519050606087015160001a92506001898787876040516000815260200160405260405161289194939291906159d9565b6020604051602081039080840390855afa1580156128b3573d6000803e3d6000fd5b5050506020604051035160018a858585604051600081526020016040526040516128e094939291906159d9565b6020604051602081039080840390855afa158015612902573d6000803e3d6000fd5b505050602060405103519b509b5050505050505050505050965096945050505050565b60007f2a55205a000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806129985750612997826133d7565b5b9050919050565b6000806129ab83613451565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603612a1e57826040517f7e273289000000000000000000000000000000000000000000000000000000008152600401612a159190614643565b60405180910390fd5b80915050919050565b60006004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600033905090565b612a79838383600161348e565b505050565b6000612a8b848484613653565b90509392505050565b612a9c612a64565b73ffffffffffffffffffffffffffffffffffffffff16612aba611bed565b73ffffffffffffffffffffffffffffffffffffffff1614612b1957612add612a64565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401612b10919061439c565b60405180910390fd5b565b6000612710905090565b600060125490506000600190505b828111612b805760008183612b4891906153a2565b9050612b548582613770565b60126000815480929190612b67906150dc565b9190505550508080612b78906150dc565b915050612b33565b50505050565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6060612c82600b7f526f626f7469635f5261626269745f53796e646963617465000000000000001861378e90919063ffffffff16565b905090565b6060612cbd600c7f310000000000000000000000000000000000000000000000000000000000000161378e90919063ffffffff16565b905090565b80471015612d0757306040517fcd786059000000000000000000000000000000000000000000000000000000008152600401612cfe919061439c565b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff1682604051612d2d90615a4f565b60006040518083038185875af1925050503d8060008114612d6a576040519150601f19603f3d011682016040523d82523d6000602084013e612d6f565b606091505b5050905080612daa576040517f1425ea4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612e2057816040517f5b08ba18000000000000000000000000000000000000000000000000000000008152600401612e17919061439c565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612f11919061446b565b60405180910390a3505050565b60008373ffffffffffffffffffffffffffffffffffffffff163b11156130cf578273ffffffffffffffffffffffffffffffffffffffff1663150b7a02612f62612a64565b8685856040518563ffffffff1660e01b8152600401612f849493929190615ab9565b6020604051808303816000875af1925050508015612fc057506040513d601f19601f82011682018060405250810190612fbd9190615b1a565b60015b613044573d8060008114612ff0576040519150601f19603f3d011682016040523d82523d6000602084013e612ff5565b606091505b50600081510361303c57836040517f64a0ae92000000000000000000000000000000000000000000000000000000008152600401613033919061439c565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146130cd57836040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016130c4919061439c565b60405180910390fd5b505b50505050565b6060601580546130e490614e76565b80601f016020809104026020016040519081016040528092919081815260200182805461311090614e76565b801561315d5780601f106131325761010080835404028352916020019161315d565b820191906000526020600020905b81548152906001019060200180831161314057829003601f168201915b5050505050905090565b6060600060016131768461383e565b01905060008167ffffffffffffffff81111561319557613194614838565b5b6040519080825280601f01601f1916602001820160405280156131c75781602001600182028036833780820191505090505b509050600082602001820190505b60011561322a578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a858161321e5761321d614fe1565b5b049450600085036131d5575b819350505050919050565b600061323f612b1b565b6bffffffffffffffffffffffff16905080826bffffffffffffffffffffffff1611156132a45781816040517f6f483d0900000000000000000000000000000000000000000000000000000000815260040161329b929190615b78565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036133165760006040517fb6d9900a00000000000000000000000000000000000000000000000000000000815260040161330d919061439c565b60405180910390fd5b60405180604001604052808473ffffffffffffffffffffffffffffffffffffffff168152602001836bffffffffffffffffffffffff16815250600d60008201518160000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555060208201518160000160146101000a8154816bffffffffffffffffffffffff02191690836bffffffffffffffffffffffff160217905550905050505050565b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061344a575061344982613991565b5b9050919050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b80806134c75750600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614155b156135fb5760006134d78461299f565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561354257508273ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614155b8015613555575061355381846125bd565b155b1561359757826040517fa9fbf51f00000000000000000000000000000000000000000000000000000000815260040161358e919061439c565b60405180910390fd5b81156135f957838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45b505b836004600085815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050505050565b600080613661858585613a73565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036136a5576136a084613c8d565b6136e4565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146136e3576136e28185613cd6565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff16036137265761372184613e37565b613765565b8473ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613764576137638585613f08565b5b5b809150509392505050565b61378a828260405180602001604052806000815250613f93565b5050565b606060ff60001b83146137ab576137a483613faf565b9050613838565b8180546137b790614e76565b80601f01602080910402602001604051908101604052809291908181526020018280546137e390614e76565b80156138305780601f1061380557610100808354040283529160200191613830565b820191906000526020600020905b81548152906001019060200180831161381357829003601f168201915b505050505090505b92915050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000831061389c577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161389257613891614fe1565b5b0492506040810190505b6d04ee2d6d415b85acef810000000083106138d9576d04ee2d6d415b85acef810000000083816138cf576138ce614fe1565b5b0492506020810190505b662386f26fc10000831061390857662386f26fc1000083816138fe576138fd614fe1565b5b0492506010810190505b6305f5e1008310613931576305f5e100838161392757613926614fe1565b5b0492506008810190505b612710831061395657612710838161394c5761394b614fe1565b5b0492506004810190505b60648310613979576064838161396f5761396e614fe1565b5b0492506002810190505b600a8310613988576001810190505b80915050919050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480613a5c57507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80613a6c5750613a6b82614023565b5b9050919050565b600080613a7f84613451565b9050600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614613ac157613ac081848661408d565b5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614613b5257613b0360008560008061348e565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614613bd5576001600360008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825401925050819055505b846002600086815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550838573ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4809150509392505050565b6008805490506009600083815260200190815260200160002081905550600881908060018154018082558091505060019003906000526020600020016000909190919091505550565b6000613ce183611a63565b9050600060076000848152602001908152602001600020549050818114613dc6576000600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816007600083815260200190815260200160002081905550505b6007600084815260200190815260200160002060009055600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b60006001600880549050613e4b9190615442565b9050600060096000848152602001908152602001600020549050600060088381548110613e7b57613e7a6150ad565b5b906000526020600020015490508060088381548110613e9d57613e9c6150ad565b5b906000526020600020018190555081600960008381526020019081526020016000208190555060096000858152602001908152602001600020600090556008805480613eec57613eeb615ba1565b5b6001900381819060005260206000200160009055905550505050565b60006001613f1584611a63565b613f1f9190615442565b905081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806007600084815260200190815260200160002081905550505050565b613f9d8383614151565b613faa6000848484612f1e565b505050565b60606000613fbc8361424a565b90506000602067ffffffffffffffff811115613fdb57613fda614838565b5b6040519080825280601f01601f19166020018201604052801561400d5781602001600182028036833780820191505090505b5090508181528360208201528092505050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b61409883838361429a565b61414c57600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160361410d57806040517f7e2732890000000000000000000000000000000000000000000000000000000081526004016141049190614643565b60405180910390fd5b81816040517f177e802f0000000000000000000000000000000000000000000000000000000081526004016141439291906146f1565b60405180910390fd5b505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036141c35760006040517f64a0ae920000000000000000000000000000000000000000000000000000000081526004016141ba919061439c565b60405180910390fd5b60006141d183836000612a7e565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146142455760006040517f73c6ac6e00000000000000000000000000000000000000000000000000000000815260040161423c919061439c565b60405180910390fd5b505050565b60008060ff8360001c169050601f811115614291576040517fb3512b0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415801561435257508273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480614313575061431284846125bd565b5b8061435157508273ffffffffffffffffffffffffffffffffffffffff1661433983612a27565b73ffffffffffffffffffffffffffffffffffffffff16145b5b90509392505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006143868261435b565b9050919050565b6143968161437b565b82525050565b60006020820190506143b1600083018461438d565b92915050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b614400816143cb565b811461440b57600080fd5b50565b60008135905061441d816143f7565b92915050565b600060208284031215614439576144386143c1565b5b60006144478482850161440e565b91505092915050565b60008115159050919050565b61446581614450565b82525050565b6000602082019050614480600083018461445c565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b838110156144c05780820151818401526020810190506144a5565b60008484015250505050565b6000601f19601f8301169050919050565b60006144e882614486565b6144f28185614491565b93506145028185602086016144a2565b61450b816144cc565b840191505092915050565b6000602082019050818103600083015261453081846144dd565b905092915050565b6145418161437b565b811461454c57600080fd5b50565b60008135905061455e81614538565b92915050565b60006020828403121561457a576145796143c1565b5b60006145888482850161454f565b91505092915050565b6000819050919050565b6145a481614591565b81146145af57600080fd5b50565b6000813590506145c18161459b565b92915050565b6000602082840312156145dd576145dc6143c1565b5b60006145eb848285016145b2565b91505092915050565b6000806040838503121561460b5761460a6143c1565b5b60006146198582860161454f565b925050602061462a858286016145b2565b9150509250929050565b61463d81614591565b82525050565b60006020820190506146586000830184614634565b92915050565b600080600060608486031215614677576146766143c1565b5b60006146858682870161454f565b93505060206146968682870161454f565b92505060406146a7868287016145b2565b9150509250925092565b600080604083850312156146c8576146c76143c1565b5b60006146d6858286016145b2565b92505060206146e7858286016145b2565b9150509250929050565b6000604082019050614706600083018561438d565b6147136020830184614634565b9392505050565b6000819050919050565b61472d8161471a565b82525050565b60006020820190506147486000830184614724565b92915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61478381614591565b82525050565b6000614795838361477a565b60208301905092915050565b6000602082019050919050565b60006147b98261474e565b6147c38185614759565b93506147ce8361476a565b8060005b838110156147ff5781516147e68882614789565b97506147f1836147a1565b9250506001810190506147d2565b5085935050505092915050565b6000602082019050818103600083015261482681846147ae565b905092915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b614870826144cc565b810181811067ffffffffffffffff8211171561488f5761488e614838565b5b80604052505050565b60006148a26143b7565b90506148ae8282614867565b919050565b600067ffffffffffffffff8211156148ce576148cd614838565b5b6148d7826144cc565b9050602081019050919050565b82818337600083830152505050565b6000614906614901846148b3565b614898565b90508281526020810184848401111561492257614921614833565b5b61492d8482856148e4565b509392505050565b600082601f83011261494a5761494961482e565b5b813561495a8482602086016148f3565b91505092915050565b600060208284031215614979576149786143c1565b5b600082013567ffffffffffffffff811115614997576149966143c6565b5b6149a384828501614935565b91505092915050565b600080fd5b600080fd5b60008083601f8401126149cc576149cb61482e565b5b8235905067ffffffffffffffff8111156149e9576149e86149ac565b5b602083019150836020820283011115614a0557614a046149b1565b5b9250929050565b60008060208385031215614a2357614a226143c1565b5b600083013567ffffffffffffffff811115614a4157614a406143c6565b5b614a4d858286016149b6565b92509250509250929050565b60007fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b614a8e81614a59565b82525050565b600060e082019050614aa9600083018a614a85565b8181036020830152614abb81896144dd565b90508181036040830152614acf81886144dd565b9050614ade6060830187614634565b614aeb608083018661438d565b614af860a0830185614724565b81810360c0830152614b0a81846147ae565b905098975050505050505050565b600067ffffffffffffffff821115614b3357614b32614838565b5b614b3c826144cc565b9050602081019050919050565b6000614b5c614b5784614b18565b614898565b905082815260208101848484011115614b7857614b77614833565b5b614b838482856148e4565b509392505050565b600082601f830112614ba057614b9f61482e565b5b8135614bb0848260208601614b49565b91505092915050565b60008060008060008060c08789031215614bd657614bd56143c1565b5b6000614be489828a016145b2565b9650506020614bf589828a016145b2565b9550506040614c0689828a016145b2565b9450506060614c1789828a0161454f565b935050608087013567ffffffffffffffff811115614c3857614c376143c6565b5b614c4489828a01614b8b565b92505060a087013567ffffffffffffffff811115614c6557614c646143c6565b5b614c7189828a01614b8b565b9150509295509295509295565b614c8781614450565b8114614c9257600080fd5b50565b600081359050614ca481614c7e565b92915050565b60008060408385031215614cc157614cc06143c1565b5b6000614ccf8582860161454f565b9250506020614ce085828601614c95565b9150509250929050565b60008060008060808587031215614d0457614d036143c1565b5b6000614d128782880161454f565b9450506020614d238782880161454f565b9350506040614d34878288016145b2565b925050606085013567ffffffffffffffff811115614d5557614d546143c6565b5b614d6187828801614b8b565b91505092959194509250565b60006bffffffffffffffffffffffff82169050919050565b614d8e81614d6d565b8114614d9957600080fd5b50565b600081359050614dab81614d85565b92915050565b600060208284031215614dc757614dc66143c1565b5b6000614dd584828501614d9c565b91505092915050565b60008060408385031215614df557614df46143c1565b5b6000614e038582860161454f565b9250506020614e148582860161454f565b9150509250929050565b6000604082019050614e33600083018561438d565b614e40602083018461438d565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680614e8e57607f821691505b602082108103614ea157614ea0614e47565b5b50919050565b7f43616e277420617070726f76652062656361757365204d61726b6574706c616360008201527f652074726164652069732064697361626c650000000000000000000000000000602082015250565b6000614f03603283614491565b9150614f0e82614ea7565b604082019050919050565b60006020820190508181036000830152614f3281614ef6565b9050919050565b6000606082019050614f4e600083018661438d565b614f5b6020830185614634565b614f68604083018461438d565b949350505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614faa82614591565b9150614fb583614591565b9250828202614fc381614591565b91508282048414831517614fda57614fd9614f70565b5b5092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061501b82614591565b915061502683614591565b92508261503657615035614fe1565b5b828204905092915050565b7f496e76616c6964206d696e74207175616e746974790000000000000000000000600082015250565b6000615077601583614491565b915061508282615041565b602082019050919050565b600060208201905081810360008301526150a68161506a565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60006150e782614591565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff820361511957615118614f70565b5b600182019050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026151867fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82615149565b6151908683615149565b95508019841693508086168417925050509392505050565b6000819050919050565b60006151cd6151c86151c384614591565b6151a8565b614591565b9050919050565b6000819050919050565b6151e7836151b2565b6151fb6151f3826151d4565b848454615156565b825550505050565b600090565b615210615203565b61521b8184846151de565b505050565b5b8181101561523f57615234600082615208565b600181019050615221565b5050565b601f8211156152845761525581615124565b61525e84615139565b8101602085101561526d578190505b61528161527985615139565b830182615220565b50505b505050565b600082821c905092915050565b60006152a760001984600802615289565b1980831691505092915050565b60006152c08383615296565b9150826002028217905092915050565b6152d982614486565b67ffffffffffffffff8111156152f2576152f1614838565b5b6152fc8254614e76565b615307828285615243565b600060209050601f83116001811461533a5760008415615328578287015190505b61533285826152b4565b86555061539a565b601f19841661534886615124565b60005b828110156153705784890151825560018201915060208501945060208101905061534b565b8683101561538d5784890151615389601f891682615296565b8355505b6001600288020188555050505b505050505050565b60006153ad82614591565b91506153b883614591565b92508282019050808211156153d0576153cf614f70565b5b92915050565b7f4d617820737570706c7920657863656564732100000000000000000000000000600082015250565b600061540c601383614491565b9150615417826153d6565b602082019050919050565b6000602082019050818103600083015261543b816153ff565b9050919050565b600061544d82614591565b915061545883614591565b92508282039050818111156154705761546f614f70565b5b92915050565b7f47616d65206d696e742073616c65206973207061757365642e00000000000000600082015250565b60006154ac601983614491565b91506154b782615476565b602082019050919050565b600060208201905081810360008301526154db8161549f565b9050919050565b7f47616d65206d696e742074696d6520697320616c726561647920757365640000600082015250565b6000615518601e83614491565b9150615523826154e2565b602082019050919050565b600060208201905081810360008301526155478161550b565b9050919050565b7f496e76616c69642063616c6c6572000000000000000000000000000000000000600082015250565b6000615584600e83614491565b915061558f8261554e565b602082019050919050565b600060208201905081810360008301526155b381615577565b9050919050565b7f496e76616c69642076616c6964617465207369676e6174757265000000000000600082015250565b60006155f0601a83614491565b91506155fb826155ba565b602082019050919050565b6000602082019050818103600083015261561f816155e3565b9050919050565b7f496e73756666696369656e74206e667420707269636520696e2067616d650000600082015250565b600061565c601e83614491565b915061566782615626565b602082019050919050565b6000602082019050818103600083015261568b8161564f565b9050919050565b7f4d696e742073616c65206973207061757365642e000000000000000000000000600082015250565b60006156c8601483614491565b91506156d382615692565b602082019050919050565b600060208201905081810360008301526156f7816156bb565b9050919050565b7f496e73756666696369656e74206e667420707269636500000000000000000000600082015250565b6000615734601683614491565b915061573f826156fe565b602082019050919050565b6000602082019050818103600083015261576381615727565b9050919050565b7f4d61726b6574706c6163652074726164652069732064697361626c6500000000600082015250565b60006157a0601c83614491565b91506157ab8261576a565b602082019050919050565b600060208201905081810360008301526157cf81615793565b9050919050565b600081905092915050565b60006157ec82614486565b6157f681856157d6565b93506158068185602086016144a2565b80840191505092915050565b6000815461581f81614e76565b61582981866157d6565b9450600182166000811461584457600181146158595761588c565b60ff198316865281151582028601935061588c565b61586285615124565b60005b8381101561588457815481890152600182019150602081019050615865565b838801955050505b50505092915050565b60006158a182866157e1565b91506158ad82856157e1565b91506158b98284615812565b9150819050949350505050565b600060a0820190506158db6000830188614724565b6158e86020830187614634565b6158f56040830186614634565b6159026060830185614634565b61590f608083018461438d565b9695505050505050565b7f1901000000000000000000000000000000000000000000000000000000000000600082015250565b600061594f6002836157d6565b915061595a82615919565b600282019050919050565b6000819050919050565b61598061597b8261471a565b615965565b82525050565b600061599182615942565b915061599d828561596f565b6020820191506159ad828461596f565b6020820191508190509392505050565b600060ff82169050919050565b6159d3816159bd565b82525050565b60006080820190506159ee6000830187614724565b6159fb60208301866159ca565b615a086040830185614724565b615a156060830184614724565b95945050505050565b600081905092915050565b50565b6000615a39600083615a1e565b9150615a4482615a29565b600082019050919050565b6000615a5a82615a2c565b9150819050919050565b600081519050919050565b600082825260208201905092915050565b6000615a8b82615a64565b615a958185615a6f565b9350615aa58185602086016144a2565b615aae816144cc565b840191505092915050565b6000608082019050615ace600083018761438d565b615adb602083018661438d565b615ae86040830185614634565b8181036060830152615afa8184615a80565b905095945050505050565b600081519050615b14816143f7565b92915050565b600060208284031215615b3057615b2f6143c1565b5b6000615b3e84828501615b05565b91505092915050565b6000615b62615b5d615b5884614d6d565b6151a8565b614591565b9050919050565b615b7281615b47565b82525050565b6000604082019050615b8d6000830185615b69565b615b9a6020830184614634565b9392505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea2646970667358221220436cef156d0e0dce4745a9f99575daf855f092add0339ccdb7dd6bbcd5a41cf864736f6c63430008140033

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

0000000000000000000000009551297cb58ad5ebc027deeb7ff3590fb80ace2f0000000000000000000000000000000000000000000000000000000000000d0500000000000000000000000000000000000000000000000000d529ae9e86000000000000000000000000000000000000000000000000000000b1a2bc2ec500000000000000000000000000000000000000000000000000000000000000000001000000000000000000000000000000000000000000000000000000000000028a

-----Decoded View---------------
Arg [0] : _funderWallet (address): 0x9551297cb58ad5EBC027deEb7FF3590fb80AcE2F
Arg [1] : _maxSupply (uint256): 3333
Arg [2] : nftCost (uint256): 60000000000000000
Arg [3] : gameNFTPrice (uint256): 50000000000000000
Arg [4] : networkChainId (uint256): 1
Arg [5] : feeNumerator (uint96): 650

-----Encoded View---------------
6 Constructor Arguments found :
Arg [0] : 0000000000000000000000009551297cb58ad5ebc027deeb7ff3590fb80ace2f
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000d05
Arg [2] : 00000000000000000000000000000000000000000000000000d529ae9e860000
Arg [3] : 00000000000000000000000000000000000000000000000000b1a2bc2ec50000
Arg [4] : 0000000000000000000000000000000000000000000000000000000000000001
Arg [5] : 000000000000000000000000000000000000000000000000000000000000028a


Deployed Bytecode Sourcemap

98389:13067:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99700:83;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;108778:195;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;75215:91;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99571:54;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;76387:158;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99194:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;110962:234;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;98935:19;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;102023:95;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99790:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99114:39;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;77056:588;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;103026:124;;;;;;;;;;;;;:::i;:::-;;63365:429;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;92635:260;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;102613:166;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;100115:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;77715:134;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;107783:320;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;103504:79;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;103845:113;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;99485:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;93152:231;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99427:20;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;102293:150;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;104521:156;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99454:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;108111:294;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;103310:85;;;;;;;;;;;;;:::i;:::-;;75028:120;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;104685:541;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;102451:154;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;99166:21;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;98968:26;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;103403:93;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;74753:213;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56389:103;;;;;;;;;;;;;:::i;:::-;;103595:111;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;51512:580;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;55714:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;105782:1055;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;103970:107;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;75375:95;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;105353:371;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;111204:248;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;77920:211;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;99229:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99258:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;107147:628;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99001:24;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;102153:132;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;99520:44;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;102787:166;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;104087:121;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;103162:140;;;;;;;;;;;;;:::i;:::-;;99032:29;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101820:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;76834:155;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;99068:39;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;104338:175;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;103714:119;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;56647:220;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;109663:1289;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;99700:83;99741:42;99700:83;:::o;108778:195::-;108900:4;108929:36;108953:11;108929:23;:36::i;:::-;108922:43;;108778:195;;;:::o;75215:91::-;75260:13;75293:5;75286:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75215:91;:::o;99571:54::-;;;;;;;;;;;;;;;;;;;;;;:::o;76387:158::-;76454:7;76474:22;76488:7;76474:13;:22::i;:::-;;76516:21;76529:7;76516:12;:21::i;:::-;76509:28;;76387:158;;;:::o;99194:28::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;110962:234::-;111061:22;:26;111084:2;111061:26;;;;;;;;;;;;;;;;;;;;;;;;;111060:27;111052:90;;;;;;;;;;;;:::i;:::-;;;;;;;;;111153:35;111162:2;111166:7;111175:12;:10;:12::i;:::-;111153:8;:35::i;:::-;110962:234;;:::o;98935:19::-;;;;:::o;102023:95::-;102075:7;102101:9;;102094:16;;102023:95;:::o;99790:37::-;;;:::o;99114:39::-;;;;:::o;77056:588::-;77165:1;77151:16;;:2;:16;;;77147:89;;77221:1;77191:33;;;;;;;;;;;:::i;:::-;;;;;;;;77147:89;77457:21;77481:34;77489:2;77493:7;77502:12;:10;:12::i;:::-;77481:7;:34::i;:::-;77457:58;;77547:4;77530:21;;:13;:21;;;77526:111;;77596:4;77602:7;77611:13;77575:50;;;;;;;;;;;;;:::i;:::-;;;;;;;;77526:111;77136:508;77056:588;;;:::o;103026:124::-;55600:13;:11;:13::i;:::-;103098:12:::1;;;;;;;;;;;103097:13;103082:12;;:28;;;;;;;;;;;;;;;;;;103126:16;;;;;;;;;;103026:124::o:0;63365:429::-;63451:7;63460;63480:26;63509:17;:26;63527:7;63509:26;;;;;;;;;;;63480:55;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63580:1;63552:30;;:7;:16;;;:30;;;63548:92;;63609:19;63599:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63548:92;63652:21;63716:17;:15;:17::i;:::-;63676:57;;63689:7;:23;;;63677:35;;:9;:35;;;;:::i;:::-;63676:57;;;;:::i;:::-;63652:81;;63754:7;:16;;;63772:13;63746:40;;;;;;63365:429;;;;;:::o;92635:260::-;92723:7;92756:16;92766:5;92756:9;:16::i;:::-;92747:5;:25;92743:101;;92819:5;92826;92796:36;;;;;;;;;;;;:::i;:::-;;;;;;;;92743:101;92861:12;:19;92874:5;92861:19;;;;;;;;;;;;;;;:26;92881:5;92861:26;;;;;;;;;;;;92854:33;;92635:260;;;;:::o;102613:166::-;102694:16;100623:1;100608:12;:16;100600:50;;;;;;;;;;;;:::i;:::-;;;;;;;;;55600:13:::1;:11;:13::i;:::-;102755:16:::2;102733:19;:38;;;;102613:166:::0;;:::o;100115:31::-;;;;:::o;77715:134::-;77802:39;77819:4;77825:2;77829:7;77802:39;;;;;;;;;;;;:16;:39::i;:::-;77715:134;;;:::o;107783:320::-;107843:16;107866:23;107892:17;107902:6;107892:9;:17::i;:::-;107866:43;;107914:25;107956:15;107942:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;107914:58;;107984:9;107979:98;107999:15;107995:1;:19;107979:98;;;108041:30;108061:6;108069:1;108041:19;:30::i;:::-;108027:8;108036:1;108027:11;;;;;;;;:::i;:::-;;;;;;;:44;;;;;108016:3;;;;;:::i;:::-;;;;107979:98;;;;108090:8;108083:15;;;;107783:320;;;:::o;103504:79::-;55600:13;:11;:13::i;:::-;103570:8:::1;103563:4;:15;;;;103504:79:::0;:::o;103845:113::-;55600:13;:11;:13::i;:::-;103922:11:::1;103912:7;:21;;;;;;:::i;:::-;;103949:4;103938:8;;:15;;;;;;;;;;;;;;;;;;103845:113:::0;:::o;99485:28::-;;;;;;;;;;;;;:::o;93152:231::-;93218:7;93251:13;:11;:13::i;:::-;93242:5;:22;93238:103;;93319:1;93323:5;93288:41;;;;;;;;;;;;:::i;:::-;;;;;;;;93238:103;93358:10;93369:5;93358:17;;;;;;;;:::i;:::-;;;;;;;;;;93351:24;;93152:231;;;:::o;99427:20::-;;;;;;;;;;;;;:::o;102293:150::-;55600:13;:11;:13::i;:::-;102431:4:::1;102385:22;:43;102408:19;102385:43;;;;;;;;;;;;;;;;:50;;;;;;;;;;;;;;;;;;102293:150:::0;:::o;104521:156::-;104592:7;104611:13;104634:12;104627:4;;:19;;;;:::i;:::-;104611:35;;104664:5;104657:12;;;104521:156;;;:::o;99454:24::-;;;;;;;;;;;;;:::o;108111:294::-;55600:13;:11;:13::i;:::-;108240:9:::1;;108218:11;;:18;;108201:14;;:35;;;;:::i;:::-;:48;;108193:80;;;;;;;;;;;;:::i;:::-;;;;;;;;;108289:9;108284:114;108305:11;;:18;;108302:1;:21;108284:114;;;108355:31;108368:11;;108380:1;108368:14;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;108384:1;108355:12;:31::i;:::-;108325:3;;;;;:::i;:::-;;;;108284:114;;;;108111:294:::0;;:::o;103310:85::-;55600:13;:11;:13::i;:::-;103379:8:::1;;;;;;;;;;;103378:9;103367:8;;:20;;;;;;;;;;;;;;;;;;103310:85::o:0;75028:120::-;75091:7;75118:22;75132:7;75118:13;:22::i;:::-;75111:29;;75028:120;;;:::o;104685:541::-;104775:7;104794:13;104824:12;104810:11;;:26;;;;:::i;:::-;104794:42;;104867:1;104850:13;:18;104847:170;;104884:30;104947:3;104926:19;;104918:5;:27;;;;:::i;:::-;104917:33;;;;:::i;:::-;104884:66;;104981:22;104973:5;:30;;;;:::i;:::-;104965:40;;;;;;104847:170;105047:1;105030:13;:18;105027:169;;105064:30;105127:3;105106:19;;105098:5;:27;;;;:::i;:::-;105097:33;;;;:::i;:::-;105064:66;;105161:22;105153:5;:30;;;;:::i;:::-;105145:39;;;;;;105027:169;105213:5;105206:12;;;104685:541;;;;;:::o;102451:154::-;55600:13;:11;:13::i;:::-;102592:5:::1;102546:22;:43;102569:19;102546:43;;;;;;;;;;;;;;;;:51;;;;;;;;;;;;;;;;;;102451:154:::0;:::o;99166:21::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;98968:26::-;;;;:::o;103403:93::-;55600:13;:11;:13::i;:::-;103481:10:::1;103469:9;:22;;;;103403:93:::0;:::o;74753:213::-;74816:7;74857:1;74840:19;;:5;:19;;;74836:89;;74910:1;74883:30;;;;;;;;;;;:::i;:::-;;;;;;;;74836:89;74942:9;:16;74952:5;74942:16;;;;;;;;;;;;;;;;74935:23;;74753:213;;;:::o;56389:103::-;55600:13;:11;:13::i;:::-;56454:30:::1;56481:1;56454:18;:30::i;:::-;56389:103::o:0;103595:111::-;55600:13;:11;:13::i;:::-;103684:14:::1;103670:11;:28;;;;103595:111:::0;:::o;51512:580::-;51615:13;51643:18;51676:21;51712:15;51742:25;51782:12;51809:27;51917:13;:11;:13::i;:::-;51945:16;:14;:16::i;:::-;51976:13;52012:4;52040:1;52032:10;;52071:1;52057:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;51864:220;;;;;;;;;;;;;;;;;;;;;51512:580;;;;;;;:::o;55714:87::-;55760:7;55787:6;;;;;;;;;;;55780:13;;55714:87;:::o;105782:1055::-;100310:16;;;;;;;;;;;100302:54;;;;;;;;;;;;:::i;:::-;;;;;;;;;105981:14:::1;105997:22:::0;106023:90:::1;106031:12;106046:8;106057:13;106073:5;106082:9;106095:17;106023:6;:90::i;:::-;105980:133;;;;106124:15;106142:12;106124:30;;106165:20;106188:8;106165:31;;106207:15;106225:13;106207:31;;106258:12;:21;106271:7;106258:21;;;;;;;;;;;;;;;;;;;;;106257:22;106249:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;106325:20;106348:38;106364:7;106373:12;106348:15;:38::i;:::-;106325:61;;106419:6;106405:20;;:10;:20;;;106397:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;106481:14;106463:32;;99741:42;106463:32;;;106455:71;;;;;;;;;;;;:::i;:::-;;;;;;;;;106573:9;;106562:7;106545:14;;:24;;;;:::i;:::-;:37;;106537:69;;;;;;;;;;;;:::i;:::-;;;;;;;;;106638:12;106625:9;:25;;106617:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;106696:51;106722:12;106737:9;106696:17;:51::i;:::-;106758:33;106771:10;106783:7;106758:12;:33::i;:::-;106825:4;106802:12;:21;106815:7;106802:21;;;;;;;;;;;;:27;;;;;;;;;;;;;;;;;;105969:868;;;;;;105782:1055:::0;;;;;;:::o;103970:107::-;55600:13;:11;:13::i;:::-;104060:12:::1;104046:11;:26;;;;;;:::i;:::-;;103970:107:::0;:::o;75375:95::-;75422:13;75455:7;75448:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75375:95;:::o;105353:371::-;100196:12;;;;;;;;;;;100188:45;;;;;;;;;;;;:::i;:::-;;;;;;;;;105421:12:::1;100479:9;;100463:12;100446:14;;:29;;;;:::i;:::-;:42;;100438:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;105453:12:::2;100623:1;100608:12;:16:::0;100600:50:::2;;;;;;;;;;;;:::i;:::-;;;;;;;;;105486:16:::3;105505:33;105525:12;105505:19;:33::i;:::-;105486:52;;105570:8;105557:9;:21;;105549:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;105616:51;105642:12;105657:9;105616:17;:51::i;:::-;105678:38;105691:10;105703:12;105678;:38::i;:::-;105475:249;100523:1:::2;100244::::1;105353:371:::0;:::o;111204:248::-;111316:22;:32;111339:8;111316:32;;;;;;;;;;;;;;;;;;;;;;;;;111315:33;111307:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;111392:52;111411:12;:10;:12::i;:::-;111425:8;111435;111392:18;:52::i;:::-;111204:248;;:::o;77920:211::-;78034:31;78047:4;78053:2;78057:7;78034:12;:31::i;:::-;78076:47;78099:4;78105:2;78109:7;78118:4;78076:22;:47::i;:::-;77920:211;;;;:::o;99229:25::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;99258:37::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;107147:628::-;107265:13;107300:22;107314:7;107300:13;:22::i;:::-;;107338:8;;;;;;;;;;;107333:63;;107370:14;107363:21;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;107333:63;107408:28;107439:10;:8;:10::i;:::-;107408:41;;107511:1;107486:14;107480:28;:32;:287;;;;;;;;;;;;;;;;;107604:14;107645:18;:7;:16;:18::i;:::-;107690:13;107561:165;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;107480:287;107460:307;;;107147:628;;;;:::o;99001:24::-;;;;:::o;102153:132::-;55600:13;:11;:13::i;:::-;102231:46:::1;102250:12;102264;102231:18;:46::i;:::-;102153:132:::0;:::o;99520:44::-;;;;;;;;;;;;;;;;;;;;;;:::o;102787:166::-;102868:16;100623:1;100608:12;:16;100600:50;;;;;;;;;;;;:::i;:::-;;;;;;;;;55600:13:::1;:11;:13::i;:::-;102929:16:::2;102907:19;:38;;;;102787:166:::0;;:::o;104087:121::-;55600:13;:11;:13::i;:::-;104186:17:::1;104170:13;:33;;;;;;:::i;:::-;;104087:121:::0;:::o;103162:140::-;55600:13;:11;:13::i;:::-;103242:16:::1;;;;;;;;;;;103241:17;103222:16;;:36;;;;;;;;;;;;;;;;;;103274:20;;;;;;;;;;103162:140::o:0;99032:29::-;;;;:::o;101820:87::-;101864:13;101891:11;101884:18;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;101820:87;:::o;76834:155::-;76922:4;76946:18;:25;76965:5;76946:25;;;;;;;;;;;;;;;:35;76972:8;76946:35;;;;;;;;;;;;;;;;;;;;;;;;;76939:42;;76834:155;;;;:::o;99068:39::-;;;;:::o;104338:175::-;104400:12;100479:9;;100463:12;100446:14;;:29;;;;:::i;:::-;:42;;100438:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;104432:12:::1;100623:1;100608:12;:16:::0;100600:50:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;55600:13:::2;:11;:13::i;:::-;104467:38:::3;104480:10;104492:12;104467;:38::i;:::-;100523:1:::1;104338:175:::0;;:::o;103714:119::-;55600:13;:11;:13::i;:::-;103813:15:::1;103796:14;:32;;;;;;:::i;:::-;;103714:119:::0;:::o;56647:220::-;55600:13;:11;:13::i;:::-;56752:1:::1;56732:22;;:8;:22;;::::0;56728:93:::1;;56806:1;56778:31;;;;;;;;;;;:::i;:::-;;;;;;;;56728:93;56831:28;56850:8;56831:18;:28::i;:::-;56647:220:::0;:::o;109663:1289::-;109834:7;109843;109937:16;100009:99;110018:12;110045:8;110068:13;110096:5;109966:146;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;109956:157;;;;;;109937:176;;110124:14;110207:16;;110238:8;110151:106;;;;;;;;;:::i;:::-;;;;;;;;;;;;;110141:117;;;;;;110124:134;;110269:23;110295:9;110269:35;;110315:26;110344:17;110315:46;;110372:7;110390:9;110410;110430;110450:11;110472;110547:4;110535:10;110531:21;110525:28;110520:33;;110594:4;110582:10;110578:21;110572:28;110567:33;;110649:4;110637:10;110633:21;110627:28;110624:1;110619:37;110614:42;;110735:4;110720:13;110716:24;110710:31;110703:38;;110787:4;110772:13;110768:24;110762:31;110755:38;;110847:4;110832:13;110828:24;110822:31;110819:1;110814:40;110807:47;;110883:26;110893:6;110901:1;110904;110907;110883:26;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;110911:32;110921:6;110929:3;110934;110939;110911:32;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;110875:69;;;;;;;;;;;;;;109663:1289;;;;;;;;;:::o;63095:215::-;63197:4;63236:26;63221:41;;;:11;:41;;;;:81;;;;63266:36;63290:11;63266:23;:36::i;:::-;63221:81;63214:88;;63095:215;;;:::o;89362:247::-;89425:7;89445:13;89461:17;89470:7;89461:8;:17::i;:::-;89445:33;;89510:1;89493:19;;:5;:19;;;89489:90;;89559:7;89536:31;;;;;;;;;;;:::i;:::-;;;;;;;;89489:90;89596:5;89589:12;;;89362:247;;;:::o;78893:129::-;78963:7;78990:15;:24;79006:7;78990:24;;;;;;;;;;;;;;;;;;;;;78983:31;;78893:129;;;:::o;53723:98::-;53776:7;53803:10;53796:17;;53723:98;:::o;87594:122::-;87675:33;87684:2;87688:7;87697:4;87703;87675:8;:33::i;:::-;87594:122;;;:::o;108413:185::-;108526:7;108558:32;108572:2;108576:7;108585:4;108558:13;:32::i;:::-;108551:39;;108413:185;;;;;:::o;55879:166::-;55950:12;:10;:12::i;:::-;55939:23;;:7;:5;:7::i;:::-;:23;;;55935:103;;56013:12;:10;:12::i;:::-;55986:40;;;;;;;;;;;:::i;:::-;;;;;;;;55935:103;55879:166::o;64076:97::-;64134:6;64160:5;64153:12;;64076:97;:::o;106845:294::-;106923:17;106943:14;;106923:34;;106973:9;106985:1;106973:13;;106968:164;106993:12;106988:1;:17;106968:164;;107027:11;107053:1;107041:9;:13;;;;:::i;:::-;107027:27;;107069:20;107079:4;107085:3;107069:9;:20::i;:::-;107104:14;;:16;;;;;;;;;:::i;:::-;;;;;;107012:120;107007:3;;;;;:::i;:::-;;;;106968:164;;;;106912:227;106845:294;;:::o;57027:191::-;57101:16;57120:6;;;;;;;;;;;57101:25;;57146:8;57137:6;;:17;;;;;;;;;;;;;;;;;;57201:8;57170:40;;57191:8;57170:40;;;;;;;;;;;;57090:128;57027:191;:::o;52421:128::-;52467:13;52500:41;52527:13;52500:5;:26;;:41;;;;:::i;:::-;52493:48;;52421:128;:::o;52884:137::-;52933:13;52966:47;52996:16;52966:8;:29;;:47;;;;:::i;:::-;52959:54;;52884:137;:::o;10934:340::-;11044:6;11020:21;:30;11016:111;;;11109:4;11074:41;;;;;;;;;;;:::i;:::-;;;;;;;;11016:111;11140:12;11158:9;:14;;11180:6;11158:33;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;11139:52;;;11207:7;11202:65;;11238:17;;;;;;;;;;;;;;11202:65;11005:269;10934:340;;:::o;88801:318::-;88929:1;88909:22;;:8;:22;;;88905:93;;88977:8;88955:31;;;;;;;;;;;:::i;:::-;;;;;;;;88905:93;89046:8;89008:18;:25;89027:5;89008:25;;;;;;;;;;;;;;;:35;89034:8;89008:35;;;;;;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;89092:8;89070:41;;89085:5;89070:41;;;89102:8;89070:41;;;;;;:::i;:::-;;;;;;;;88801:318;;;:::o;90159:799::-;90293:1;90276:2;:14;;;:18;90272:679;;;90331:2;90315:36;;;90352:12;:10;:12::i;:::-;90366:4;90372:7;90381:4;90315:71;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;90311:629;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;90646:1;90629:6;:13;:18;90625:300;;90701:2;90679:25;;;;;;;;;;;:::i;:::-;;;;;;;;90625:300;90875:6;90869:13;90860:6;90856:2;90852:15;90845:38;90311:629;90444:41;;;90434:51;;;:6;:51;;;;90430:132;;90539:2;90517:25;;;;;;;;;;;:::i;:::-;;;;;;;;90430:132;90387:190;90272:679;90159:799;;;;:::o;101915:100::-;101967:13;102000:7;101993:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;101915:100;:::o;40011:718::-;40067:13;40118:14;40155:1;40135:17;40146:5;40135:10;:17::i;:::-;:21;40118:38;;40171:20;40205:6;40194:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40171:41;;40227:11;40356:6;40352:2;40348:15;40340:6;40336:28;40329:35;;40393:290;40400:4;40393:290;;;40425:5;;;;;;;;40567:10;40562:2;40555:5;40551:14;40546:32;40541:3;40533:46;40625:2;40616:11;;;;;;:::i;:::-;;;;;40659:1;40650:5;:10;40393:290;40646:21;40393:290;40704:6;40697:13;;;;;40011:718;;;:::o;64444:518::-;64539:19;64561:17;:15;:17::i;:::-;64539:39;;;;64608:11;64593:12;:26;;;64589:176;;;64727:12;64741:11;64698:55;;;;;;;;;;;;:::i;:::-;;;;;;;;64589:176;64799:1;64779:22;;:8;:22;;;64775:110;;64870:1;64825:48;;;;;;;;;;;:::i;:::-;;;;;;;;64775:110;64919:35;;;;;;;;64931:8;64919:35;;;;;;64941:12;64919:35;;;;;64897:19;:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;64528:434;64444:518;;:::o;92327:224::-;92429:4;92468:35;92453:50;;;:11;:50;;;;:90;;;;92507:36;92531:11;92507:23;:36::i;:::-;92453:90;92446:97;;92327:224;;;:::o;78655:117::-;78721:7;78748;:16;78756:7;78748:16;;;;;;;;;;;;;;;;;;;;;78741:23;;78655:117;;;:::o;87904:678::-;88066:9;:31;;;;88095:1;88079:18;;:4;:18;;;;88066:31;88062:471;;;88114:13;88130:22;88144:7;88130:13;:22::i;:::-;88114:38;;88299:1;88283:18;;:4;:18;;;;:35;;;;;88314:4;88305:13;;:5;:13;;;;88283:35;:69;;;;;88323:29;88340:5;88347:4;88323:16;:29::i;:::-;88322:30;88283:69;88279:144;;;88402:4;88380:27;;;;;;;;;;;:::i;:::-;;;;;;;;88279:144;88443:9;88439:83;;;88498:7;88494:2;88478:28;;88487:5;88478:28;;;;;;;;;;;;88439:83;88099:434;88062:471;88572:2;88545:15;:24;88561:7;88545:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;87904:678;;;;:::o;93444:640::-;93539:7;93559:21;93583:32;93597:2;93601:7;93610:4;93583:13;:32::i;:::-;93559:56;;93657:1;93632:27;;:13;:27;;;93628:214;;93676:40;93708:7;93676:31;:40::i;:::-;93628:214;;;93755:2;93738:19;;:13;:19;;;93734:108;;93774:56;93807:13;93822:7;93774:32;:56::i;:::-;93734:108;93628:214;93870:1;93856:16;;:2;:16;;;93852:192;;93889:45;93926:7;93889:36;:45::i;:::-;93852:192;;;93973:2;93956:19;;:13;:19;;;93952:92;;93992:40;94020:2;94024:7;93992:27;:40::i;:::-;93952:92;93852:192;94063:13;94056:20;;;93444:640;;;;;:::o;83713:102::-;83781:26;83791:2;83795:7;83781:26;;;;;;;;;;;;:9;:26::i;:::-;83713:102;;:::o;8391:273::-;8485:13;6337:66;8544:17;;8534:5;8515:46;8511:146;;8585:15;8594:5;8585:8;:15::i;:::-;8578:22;;;;8511:146;8640:5;8633:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8391:273;;;;;:::o;36415:948::-;36468:7;36488:14;36505:1;36488:18;;36555:8;36546:5;:17;36542:106;;36593:8;36584:17;;;;;;:::i;:::-;;;;;36630:2;36620:12;;;;36542:106;36675:8;36666:5;:17;36662:106;;36713:8;36704:17;;;;;;:::i;:::-;;;;;36750:2;36740:12;;;;36662:106;36795:8;36786:5;:17;36782:106;;36833:8;36824:17;;;;;;:::i;:::-;;;;;36870:2;36860:12;;;;36782:106;36915:7;36906:5;:16;36902:103;;36952:7;36943:16;;;;;;:::i;:::-;;;;;36988:1;36978:11;;;;36902:103;37032:7;37023:5;:16;37019:103;;37069:7;37060:16;;;;;;:::i;:::-;;;;;37105:1;37095:11;;;;37019:103;37149:7;37140:5;:16;37136:103;;37186:7;37177:16;;;;;;:::i;:::-;;;;;37222:1;37212:11;;;;37136:103;37266:7;37257:5;:16;37253:68;;37304:1;37294:11;;;;37253:68;37349:6;37342:13;;;36415:948;;;:::o;74384:305::-;74486:4;74538:25;74523:40;;;:11;:40;;;;:105;;;;74595:33;74580:48;;;:11;:48;;;;74523:105;:158;;;;74645:36;74669:11;74645:23;:36::i;:::-;74523:158;74503:178;;74384:305;;;:::o;81855:824::-;81941:7;81961:12;81976:17;81985:7;81976:8;:17::i;:::-;81961:32;;82072:1;82056:18;;:4;:18;;;82052:88;;82091:37;82108:4;82114;82120:7;82091:16;:37::i;:::-;82052:88;82203:1;82187:18;;:4;:18;;;82183:263;;82305:48;82322:1;82326:7;82343:1;82347:5;82305:8;:48::i;:::-;82418:1;82399:9;:15;82409:4;82399:15;;;;;;;;;;;;;;;;:20;;;;;;;;;;;82183:263;82476:1;82462:16;;:2;:16;;;82458:111;;82541:1;82524:9;:13;82534:2;82524:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;82458:111;82600:2;82581:7;:16;82589:7;82581:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;82639:7;82635:2;82620:27;;82629:4;82620:27;;;;;;;;;;;;82667:4;82660:11;;;81855:824;;;;;:::o;94804:164::-;94908:10;:17;;;;94881:15;:24;94897:7;94881:24;;;;;;;;;;;:44;;;;94936:10;94952:7;94936:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;94804:164;:::o;95595:977::-;95861:22;95886:15;95896:4;95886:9;:15::i;:::-;95861:40;;95912:18;95933:17;:26;95951:7;95933:26;;;;;;;;;;;;95912:47;;96080:14;96066:10;:28;96062:328;;96111:19;96133:12;:18;96146:4;96133:18;;;;;;;;;;;;;;;:34;96152:14;96133:34;;;;;;;;;;;;96111:56;;96217:11;96184:12;:18;96197:4;96184:18;;;;;;;;;;;;;;;:30;96203:10;96184:30;;;;;;;;;;;:44;;;;96334:10;96301:17;:30;96319:11;96301:30;;;;;;;;;;;:43;;;;96096:294;96062:328;96486:17;:26;96504:7;96486:26;;;;;;;;;;;96479:33;;;96530:12;:18;96543:4;96530:18;;;;;;;;;;;;;;;:34;96549:14;96530:34;;;;;;;;;;;96523:41;;;95676:896;;95595:977;;:::o;96867:1079::-;97120:22;97165:1;97145:10;:17;;;;:21;;;;:::i;:::-;97120:46;;97177:18;97198:15;:24;97214:7;97198:24;;;;;;;;;;;;97177:45;;97549:19;97571:10;97582:14;97571:26;;;;;;;;:::i;:::-;;;;;;;;;;97549:48;;97635:11;97610:10;97621;97610:22;;;;;;;;:::i;:::-;;;;;;;;;:36;;;;97746:10;97715:15;:28;97731:11;97715:28;;;;;;;;;;;:41;;;;97887:15;:24;97903:7;97887:24;;;;;;;;;;;97880:31;;;97922:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;96938:1008;;;96867:1079;:::o;94385:218::-;94470:14;94503:1;94487:13;94497:2;94487:9;:13::i;:::-;:17;;;;:::i;:::-;94470:34;;94542:7;94515:12;:16;94528:2;94515:16;;;;;;;;;;;;;;;:24;94532:6;94515:24;;;;;;;;;;;:34;;;;94589:6;94560:17;:26;94578:7;94560:26;;;;;;;;;;;:35;;;;94459:144;94385:218;;:::o;84042:185::-;84137:18;84143:2;84147:7;84137:5;:18::i;:::-;84166:53;84197:1;84201:2;84205:7;84214:4;84166:22;:53::i;:::-;84042:185;;;:::o;7046:415::-;7105:13;7131:11;7145:16;7156:4;7145:10;:16::i;:::-;7131:30;;7251:17;7282:2;7271:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;7251:34;;7376:3;7371;7364:16;7417:4;7410;7405:3;7401:14;7394:28;7450:3;7443:10;;;;7046:415;;;:::o;60867:148::-;60943:4;60982:25;60967:40;;;:11;:40;;;;60960:47;;60867:148;;;:::o;80062:376::-;80175:38;80189:5;80196:7;80205;80175:13;:38::i;:::-;80170:261;;80251:1;80234:19;;:5;:19;;;80230:190;;80304:7;80281:31;;;;;;;;;;;:::i;:::-;;;;;;;;80230:190;80387:7;80396;80360:44;;;;;;;;;;;;:::i;:::-;;;;;;;;80170:261;80062:376;;;:::o;83015:335::-;83097:1;83083:16;;:2;:16;;;83079:89;;83153:1;83123:33;;;;;;;;;;;:::i;:::-;;;;;;;;83079:89;83178:21;83202:32;83210:2;83214:7;83231:1;83202:7;:32::i;:::-;83178:56;;83274:1;83249:27;;:13;:27;;;83245:98;;83328:1;83300:31;;;;;;;;;;;:::i;:::-;;;;;;;;83245:98;83068:282;83015:335;;:::o;7538:251::-;7599:7;7619:14;7672:4;7663;7636:33;;:40;7619:57;;7700:2;7691:6;:11;7687:71;;;7726:20;;;;;;;;;;;;;;7687:71;7775:6;7768:13;;;7538:251;;;:::o;79342:276::-;79445:4;79501:1;79482:21;;:7;:21;;;;:128;;;;;79530:7;79521:16;;:5;:16;;;:52;;;;79541:32;79558:5;79565:7;79541:16;:32::i;:::-;79521:52;:88;;;;79602:7;79577:32;;:21;79590:7;79577:12;:21::i;:::-;:32;;;79521:88;79482:128;79462:148;;79342:276;;;;;:::o;7:126:1:-;44:7;84:42;77:5;73:54;62:65;;7:126;;;:::o;139:96::-;176:7;205:24;223:5;205:24;:::i;:::-;194:35;;139:96;;;:::o;241:118::-;328:24;346:5;328:24;:::i;:::-;323:3;316:37;241:118;;:::o;365:222::-;458:4;496:2;485:9;481:18;473:26;;509:71;577:1;566:9;562:17;553:6;509:71;:::i;:::-;365:222;;;;:::o;593:75::-;626:6;659:2;653:9;643:19;;593:75;:::o;674:117::-;783:1;780;773:12;797:117;906:1;903;896:12;920:149;956:7;996:66;989:5;985:78;974:89;;920:149;;;:::o;1075:120::-;1147:23;1164:5;1147:23;:::i;:::-;1140:5;1137:34;1127:62;;1185:1;1182;1175:12;1127:62;1075:120;:::o;1201:137::-;1246:5;1284:6;1271:20;1262:29;;1300:32;1326:5;1300:32;:::i;:::-;1201:137;;;;:::o;1344:327::-;1402:6;1451:2;1439:9;1430:7;1426:23;1422:32;1419:119;;;1457:79;;:::i;:::-;1419:119;1577:1;1602:52;1646:7;1637:6;1626:9;1622:22;1602:52;:::i;:::-;1592:62;;1548:116;1344:327;;;;:::o;1677:90::-;1711:7;1754:5;1747:13;1740:21;1729:32;;1677:90;;;:::o;1773:109::-;1854:21;1869:5;1854:21;:::i;:::-;1849:3;1842:34;1773:109;;:::o;1888:210::-;1975:4;2013:2;2002:9;1998:18;1990:26;;2026:65;2088:1;2077:9;2073:17;2064:6;2026:65;:::i;:::-;1888:210;;;;:::o;2104:99::-;2156:6;2190:5;2184:12;2174:22;;2104:99;;;:::o;2209:169::-;2293:11;2327:6;2322:3;2315:19;2367:4;2362:3;2358:14;2343:29;;2209:169;;;;:::o;2384:246::-;2465:1;2475:113;2489:6;2486:1;2483:13;2475:113;;;2574:1;2569:3;2565:11;2559:18;2555:1;2550:3;2546:11;2539:39;2511:2;2508:1;2504:10;2499:15;;2475:113;;;2622:1;2613:6;2608:3;2604:16;2597:27;2446:184;2384:246;;;:::o;2636:102::-;2677:6;2728:2;2724:7;2719:2;2712:5;2708:14;2704:28;2694:38;;2636:102;;;:::o;2744:377::-;2832:3;2860:39;2893:5;2860:39;:::i;:::-;2915:71;2979:6;2974:3;2915:71;:::i;:::-;2908:78;;2995:65;3053:6;3048:3;3041:4;3034:5;3030:16;2995:65;:::i;:::-;3085:29;3107:6;3085:29;:::i;:::-;3080:3;3076:39;3069:46;;2836:285;2744:377;;;;:::o;3127:313::-;3240:4;3278:2;3267:9;3263:18;3255:26;;3327:9;3321:4;3317:20;3313:1;3302:9;3298:17;3291:47;3355:78;3428:4;3419:6;3355:78;:::i;:::-;3347:86;;3127:313;;;;:::o;3446:122::-;3519:24;3537:5;3519:24;:::i;:::-;3512:5;3509:35;3499:63;;3558:1;3555;3548:12;3499:63;3446:122;:::o;3574:139::-;3620:5;3658:6;3645:20;3636:29;;3674:33;3701:5;3674:33;:::i;:::-;3574:139;;;;:::o;3719:329::-;3778:6;3827:2;3815:9;3806:7;3802:23;3798:32;3795:119;;;3833:79;;:::i;:::-;3795:119;3953:1;3978:53;4023:7;4014:6;4003:9;3999:22;3978:53;:::i;:::-;3968:63;;3924:117;3719:329;;;;:::o;4054:77::-;4091:7;4120:5;4109:16;;4054:77;;;:::o;4137:122::-;4210:24;4228:5;4210:24;:::i;:::-;4203:5;4200:35;4190:63;;4249:1;4246;4239:12;4190:63;4137:122;:::o;4265:139::-;4311:5;4349:6;4336:20;4327:29;;4365:33;4392:5;4365:33;:::i;:::-;4265:139;;;;:::o;4410:329::-;4469:6;4518:2;4506:9;4497:7;4493:23;4489:32;4486:119;;;4524:79;;:::i;:::-;4486:119;4644:1;4669:53;4714:7;4705:6;4694:9;4690:22;4669:53;:::i;:::-;4659:63;;4615:117;4410:329;;;;:::o;4745:474::-;4813:6;4821;4870:2;4858:9;4849:7;4845:23;4841:32;4838:119;;;4876:79;;:::i;:::-;4838:119;4996:1;5021:53;5066:7;5057:6;5046:9;5042:22;5021:53;:::i;:::-;5011:63;;4967:117;5123:2;5149:53;5194:7;5185:6;5174:9;5170:22;5149:53;:::i;:::-;5139:63;;5094:118;4745:474;;;;;:::o;5225:118::-;5312:24;5330:5;5312:24;:::i;:::-;5307:3;5300:37;5225:118;;:::o;5349:222::-;5442:4;5480:2;5469:9;5465:18;5457:26;;5493:71;5561:1;5550:9;5546:17;5537:6;5493:71;:::i;:::-;5349:222;;;;:::o;5577:619::-;5654:6;5662;5670;5719:2;5707:9;5698:7;5694:23;5690:32;5687:119;;;5725:79;;:::i;:::-;5687:119;5845:1;5870:53;5915:7;5906:6;5895:9;5891:22;5870:53;:::i;:::-;5860:63;;5816:117;5972:2;5998:53;6043:7;6034:6;6023:9;6019:22;5998:53;:::i;:::-;5988:63;;5943:118;6100:2;6126:53;6171:7;6162:6;6151:9;6147:22;6126:53;:::i;:::-;6116:63;;6071:118;5577:619;;;;;:::o;6202:474::-;6270:6;6278;6327:2;6315:9;6306:7;6302:23;6298:32;6295:119;;;6333:79;;:::i;:::-;6295:119;6453:1;6478:53;6523:7;6514:6;6503:9;6499:22;6478:53;:::i;:::-;6468:63;;6424:117;6580:2;6606:53;6651:7;6642:6;6631:9;6627:22;6606:53;:::i;:::-;6596:63;;6551:118;6202:474;;;;;:::o;6682:332::-;6803:4;6841:2;6830:9;6826:18;6818:26;;6854:71;6922:1;6911:9;6907:17;6898:6;6854:71;:::i;:::-;6935:72;7003:2;6992:9;6988:18;6979:6;6935:72;:::i;:::-;6682:332;;;;;:::o;7020:77::-;7057:7;7086:5;7075:16;;7020:77;;;:::o;7103:118::-;7190:24;7208:5;7190:24;:::i;:::-;7185:3;7178:37;7103:118;;:::o;7227:222::-;7320:4;7358:2;7347:9;7343:18;7335:26;;7371:71;7439:1;7428:9;7424:17;7415:6;7371:71;:::i;:::-;7227:222;;;;:::o;7455:114::-;7522:6;7556:5;7550:12;7540:22;;7455:114;;;:::o;7575:184::-;7674:11;7708:6;7703:3;7696:19;7748:4;7743:3;7739:14;7724:29;;7575:184;;;;:::o;7765:132::-;7832:4;7855:3;7847:11;;7885:4;7880:3;7876:14;7868:22;;7765:132;;;:::o;7903:108::-;7980:24;7998:5;7980:24;:::i;:::-;7975:3;7968:37;7903:108;;:::o;8017:179::-;8086:10;8107:46;8149:3;8141:6;8107:46;:::i;:::-;8185:4;8180:3;8176:14;8162:28;;8017:179;;;;:::o;8202:113::-;8272:4;8304;8299:3;8295:14;8287:22;;8202:113;;;:::o;8351:732::-;8470:3;8499:54;8547:5;8499:54;:::i;:::-;8569:86;8648:6;8643:3;8569:86;:::i;:::-;8562:93;;8679:56;8729:5;8679:56;:::i;:::-;8758:7;8789:1;8774:284;8799:6;8796:1;8793:13;8774:284;;;8875:6;8869:13;8902:63;8961:3;8946:13;8902:63;:::i;:::-;8895:70;;8988:60;9041:6;8988:60;:::i;:::-;8978:70;;8834:224;8821:1;8818;8814:9;8809:14;;8774:284;;;8778:14;9074:3;9067:10;;8475:608;;;8351:732;;;;:::o;9089:373::-;9232:4;9270:2;9259:9;9255:18;9247:26;;9319:9;9313:4;9309:20;9305:1;9294:9;9290:17;9283:47;9347:108;9450:4;9441:6;9347:108;:::i;:::-;9339:116;;9089:373;;;;:::o;9468:117::-;9577:1;9574;9567:12;9591:117;9700:1;9697;9690:12;9714:180;9762:77;9759:1;9752:88;9859:4;9856:1;9849:15;9883:4;9880:1;9873:15;9900:281;9983:27;10005:4;9983:27;:::i;:::-;9975:6;9971:40;10113:6;10101:10;10098:22;10077:18;10065:10;10062:34;10059:62;10056:88;;;10124:18;;:::i;:::-;10056:88;10164:10;10160:2;10153:22;9943:238;9900:281;;:::o;10187:129::-;10221:6;10248:20;;:::i;:::-;10238:30;;10277:33;10305:4;10297:6;10277:33;:::i;:::-;10187:129;;;:::o;10322:308::-;10384:4;10474:18;10466:6;10463:30;10460:56;;;10496:18;;:::i;:::-;10460:56;10534:29;10556:6;10534:29;:::i;:::-;10526:37;;10618:4;10612;10608:15;10600:23;;10322:308;;;:::o;10636:146::-;10733:6;10728:3;10723;10710:30;10774:1;10765:6;10760:3;10756:16;10749:27;10636:146;;;:::o;10788:425::-;10866:5;10891:66;10907:49;10949:6;10907:49;:::i;:::-;10891:66;:::i;:::-;10882:75;;10980:6;10973:5;10966:21;11018:4;11011:5;11007:16;11056:3;11047:6;11042:3;11038:16;11035:25;11032:112;;;11063:79;;:::i;:::-;11032:112;11153:54;11200:6;11195:3;11190;11153:54;:::i;:::-;10872:341;10788:425;;;;;:::o;11233:340::-;11289:5;11338:3;11331:4;11323:6;11319:17;11315:27;11305:122;;11346:79;;:::i;:::-;11305:122;11463:6;11450:20;11488:79;11563:3;11555:6;11548:4;11540:6;11536:17;11488:79;:::i;:::-;11479:88;;11295:278;11233:340;;;;:::o;11579:509::-;11648:6;11697:2;11685:9;11676:7;11672:23;11668:32;11665:119;;;11703:79;;:::i;:::-;11665:119;11851:1;11840:9;11836:17;11823:31;11881:18;11873:6;11870:30;11867:117;;;11903:79;;:::i;:::-;11867:117;12008:63;12063:7;12054:6;12043:9;12039:22;12008:63;:::i;:::-;11998:73;;11794:287;11579:509;;;;:::o;12094:117::-;12203:1;12200;12193:12;12217:117;12326:1;12323;12316:12;12357:568;12430:8;12440:6;12490:3;12483:4;12475:6;12471:17;12467:27;12457:122;;12498:79;;:::i;:::-;12457:122;12611:6;12598:20;12588:30;;12641:18;12633:6;12630:30;12627:117;;;12663:79;;:::i;:::-;12627:117;12777:4;12769:6;12765:17;12753:29;;12831:3;12823:4;12815:6;12811:17;12801:8;12797:32;12794:41;12791:128;;;12838:79;;:::i;:::-;12791:128;12357:568;;;;;:::o;12931:559::-;13017:6;13025;13074:2;13062:9;13053:7;13049:23;13045:32;13042:119;;;13080:79;;:::i;:::-;13042:119;13228:1;13217:9;13213:17;13200:31;13258:18;13250:6;13247:30;13244:117;;;13280:79;;:::i;:::-;13244:117;13393:80;13465:7;13456:6;13445:9;13441:22;13393:80;:::i;:::-;13375:98;;;;13171:312;12931:559;;;;;:::o;13496:149::-;13532:7;13572:66;13565:5;13561:78;13550:89;;13496:149;;;:::o;13651:115::-;13736:23;13753:5;13736:23;:::i;:::-;13731:3;13724:36;13651:115;;:::o;13772:1215::-;14121:4;14159:3;14148:9;14144:19;14136:27;;14173:69;14239:1;14228:9;14224:17;14215:6;14173:69;:::i;:::-;14289:9;14283:4;14279:20;14274:2;14263:9;14259:18;14252:48;14317:78;14390:4;14381:6;14317:78;:::i;:::-;14309:86;;14442:9;14436:4;14432:20;14427:2;14416:9;14412:18;14405:48;14470:78;14543:4;14534:6;14470:78;:::i;:::-;14462:86;;14558:72;14626:2;14615:9;14611:18;14602:6;14558:72;:::i;:::-;14640:73;14708:3;14697:9;14693:19;14684:6;14640:73;:::i;:::-;14723;14791:3;14780:9;14776:19;14767:6;14723:73;:::i;:::-;14844:9;14838:4;14834:20;14828:3;14817:9;14813:19;14806:49;14872:108;14975:4;14966:6;14872:108;:::i;:::-;14864:116;;13772:1215;;;;;;;;;;:::o;14993:307::-;15054:4;15144:18;15136:6;15133:30;15130:56;;;15166:18;;:::i;:::-;15130:56;15204:29;15226:6;15204:29;:::i;:::-;15196:37;;15288:4;15282;15278:15;15270:23;;14993:307;;;:::o;15306:423::-;15383:5;15408:65;15424:48;15465:6;15424:48;:::i;:::-;15408:65;:::i;:::-;15399:74;;15496:6;15489:5;15482:21;15534:4;15527:5;15523:16;15572:3;15563:6;15558:3;15554:16;15551:25;15548:112;;;15579:79;;:::i;:::-;15548:112;15669:54;15716:6;15711:3;15706;15669:54;:::i;:::-;15389:340;15306:423;;;;;:::o;15748:338::-;15803:5;15852:3;15845:4;15837:6;15833:17;15829:27;15819:122;;15860:79;;:::i;:::-;15819:122;15977:6;15964:20;16002:78;16076:3;16068:6;16061:4;16053:6;16049:17;16002:78;:::i;:::-;15993:87;;15809:277;15748:338;;;;:::o;16092:1413::-;16214:6;16222;16230;16238;16246;16254;16303:3;16291:9;16282:7;16278:23;16274:33;16271:120;;;16310:79;;:::i;:::-;16271:120;16430:1;16455:53;16500:7;16491:6;16480:9;16476:22;16455:53;:::i;:::-;16445:63;;16401:117;16557:2;16583:53;16628:7;16619:6;16608:9;16604:22;16583:53;:::i;:::-;16573:63;;16528:118;16685:2;16711:53;16756:7;16747:6;16736:9;16732:22;16711:53;:::i;:::-;16701:63;;16656:118;16813:2;16839:53;16884:7;16875:6;16864:9;16860:22;16839:53;:::i;:::-;16829:63;;16784:118;16969:3;16958:9;16954:19;16941:33;17001:18;16993:6;16990:30;16987:117;;;17023:79;;:::i;:::-;16987:117;17128:62;17182:7;17173:6;17162:9;17158:22;17128:62;:::i;:::-;17118:72;;16912:288;17267:3;17256:9;17252:19;17239:33;17299:18;17291:6;17288:30;17285:117;;;17321:79;;:::i;:::-;17285:117;17426:62;17480:7;17471:6;17460:9;17456:22;17426:62;:::i;:::-;17416:72;;17210:288;16092:1413;;;;;;;;:::o;17511:116::-;17581:21;17596:5;17581:21;:::i;:::-;17574:5;17571:32;17561:60;;17617:1;17614;17607:12;17561:60;17511:116;:::o;17633:133::-;17676:5;17714:6;17701:20;17692:29;;17730:30;17754:5;17730:30;:::i;:::-;17633:133;;;;:::o;17772:468::-;17837:6;17845;17894:2;17882:9;17873:7;17869:23;17865:32;17862:119;;;17900:79;;:::i;:::-;17862:119;18020:1;18045:53;18090:7;18081:6;18070:9;18066:22;18045:53;:::i;:::-;18035:63;;17991:117;18147:2;18173:50;18215:7;18206:6;18195:9;18191:22;18173:50;:::i;:::-;18163:60;;18118:115;17772:468;;;;;:::o;18246:943::-;18341:6;18349;18357;18365;18414:3;18402:9;18393:7;18389:23;18385:33;18382:120;;;18421:79;;:::i;:::-;18382:120;18541:1;18566:53;18611:7;18602:6;18591:9;18587:22;18566:53;:::i;:::-;18556:63;;18512:117;18668:2;18694:53;18739:7;18730:6;18719:9;18715:22;18694:53;:::i;:::-;18684:63;;18639:118;18796:2;18822:53;18867:7;18858:6;18847:9;18843:22;18822:53;:::i;:::-;18812:63;;18767:118;18952:2;18941:9;18937:18;18924:32;18983:18;18975:6;18972:30;18969:117;;;19005:79;;:::i;:::-;18969:117;19110:62;19164:7;19155:6;19144:9;19140:22;19110:62;:::i;:::-;19100:72;;18895:287;18246:943;;;;;;;:::o;19195:109::-;19231:7;19271:26;19264:5;19260:38;19249:49;;19195:109;;;:::o;19310:120::-;19382:23;19399:5;19382:23;:::i;:::-;19375:5;19372:34;19362:62;;19420:1;19417;19410:12;19362:62;19310:120;:::o;19436:137::-;19481:5;19519:6;19506:20;19497:29;;19535:32;19561:5;19535:32;:::i;:::-;19436:137;;;;:::o;19579:327::-;19637:6;19686:2;19674:9;19665:7;19661:23;19657:32;19654:119;;;19692:79;;:::i;:::-;19654:119;19812:1;19837:52;19881:7;19872:6;19861:9;19857:22;19837:52;:::i;:::-;19827:62;;19783:116;19579:327;;;;:::o;19912:474::-;19980:6;19988;20037:2;20025:9;20016:7;20012:23;20008:32;20005:119;;;20043:79;;:::i;:::-;20005:119;20163:1;20188:53;20233:7;20224:6;20213:9;20209:22;20188:53;:::i;:::-;20178:63;;20134:117;20290:2;20316:53;20361:7;20352:6;20341:9;20337:22;20316:53;:::i;:::-;20306:63;;20261:118;19912:474;;;;;:::o;20392:332::-;20513:4;20551:2;20540:9;20536:18;20528:26;;20564:71;20632:1;20621:9;20617:17;20608:6;20564:71;:::i;:::-;20645:72;20713:2;20702:9;20698:18;20689:6;20645:72;:::i;:::-;20392:332;;;;;:::o;20730:180::-;20778:77;20775:1;20768:88;20875:4;20872:1;20865:15;20899:4;20896:1;20889:15;20916:320;20960:6;20997:1;20991:4;20987:12;20977:22;;21044:1;21038:4;21034:12;21065:18;21055:81;;21121:4;21113:6;21109:17;21099:27;;21055:81;21183:2;21175:6;21172:14;21152:18;21149:38;21146:84;;21202:18;;:::i;:::-;21146:84;20967:269;20916:320;;;:::o;21242:237::-;21382:34;21378:1;21370:6;21366:14;21359:58;21451:20;21446:2;21438:6;21434:15;21427:45;21242:237;:::o;21485:366::-;21627:3;21648:67;21712:2;21707:3;21648:67;:::i;:::-;21641:74;;21724:93;21813:3;21724:93;:::i;:::-;21842:2;21837:3;21833:12;21826:19;;21485:366;;;:::o;21857:419::-;22023:4;22061:2;22050:9;22046:18;22038:26;;22110:9;22104:4;22100:20;22096:1;22085:9;22081:17;22074:47;22138:131;22264:4;22138:131;:::i;:::-;22130:139;;21857:419;;;:::o;22282:442::-;22431:4;22469:2;22458:9;22454:18;22446:26;;22482:71;22550:1;22539:9;22535:17;22526:6;22482:71;:::i;:::-;22563:72;22631:2;22620:9;22616:18;22607:6;22563:72;:::i;:::-;22645;22713:2;22702:9;22698:18;22689:6;22645:72;:::i;:::-;22282:442;;;;;;:::o;22730:180::-;22778:77;22775:1;22768:88;22875:4;22872:1;22865:15;22899:4;22896:1;22889:15;22916:410;22956:7;22979:20;22997:1;22979:20;:::i;:::-;22974:25;;23013:20;23031:1;23013:20;:::i;:::-;23008:25;;23068:1;23065;23061:9;23090:30;23108:11;23090:30;:::i;:::-;23079:41;;23269:1;23260:7;23256:15;23253:1;23250:22;23230:1;23223:9;23203:83;23180:139;;23299:18;;:::i;:::-;23180:139;22964:362;22916:410;;;;:::o;23332:180::-;23380:77;23377:1;23370:88;23477:4;23474:1;23467:15;23501:4;23498:1;23491:15;23518:185;23558:1;23575:20;23593:1;23575:20;:::i;:::-;23570:25;;23609:20;23627:1;23609:20;:::i;:::-;23604:25;;23648:1;23638:35;;23653:18;;:::i;:::-;23638:35;23695:1;23692;23688:9;23683:14;;23518:185;;;;:::o;23709:171::-;23849:23;23845:1;23837:6;23833:14;23826:47;23709:171;:::o;23886:366::-;24028:3;24049:67;24113:2;24108:3;24049:67;:::i;:::-;24042:74;;24125:93;24214:3;24125:93;:::i;:::-;24243:2;24238:3;24234:12;24227:19;;23886:366;;;:::o;24258:419::-;24424:4;24462:2;24451:9;24447:18;24439:26;;24511:9;24505:4;24501:20;24497:1;24486:9;24482:17;24475:47;24539:131;24665:4;24539:131;:::i;:::-;24531:139;;24258:419;;;:::o;24683:180::-;24731:77;24728:1;24721:88;24828:4;24825:1;24818:15;24852:4;24849:1;24842:15;24869:233;24908:3;24931:24;24949:5;24931:24;:::i;:::-;24922:33;;24977:66;24970:5;24967:77;24964:103;;25047:18;;:::i;:::-;24964:103;25094:1;25087:5;25083:13;25076:20;;24869:233;;;:::o;25108:141::-;25157:4;25180:3;25172:11;;25203:3;25200:1;25193:14;25237:4;25234:1;25224:18;25216:26;;25108:141;;;:::o;25255:93::-;25292:6;25339:2;25334;25327:5;25323:14;25319:23;25309:33;;25255:93;;;:::o;25354:107::-;25398:8;25448:5;25442:4;25438:16;25417:37;;25354:107;;;;:::o;25467:393::-;25536:6;25586:1;25574:10;25570:18;25609:97;25639:66;25628:9;25609:97;:::i;:::-;25727:39;25757:8;25746:9;25727:39;:::i;:::-;25715:51;;25799:4;25795:9;25788:5;25784:21;25775:30;;25848:4;25838:8;25834:19;25827:5;25824:30;25814:40;;25543:317;;25467:393;;;;;:::o;25866:60::-;25894:3;25915:5;25908:12;;25866:60;;;:::o;25932:142::-;25982:9;26015:53;26033:34;26042:24;26060:5;26042:24;:::i;:::-;26033:34;:::i;:::-;26015:53;:::i;:::-;26002:66;;25932:142;;;:::o;26080:75::-;26123:3;26144:5;26137:12;;26080:75;;;:::o;26161:269::-;26271:39;26302:7;26271:39;:::i;:::-;26332:91;26381:41;26405:16;26381:41;:::i;:::-;26373:6;26366:4;26360:11;26332:91;:::i;:::-;26326:4;26319:105;26237:193;26161:269;;;:::o;26436:73::-;26481:3;26436:73;:::o;26515:189::-;26592:32;;:::i;:::-;26633:65;26691:6;26683;26677:4;26633:65;:::i;:::-;26568:136;26515:189;;:::o;26710:186::-;26770:120;26787:3;26780:5;26777:14;26770:120;;;26841:39;26878:1;26871:5;26841:39;:::i;:::-;26814:1;26807:5;26803:13;26794:22;;26770:120;;;26710:186;;:::o;26902:543::-;27003:2;26998:3;26995:11;26992:446;;;27037:38;27069:5;27037:38;:::i;:::-;27121:29;27139:10;27121:29;:::i;:::-;27111:8;27107:44;27304:2;27292:10;27289:18;27286:49;;;27325:8;27310:23;;27286:49;27348:80;27404:22;27422:3;27404:22;:::i;:::-;27394:8;27390:37;27377:11;27348:80;:::i;:::-;27007:431;;26992:446;26902:543;;;:::o;27451:117::-;27505:8;27555:5;27549:4;27545:16;27524:37;;27451:117;;;;:::o;27574:169::-;27618:6;27651:51;27699:1;27695:6;27687:5;27684:1;27680:13;27651:51;:::i;:::-;27647:56;27732:4;27726;27722:15;27712:25;;27625:118;27574:169;;;;:::o;27748:295::-;27824:4;27970:29;27995:3;27989:4;27970:29;:::i;:::-;27962:37;;28032:3;28029:1;28025:11;28019:4;28016:21;28008:29;;27748:295;;;;:::o;28048:1395::-;28165:37;28198:3;28165:37;:::i;:::-;28267:18;28259:6;28256:30;28253:56;;;28289:18;;:::i;:::-;28253:56;28333:38;28365:4;28359:11;28333:38;:::i;:::-;28418:67;28478:6;28470;28464:4;28418:67;:::i;:::-;28512:1;28536:4;28523:17;;28568:2;28560:6;28557:14;28585:1;28580:618;;;;29242:1;29259:6;29256:77;;;29308:9;29303:3;29299:19;29293:26;29284:35;;29256:77;29359:67;29419:6;29412:5;29359:67;:::i;:::-;29353:4;29346:81;29215:222;28550:887;;28580:618;28632:4;28628:9;28620:6;28616:22;28666:37;28698:4;28666:37;:::i;:::-;28725:1;28739:208;28753:7;28750:1;28747:14;28739:208;;;28832:9;28827:3;28823:19;28817:26;28809:6;28802:42;28883:1;28875:6;28871:14;28861:24;;28930:2;28919:9;28915:18;28902:31;;28776:4;28773:1;28769:12;28764:17;;28739:208;;;28975:6;28966:7;28963:19;28960:179;;;29033:9;29028:3;29024:19;29018:26;29076:48;29118:4;29110:6;29106:17;29095:9;29076:48;:::i;:::-;29068:6;29061:64;28983:156;28960:179;29185:1;29181;29173:6;29169:14;29165:22;29159:4;29152:36;28587:611;;;28550:887;;28140:1303;;;28048:1395;;:::o;29449:191::-;29489:3;29508:20;29526:1;29508:20;:::i;:::-;29503:25;;29542:20;29560:1;29542:20;:::i;:::-;29537:25;;29585:1;29582;29578:9;29571:16;;29606:3;29603:1;29600:10;29597:36;;;29613:18;;:::i;:::-;29597:36;29449:191;;;;:::o;29646:169::-;29786:21;29782:1;29774:6;29770:14;29763:45;29646:169;:::o;29821:366::-;29963:3;29984:67;30048:2;30043:3;29984:67;:::i;:::-;29977:74;;30060:93;30149:3;30060:93;:::i;:::-;30178:2;30173:3;30169:12;30162:19;;29821:366;;;:::o;30193:419::-;30359:4;30397:2;30386:9;30382:18;30374:26;;30446:9;30440:4;30436:20;30432:1;30421:9;30417:17;30410:47;30474:131;30600:4;30474:131;:::i;:::-;30466:139;;30193:419;;;:::o;30618:194::-;30658:4;30678:20;30696:1;30678:20;:::i;:::-;30673:25;;30712:20;30730:1;30712:20;:::i;:::-;30707:25;;30756:1;30753;30749:9;30741:17;;30780:1;30774:4;30771:11;30768:37;;;30785:18;;:::i;:::-;30768:37;30618:194;;;;:::o;30818:175::-;30958:27;30954:1;30946:6;30942:14;30935:51;30818:175;:::o;30999:366::-;31141:3;31162:67;31226:2;31221:3;31162:67;:::i;:::-;31155:74;;31238:93;31327:3;31238:93;:::i;:::-;31356:2;31351:3;31347:12;31340:19;;30999:366;;;:::o;31371:419::-;31537:4;31575:2;31564:9;31560:18;31552:26;;31624:9;31618:4;31614:20;31610:1;31599:9;31595:17;31588:47;31652:131;31778:4;31652:131;:::i;:::-;31644:139;;31371:419;;;:::o;31796:180::-;31936:32;31932:1;31924:6;31920:14;31913:56;31796:180;:::o;31982:366::-;32124:3;32145:67;32209:2;32204:3;32145:67;:::i;:::-;32138:74;;32221:93;32310:3;32221:93;:::i;:::-;32339:2;32334:3;32330:12;32323:19;;31982:366;;;:::o;32354:419::-;32520:4;32558:2;32547:9;32543:18;32535:26;;32607:9;32601:4;32597:20;32593:1;32582:9;32578:17;32571:47;32635:131;32761:4;32635:131;:::i;:::-;32627:139;;32354:419;;;:::o;32779:164::-;32919:16;32915:1;32907:6;32903:14;32896:40;32779:164;:::o;32949:366::-;33091:3;33112:67;33176:2;33171:3;33112:67;:::i;:::-;33105:74;;33188:93;33277:3;33188:93;:::i;:::-;33306:2;33301:3;33297:12;33290:19;;32949:366;;;:::o;33321:419::-;33487:4;33525:2;33514:9;33510:18;33502:26;;33574:9;33568:4;33564:20;33560:1;33549:9;33545:17;33538:47;33602:131;33728:4;33602:131;:::i;:::-;33594:139;;33321:419;;;:::o;33746:176::-;33886:28;33882:1;33874:6;33870:14;33863:52;33746:176;:::o;33928:366::-;34070:3;34091:67;34155:2;34150:3;34091:67;:::i;:::-;34084:74;;34167:93;34256:3;34167:93;:::i;:::-;34285:2;34280:3;34276:12;34269:19;;33928:366;;;:::o;34300:419::-;34466:4;34504:2;34493:9;34489:18;34481:26;;34553:9;34547:4;34543:20;34539:1;34528:9;34524:17;34517:47;34581:131;34707:4;34581:131;:::i;:::-;34573:139;;34300:419;;;:::o;34725:180::-;34865:32;34861:1;34853:6;34849:14;34842:56;34725:180;:::o;34911:366::-;35053:3;35074:67;35138:2;35133:3;35074:67;:::i;:::-;35067:74;;35150:93;35239:3;35150:93;:::i;:::-;35268:2;35263:3;35259:12;35252:19;;34911:366;;;:::o;35283:419::-;35449:4;35487:2;35476:9;35472:18;35464:26;;35536:9;35530:4;35526:20;35522:1;35511:9;35507:17;35500:47;35564:131;35690:4;35564:131;:::i;:::-;35556:139;;35283:419;;;:::o;35708:170::-;35848:22;35844:1;35836:6;35832:14;35825:46;35708:170;:::o;35884:366::-;36026:3;36047:67;36111:2;36106:3;36047:67;:::i;:::-;36040:74;;36123:93;36212:3;36123:93;:::i;:::-;36241:2;36236:3;36232:12;36225:19;;35884:366;;;:::o;36256:419::-;36422:4;36460:2;36449:9;36445:18;36437:26;;36509:9;36503:4;36499:20;36495:1;36484:9;36480:17;36473:47;36537:131;36663:4;36537:131;:::i;:::-;36529:139;;36256:419;;;:::o;36681:172::-;36821:24;36817:1;36809:6;36805:14;36798:48;36681:172;:::o;36859:366::-;37001:3;37022:67;37086:2;37081:3;37022:67;:::i;:::-;37015:74;;37098:93;37187:3;37098:93;:::i;:::-;37216:2;37211:3;37207:12;37200:19;;36859:366;;;:::o;37231:419::-;37397:4;37435:2;37424:9;37420:18;37412:26;;37484:9;37478:4;37474:20;37470:1;37459:9;37455:17;37448:47;37512:131;37638:4;37512:131;:::i;:::-;37504:139;;37231:419;;;:::o;37656:178::-;37796:30;37792:1;37784:6;37780:14;37773:54;37656:178;:::o;37840:366::-;37982:3;38003:67;38067:2;38062:3;38003:67;:::i;:::-;37996:74;;38079:93;38168:3;38079:93;:::i;:::-;38197:2;38192:3;38188:12;38181:19;;37840:366;;;:::o;38212:419::-;38378:4;38416:2;38405:9;38401:18;38393:26;;38465:9;38459:4;38455:20;38451:1;38440:9;38436:17;38429:47;38493:131;38619:4;38493:131;:::i;:::-;38485:139;;38212:419;;;:::o;38637:148::-;38739:11;38776:3;38761:18;;38637:148;;;;:::o;38791:390::-;38897:3;38925:39;38958:5;38925:39;:::i;:::-;38980:89;39062:6;39057:3;38980:89;:::i;:::-;38973:96;;39078:65;39136:6;39131:3;39124:4;39117:5;39113:16;39078:65;:::i;:::-;39168:6;39163:3;39159:16;39152:23;;38901:280;38791:390;;;;:::o;39211:874::-;39314:3;39351:5;39345:12;39380:36;39406:9;39380:36;:::i;:::-;39432:89;39514:6;39509:3;39432:89;:::i;:::-;39425:96;;39552:1;39541:9;39537:17;39568:1;39563:166;;;;39743:1;39738:341;;;;39530:549;;39563:166;39647:4;39643:9;39632;39628:25;39623:3;39616:38;39709:6;39702:14;39695:22;39687:6;39683:35;39678:3;39674:45;39667:52;;39563:166;;39738:341;39805:38;39837:5;39805:38;:::i;:::-;39865:1;39879:154;39893:6;39890:1;39887:13;39879:154;;;39967:7;39961:14;39957:1;39952:3;39948:11;39941:35;40017:1;40008:7;40004:15;39993:26;;39915:4;39912:1;39908:12;39903:17;;39879:154;;;40062:6;40057:3;40053:16;40046:23;;39745:334;;39530:549;;39318:767;;39211:874;;;;:::o;40091:589::-;40316:3;40338:95;40429:3;40420:6;40338:95;:::i;:::-;40331:102;;40450:95;40541:3;40532:6;40450:95;:::i;:::-;40443:102;;40562:92;40650:3;40641:6;40562:92;:::i;:::-;40555:99;;40671:3;40664:10;;40091:589;;;;;;:::o;40686:664::-;40891:4;40929:3;40918:9;40914:19;40906:27;;40943:71;41011:1;41000:9;40996:17;40987:6;40943:71;:::i;:::-;41024:72;41092:2;41081:9;41077:18;41068:6;41024:72;:::i;:::-;41106;41174:2;41163:9;41159:18;41150:6;41106:72;:::i;:::-;41188;41256:2;41245:9;41241:18;41232:6;41188:72;:::i;:::-;41270:73;41338:3;41327:9;41323:19;41314:6;41270:73;:::i;:::-;40686:664;;;;;;;;:::o;41356:214::-;41496:66;41492:1;41484:6;41480:14;41473:90;41356:214;:::o;41576:400::-;41736:3;41757:84;41839:1;41834:3;41757:84;:::i;:::-;41750:91;;41850:93;41939:3;41850:93;:::i;:::-;41968:1;41963:3;41959:11;41952:18;;41576:400;;;:::o;41982:79::-;42021:7;42050:5;42039:16;;41982:79;;;:::o;42067:157::-;42172:45;42192:24;42210:5;42192:24;:::i;:::-;42172:45;:::i;:::-;42167:3;42160:58;42067:157;;:::o;42230:663::-;42471:3;42493:148;42637:3;42493:148;:::i;:::-;42486:155;;42651:75;42722:3;42713:6;42651:75;:::i;:::-;42751:2;42746:3;42742:12;42735:19;;42764:75;42835:3;42826:6;42764:75;:::i;:::-;42864:2;42859:3;42855:12;42848:19;;42884:3;42877:10;;42230:663;;;;;:::o;42899:86::-;42934:7;42974:4;42967:5;42963:16;42952:27;;42899:86;;;:::o;42991:112::-;43074:22;43090:5;43074:22;:::i;:::-;43069:3;43062:35;42991:112;;:::o;43109:545::-;43282:4;43320:3;43309:9;43305:19;43297:27;;43334:71;43402:1;43391:9;43387:17;43378:6;43334:71;:::i;:::-;43415:68;43479:2;43468:9;43464:18;43455:6;43415:68;:::i;:::-;43493:72;43561:2;43550:9;43546:18;43537:6;43493:72;:::i;:::-;43575;43643:2;43632:9;43628:18;43619:6;43575:72;:::i;:::-;43109:545;;;;;;;:::o;43660:147::-;43761:11;43798:3;43783:18;;43660:147;;;;:::o;43813:114::-;;:::o;43933:398::-;44092:3;44113:83;44194:1;44189:3;44113:83;:::i;:::-;44106:90;;44205:93;44294:3;44205:93;:::i;:::-;44323:1;44318:3;44314:11;44307:18;;43933:398;;;:::o;44337:379::-;44521:3;44543:147;44686:3;44543:147;:::i;:::-;44536:154;;44707:3;44700:10;;44337:379;;;:::o;44722:98::-;44773:6;44807:5;44801:12;44791:22;;44722:98;;;:::o;44826:168::-;44909:11;44943:6;44938:3;44931:19;44983:4;44978:3;44974:14;44959:29;;44826:168;;;;:::o;45000:373::-;45086:3;45114:38;45146:5;45114:38;:::i;:::-;45168:70;45231:6;45226:3;45168:70;:::i;:::-;45161:77;;45247:65;45305:6;45300:3;45293:4;45286:5;45282:16;45247:65;:::i;:::-;45337:29;45359:6;45337:29;:::i;:::-;45332:3;45328:39;45321:46;;45090:283;45000:373;;;;:::o;45379:640::-;45574:4;45612:3;45601:9;45597:19;45589:27;;45626:71;45694:1;45683:9;45679:17;45670:6;45626:71;:::i;:::-;45707:72;45775:2;45764:9;45760:18;45751:6;45707:72;:::i;:::-;45789;45857:2;45846:9;45842:18;45833:6;45789:72;:::i;:::-;45908:9;45902:4;45898:20;45893:2;45882:9;45878:18;45871:48;45936:76;46007:4;45998:6;45936:76;:::i;:::-;45928:84;;45379:640;;;;;;;:::o;46025:141::-;46081:5;46112:6;46106:13;46097:22;;46128:32;46154:5;46128:32;:::i;:::-;46025:141;;;;:::o;46172:349::-;46241:6;46290:2;46278:9;46269:7;46265:23;46261:32;46258:119;;;46296:79;;:::i;:::-;46258:119;46416:1;46441:63;46496:7;46487:6;46476:9;46472:22;46441:63;:::i;:::-;46431:73;;46387:127;46172:349;;;;:::o;46527:140::-;46576:9;46609:52;46627:33;46636:23;46653:5;46636:23;:::i;:::-;46627:33;:::i;:::-;46609:52;:::i;:::-;46596:65;;46527:140;;;:::o;46673:129::-;46759:36;46789:5;46759:36;:::i;:::-;46754:3;46747:49;46673:129;;:::o;46808:330::-;46928:4;46966:2;46955:9;46951:18;46943:26;;46979:70;47046:1;47035:9;47031:17;47022:6;46979:70;:::i;:::-;47059:72;47127:2;47116:9;47112:18;47103:6;47059:72;:::i;:::-;46808:330;;;;;:::o;47144:180::-;47192:77;47189:1;47182:88;47289:4;47286:1;47279:15;47313:4;47310:1;47303:15

Swarm Source

ipfs://436cef156d0e0dce4745a9f99575daf855f092add0339ccdb7dd6bbcd5a41cf8
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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