POL Price: $0.701751 (-1.93%)
 

Overview

TokenID

4

Total Transfers

-

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
This contract may be a proxy contract. Click on More Options and select Is this a proxy? to confirm and enable the "Read as Proxy" & "Write as Proxy" tabs.

Contract Source Code Verified (Exact Match)

Contract Name:
CredlyKz

Compiler Version
v0.8.18+commit.87f61d96

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at polygonscan.com on 2023-06-12
*/

// SPDX-License-Identifier: MIT
// File: @openzeppelin/contracts/utils/Counters.sol


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

pragma solidity ^0.8.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}

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


// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

/**
 * @dev Standard math utilities missing in the Solidity language.
 */
library Math {
    enum Rounding {
        Down, // Toward negative infinity
        Up, // Toward infinity
        Zero // Toward zero
    }

    /**
     * @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 up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (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; // Least significant 256 bits of the product
            uint256 prod1; // Most significant 256 bits of the product
            assembly {
                let mm := mulmod(x, y, not(0))
                prod0 := mul(x, y)
                prod1 := sub(sub(mm, prod0), lt(mm, prod0))
            }

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                return prod0 / denominator;
            }

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1);

            ///////////////////////////////////////////////
            // 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.

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            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 (rounding == Rounding.Up && 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 down.
     *
     * 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 + (rounding == Rounding.Up && result * result < a ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 2, rounded down, of a positive value.
     * 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 + (rounding == Rounding.Up && 1 << result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 10, rounded down, of a positive value.
     * 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 + (rounding == Rounding.Up && 10**result < value ? 1 : 0);
        }
    }

    /**
     * @dev Return the log in base 256, rounded down, of a positive value.
     * 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 10, 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 + (rounding == Rounding.Up && 1 << (result * 8) < value ? 1 : 0);
        }
    }
}

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


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

pragma solidity ^0.8.0;


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

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        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), _SYMBOLS))
                }
                value /= 10;
                if (value == 0) break;
            }
            return buffer;
        }
    }

    /**
     * @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) {
        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] = _SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

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

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


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

pragma solidity ^0.8.0;

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

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

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


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

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev Tool to verify that a low level call to smart-contract was successful, and revert (either by bubbling
     * the revert reason or using the provided one) in case of unsuccessful call or if target was not a contract.
     *
     * _Available since v4.8._
     */
    function verifyCallResultFromTarget(
        address target,
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        if (success) {
            if (returndata.length == 0) {
                // only check isContract if the call was successful and the return data is empty
                // otherwise we already know that it was a contract
                require(isContract(target), "Address: call to non-contract");
            }
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    /**
     * @dev Tool to verify that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason or using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            _revert(returndata, errorMessage);
        }
    }

    function _revert(bytes memory returndata, string memory errorMessage) 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(errorMessage);
        }
    }
}

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


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

pragma solidity ^0.8.0;

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

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


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

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC165 standard, as defined in the
 * https://eips.ethereum.org/EIPS/eip-165[EIP].
 *
 * Implementers can declare support of contract interfaces, which can then be
 * queried by others ({ERC165Checker}).
 *
 * For an implementation, see {ERC165}.
 */
interface IERC165 {
    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified[EIP section]
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);
}

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


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

pragma solidity ^0.8.0;


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

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


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

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: 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 caller.
     *
     * Emits an {ApprovalForAll} event.
     */
    function setApprovalForAll(address operator, bool _approved) external;

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

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

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


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

pragma solidity ^0.8.0;


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

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

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

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


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

pragma solidity ^0.8.0;


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

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

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

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


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

pragma solidity ^0.8.0;








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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _ownerOf(tokenId);
        require(owner != address(0), "ERC721: invalid token ID");
        return owner;
    }

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

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

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

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

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

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

    /**
     * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist
     */
    function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
        return _owners[tokenId];
    }

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

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

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

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

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

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

        // Check that tokenId was not minted by `_beforeTokenTransfer` hook
        require(!_exists(tokenId), "ERC721: token already minted");

        unchecked {
            // Will not overflow unless all 2**256 token ids are minted to the same owner.
            // Given that tokens are minted one by one, it is impossible in practice that
            // this ever happens. Might change if we allow batch minting.
            // The ERC fails to describe this case.
            _balances[to] += 1;
        }

        _owners[tokenId] = to;

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

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

    /**
     * @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 virtual {
        address owner = ERC721.ownerOf(tokenId);

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

        // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook
        owner = ERC721.ownerOf(tokenId);

        // Clear approvals
        delete _tokenApprovals[tokenId];

        unchecked {
            // Cannot overflow, as that would require more tokens to be burned/transferred
            // out than the owner initially received through minting and transferring in.
            _balances[owner] -= 1;
        }
        delete _owners[tokenId];

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

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

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

        _beforeTokenTransfer(from, to, tokenId, 1);

        // Check that tokenId was not transferred by `_beforeTokenTransfer` hook
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");

        // Clear approvals from the previous owner
        delete _tokenApprovals[tokenId];

        unchecked {
            // `_balances[from]` cannot overflow for the same reason as described in `_burn`:
            // `from`'s balance is the number of token held, which is at least one before the current
            // transfer.
            // `_balances[to]` could overflow in the conditions described in `_mint`. That would require
            // all 2**256 token ids to be minted, which in practice is impossible.
            _balances[from] -= 1;
            _balances[to] += 1;
        }
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId, 1);
    }

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

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

    /**
     * @dev Reverts if the `tokenId` has not been minted yet.
     */
    function _requireMinted(uint256 tokenId) internal view virtual {
        require(_exists(tokenId), "ERC721: invalid token ID");
    }

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

    /**
     * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.
     * - When `from` is zero, the tokens will be minted for `to`.
     * - When `to` is zero, ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual {}

    /**
     * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.
     * - When `from` is zero, the tokens were minted for `to`.
     * - When `to` is zero, ``from``'s tokens were burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual {}

    /**
     * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override.
     *
     * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant
     * being 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`.
     */
    // solhint-disable-next-line func-name-mixedcase
    function __unsafe_increaseBalance(address account, uint256 amount) internal {
        _balances[account] += amount;
    }
}

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


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

pragma solidity ^0.8.0;


/**
 * @dev ERC721 token with storage based token URI management.
 */
abstract contract ERC721URIStorage is ERC721 {
    using Strings for uint256;

    // Optional mapping for token URIs
    mapping(uint256 => string) private _tokenURIs;

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

        string memory _tokenURI = _tokenURIs[tokenId];
        string memory base = _baseURI();

        // If there is no base URI, return the token URI.
        if (bytes(base).length == 0) {
            return _tokenURI;
        }
        // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
        if (bytes(_tokenURI).length > 0) {
            return string(abi.encodePacked(base, _tokenURI));
        }

        return super.tokenURI(tokenId);
    }

    /**
     * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
        require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
        _tokenURIs[tokenId] = _tokenURI;
    }

    /**
     * @dev See {ERC721-_burn}. This override additionally checks to see if a
     * token-specific URI was set for the token, and if so, it deletes the token URI from
     * the storage mapping.
     */
    function _burn(uint256 tokenId) internal virtual override {
        super._burn(tokenId);

        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }
    }
}

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


// OpenZeppelin Contracts (last updated v4.8.0) (token/ERC721/extensions/ERC721Enumerable.sol)

pragma solidity ^0.8.0;



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

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

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

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

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

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

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

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

    /**
     * @dev See {ERC721-_beforeTokenTransfer}.
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 firstTokenId,
        uint256 batchSize
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, firstTokenId, batchSize);

        if (batchSize > 1) {
            // Will only trigger during construction. Batch transferring (minting) is not available afterwards.
            revert("ERC721Enumerable: consecutive transfers not supported");
        }

        uint256 tokenId = firstTokenId;

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: Credlykz-simple.sol


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

pragma solidity ^0.8.0;






contract CredlyKz is ERC721, ERC721Enumerable, ERC721URIStorage, Ownable {
    using Counters for Counters.Counter;

    Counters.Counter private _tokenIdCounter;

    // Возможности майнинга NFT
    mapping(address => bool) private _userCanMintNft;
    mapping(address => uint256) private _userNftCount;
    mapping(address => uint256) private _userCurrentNftCountInSubscription;
    mapping(address => uint256) private _userMaxNftCountInSubscription;
    mapping(address => uint256) private _userMintExpirationDate; //Дата в Unix Timestamp до истечения которой возможен майнинг

    // Список авторизованных пользователей
    mapping(address => bool) private _authorizedUsers; //Пользователям которым доступны функции администрирования
    mapping(address => bool) private _authorizedProUsers; //Пользователям которым доступны технические, критически важные функции

    //--------------------------Конструктор-------------------------------------

    constructor() ERC721("CredlyKz", "CKZ") {}

    //--------------------------Данные пользователя-------------------------------------

    function getSender() public view returns (address) {
        return msg.sender;
    }

    function getMyUserData()
        public
        view
        returns (
            address userAdress,
            bool userCanMintNft,
            uint256 userNftCount,
            uint256 userCurrentNftCountInSubscription,
            uint256 userMaxNftCountInSubscription,
            uint256 userMintExpirationDate,
            bool authorizedUser,
            bool authorizedProUser
        )
    {
        userAdress = msg.sender;
        userCanMintNft = _userCanMintNft[msg.sender];
        userNftCount = _userNftCount[msg.sender];
        userCurrentNftCountInSubscription = _userCurrentNftCountInSubscription[
            msg.sender
        ];
        userMaxNftCountInSubscription = _userMaxNftCountInSubscription[
            msg.sender
        ];
        userMintExpirationDate = _userMintExpirationDate[msg.sender];
        authorizedUser = _authorizedUsers[msg.sender];
        authorizedProUser = _authorizedProUsers[msg.sender];
    }

    function getUserData(address userAddress)
        public
        view
        onlyAuthorized
        returns (
            address userAdr,
            bool userCanMintNft,
            uint256 userNftCount,
            uint256 userCurrentNftCountInSubscription,
            uint256 userMaxNftCountInSubscription,
            uint256 userMintExpirationDate,
            bool authorizedUser,
            bool authorizedProUser
        )
    {
        userAdr = userAddress;
        userCanMintNft = _userCanMintNft[userAddress];
        userNftCount = _userNftCount[userAddress];
        userCurrentNftCountInSubscription = _userCurrentNftCountInSubscription[
            userAddress
        ];
        userMaxNftCountInSubscription = _userMaxNftCountInSubscription[
            userAddress
        ];
        userMintExpirationDate = _userMintExpirationDate[userAddress];
        authorizedUser = _authorizedUsers[userAddress];
        authorizedProUser = _authorizedProUsers[userAddress];
    }

    //--------------------------Майнинг-------------------------------------

    function safeMint(string memory uri) public returns (uint256) {
        require(
            _userCanMintNft[msg.sender],
            "Minting NFT is not allowed for this user"
        );

        require(
            _userCurrentNftCountInSubscription[_msgSender()] <
                _userMaxNftCountInSubscription[_msgSender()],
            "User has reached max NFT limit"
        );

        require(
            block.timestamp <= _userMintExpirationDate[_msgSender()],
            "User's minting permission has expired"
        );

        uint256 tokenId = _tokenIdCounter.current();

        // Повторяем процесс, пока не найдем свободный ID токена
        while (_exists(tokenId)) {
            _tokenIdCounter.increment();
            tokenId = _tokenIdCounter.current();
        }

        _tokenIdCounter.increment();
        _safeMint(_msgSender(), tokenId);
        _setTokenURI(tokenId, uri);
        _userCurrentNftCountInSubscription[_msgSender()]++;
        _userNftCount[_msgSender()]++;

        return tokenId;
    }

    function safeMintMultiple(string[] memory uris)
        public
        returns (uint256[] memory)
    {
        require(
            _userCanMintNft[msg.sender],
            "Minting NFT is not allowed for this user"
        );

        require(
            _userCurrentNftCountInSubscription[_msgSender()] + uris.length <=
                _userMaxNftCountInSubscription[_msgSender()],
            "User has reached max NFT limit"
        );

        require(
            block.timestamp <= _userMintExpirationDate[_msgSender()],
            "User's minting permission has expired"
        );

        uint256[] memory tokenIds = new uint256[](uris.length);

        for (uint256 i = 0; i < uris.length; i++) {
            uint256 tokenId = _tokenIdCounter.current();
            while (_exists(tokenId)) {
                _tokenIdCounter.increment();
                tokenId = _tokenIdCounter.current();
            }
            _tokenIdCounter.increment();
            _safeMint(_msgSender(), tokenId);
            _setTokenURI(tokenId, uris[i]);
            _userCurrentNftCountInSubscription[_msgSender()]++;
            _userNftCount[_msgSender()]++;

            tokenIds[i] = tokenId;
        }

        return tokenIds;
    }

    //--------------------------Майнинг------------_userCanMintNft

    // Функция для установки разрешения на майнинг NFT для пользователя
    function setUserCanMintNft(address userAddress, bool canMint)
        public
        onlyAuthorized
    {
        _userCanMintNft[userAddress] = canMint;
    }

    // Функция для добавления пользователя в список допущенных к майнингу NFT
    function addUserToCanMintNft(address userAddress) public onlyAuthorized {
        _userCanMintNft[userAddress] = true;
    }

    // Функция для удаления пользователя из списка допущенных к майнингу NFT
    function removeUserFromCanMintNft(address userAddress)
        public
        onlyAuthorized
    {
        _userCanMintNft[userAddress] = false;
    }

    //--------------------------Майнинг------------_userNftCount

    function setUserNftCount(address userAddress, uint256 count)
        public
        onlyOwner
    {
        _userNftCount[userAddress] = count;
    }

    //--------------------------Майнинг------------_userMaxNftCountInSubscription

    function setUserCurrentNftCountInSubscription(
        address userAddress,
        uint256 maxCount
    ) public onlyAuthorized {
        _userCurrentNftCountInSubscription[userAddress] = maxCount;
    }

    // Установка максимального количества нфт, которое может выпустатить пользователь
    function setUserMaxNftCountInSubscription(
        address userAddress,
        uint256 maxCount
    ) public onlyAuthorized {
        _userMaxNftCountInSubscription[userAddress] = maxCount;
    }

    //--------------------------Майнинг------------_userMintExpirationDate

    //Установка даты истечения возможности майнинга в секундах, в формате Unix Timestamp
    function setUserMintExpirationDate(
        address userAddress,
        uint256 expirationDate
    ) public onlyAuthorized {
        _userMintExpirationDate[userAddress] = expirationDate;
    }

    //Расчёт даты начиная с текущего момента, к которой прибавляется указанное количество дней, результат в Unix Timestamp
    function addDaysToToday(uint256 daysCount)
        public
        view
        onlyAuthorized
        returns (uint256)
    {
        uint256 secondsPerDay = 24 * 60 * 60;
        uint256 newTimestamp = block.timestamp + (daysCount * secondsPerDay);
        return newTimestamp;
    }

    //--------------------------Подписки-------------------------------------
    //Обновление или добавление подписки
    function renewSubscription(
        address userAddress,
        bool canMint,
        uint256 maxNftCount,
        uint256 daysToAdd
    ) public onlyAuthorized {
        _userCurrentNftCountInSubscription[userAddress] = 0;
        _userMaxNftCountInSubscription[userAddress] = maxNftCount;
        _userMintExpirationDate[userAddress] = addDaysToToday(daysToAdd);
        _userCanMintNft[userAddress] = canMint;
    }

    //Продление подписки на определнное количество дней
    function addDaysToSubscription(address userAddress, uint256 daysToAdd)
        public
        onlyAuthorized
    {
        _userMintExpirationDate[userAddress] = addDaysToToday(daysToAdd);
    }

    //Увеличение максимального количества нфт в подписке на указанное значение
    function addMaxNftToSubscription(address userAddress, uint256 nftCountToAdd)
        public
        onlyAuthorized
    {
        _userMaxNftCountInSubscription[userAddress] += nftCountToAdd;
    }

    //--------------------------Количество токенов-------------------------------------

    function incrementTokenCount() public onlyOwner {
        _tokenIdCounter.increment();
    }

    function decrementTokenCount() public onlyOwner {
        _tokenIdCounter.decrement();
    }

    function getCurrentTokenId() public view returns (uint256) {
        return _tokenIdCounter.current();
    }

    //--------------------------Авторизация-------------------------------------

    modifier onlyAuthorized() {
        require(
            owner() == msg.sender || _authorizedUsers[msg.sender],
            "Caller is not authorized"
        );
        _;
    }

    // Функция для добавления авторизованного пользователя
    function addAuthorizedUser(address user) public onlyOwner {
        _authorizedUsers[user] = true;
    }

    // Функция для удаления авторизованного пользователя
    function removeAuthorizedUser(address user) public onlyOwner {
        _authorizedUsers[user] = false;
    }

    //--------------------------Авторизация профессиональных пользователей-------------------------------

    modifier onlyAuthorizedPro() {
        require(
            owner() == msg.sender || _authorizedProUsers[msg.sender],
            "Caller is not pro authorized"
        );
        _;
    }

    // Функция для добавления про авторизованного пользователя
    function addAuthorizedProUser(address user) public onlyOwner {
        _authorizedProUsers[user] = true;
    }

    // Функция для удаления про авторизованного пользователя
    function removeAuthorizedProUser(address user) public onlyOwner {
        _authorizedProUsers[user] = false;
    }

    //--------------------------URI-------------------------------------
    //Изменение URI указанного токена
    function changeTokenURI(uint256 tokenId, string memory newURI)
        public
        onlyAuthorizedPro
    {
        _setTokenURI(tokenId, newURI);
    }

    //Получение URI указанного токена
    function tokenURI(uint256 tokenId)
        public
        view
        override(ERC721, ERC721URIStorage)
        returns (string memory)
    {
        return super.tokenURI(tokenId);
    }

    //--------------------------Burn-------------------------------------

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

    //--------------------------Переопределения--------------------------

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

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

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","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":[{"internalType":"address","name":"user","type":"address"}],"name":"addAuthorizedProUser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"addAuthorizedUser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"daysToAdd","type":"uint256"}],"name":"addDaysToSubscription","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"daysCount","type":"uint256"}],"name":"addDaysToToday","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"nftCountToAdd","type":"uint256"}],"name":"addMaxNftToSubscription","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"addUserToCanMintNft","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":[{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"string","name":"newURI","type":"string"}],"name":"changeTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"decrementTokenCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getMyUserData","outputs":[{"internalType":"address","name":"userAdress","type":"address"},{"internalType":"bool","name":"userCanMintNft","type":"bool"},{"internalType":"uint256","name":"userNftCount","type":"uint256"},{"internalType":"uint256","name":"userCurrentNftCountInSubscription","type":"uint256"},{"internalType":"uint256","name":"userMaxNftCountInSubscription","type":"uint256"},{"internalType":"uint256","name":"userMintExpirationDate","type":"uint256"},{"internalType":"bool","name":"authorizedUser","type":"bool"},{"internalType":"bool","name":"authorizedProUser","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getSender","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"getUserData","outputs":[{"internalType":"address","name":"userAdr","type":"address"},{"internalType":"bool","name":"userCanMintNft","type":"bool"},{"internalType":"uint256","name":"userNftCount","type":"uint256"},{"internalType":"uint256","name":"userCurrentNftCountInSubscription","type":"uint256"},{"internalType":"uint256","name":"userMaxNftCountInSubscription","type":"uint256"},{"internalType":"uint256","name":"userMintExpirationDate","type":"uint256"},{"internalType":"bool","name":"authorizedUser","type":"bool"},{"internalType":"bool","name":"authorizedProUser","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"incrementTokenCount","outputs":[],"stateMutability":"nonpayable","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":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"removeAuthorizedProUser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"removeAuthorizedUser","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"}],"name":"removeUserFromCanMintNft","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"bool","name":"canMint","type":"bool"},{"internalType":"uint256","name":"maxNftCount","type":"uint256"},{"internalType":"uint256","name":"daysToAdd","type":"uint256"}],"name":"renewSubscription","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"uri","type":"string"}],"name":"safeMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string[]","name":"uris","type":"string[]"}],"name":"safeMintMultiple","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"bool","name":"canMint","type":"bool"}],"name":"setUserCanMintNft","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"maxCount","type":"uint256"}],"name":"setUserCurrentNftCountInSubscription","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"maxCount","type":"uint256"}],"name":"setUserMaxNftCountInSubscription","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"expirationDate","type":"uint256"}],"name":"setUserMintExpirationDate","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"uint256","name":"count","type":"uint256"}],"name":"setUserNftCount","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040523480156200001157600080fd5b506040518060400160405280600881526020017f437265646c794b7a0000000000000000000000000000000000000000000000008152506040518060400160405280600381526020017f434b5a000000000000000000000000000000000000000000000000000000000081525081600090816200008f919062000412565b508060019081620000a1919062000412565b505050620000c4620000b8620000ca60201b60201c565b620000d260201b60201c565b620004f9565b600033905090565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200021a57607f821691505b60208210810362000230576200022f620001d2565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026200029a7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200025b565b620002a686836200025b565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620002f3620002ed620002e784620002be565b620002c8565b620002be565b9050919050565b6000819050919050565b6200030f83620002d2565b620003276200031e82620002fa565b84845462000268565b825550505050565b600090565b6200033e6200032f565b6200034b81848462000304565b505050565b5b8181101562000373576200036760008262000334565b60018101905062000351565b5050565b601f821115620003c2576200038c8162000236565b62000397846200024b565b81016020851015620003a7578190505b620003bf620003b6856200024b565b83018262000350565b50505b505050565b600082821c905092915050565b6000620003e760001984600802620003c7565b1980831691505092915050565b6000620004028383620003d4565b9150826002028217905092915050565b6200041d8262000198565b67ffffffffffffffff811115620004395762000438620001a3565b5b62000445825462000201565b6200045282828562000377565b600060209050601f8311600181146200048a576000841562000475578287015190505b620004818582620003f4565b865550620004f1565b601f1984166200049a8662000236565b60005b82811015620004c4578489015182556001820191506020850194506020810190506200049d565b86831015620004e45784890151620004e0601f891682620003d4565b8355505b6001600288020188555050505b505050505050565b615cba80620005096000396000f3fe608060405234801561001057600080fd5b50600436106102695760003560e01c8063715018a611610151578063b6f4b345116100c3578063c87b56dd11610087578063c87b56dd1461070b578063e985e9c51461073b578063edea4ed71461076b578063f25b62091461079b578063f2fde38b146107a5578063ffc9896b146107c157610269565b8063b6f4b3451461067f578063b88d4fde1461069b578063ba3adc3f146106b7578063c2919947146106d3578063c70c7c67146106ef57610269565b806392146b8b1161011557806392146b8b146105cc57806395d89b41146105f1578063991f453e1461060f5780639fece0981461062b578063a22cb46514610647578063b366a1f01461066357610269565b8063715018a6146105505780637fb3a9a21461055a5780638483c4ad1461057657806389fabc80146105925780638da5cb5b146105ae57610269565b806323b872dd116101ea57806356189236116101ae57806356189236146104685780635ab29cf7146104865780635e01eb5a146104a25780636352211e146104c0578063695850fb146104f057806370a082311461052057610269565b806323b872dd146103c6578063262ec85d146103e25780632f745c59146103ec57806342842e0e1461041c5780634f6ccce71461043857610269565b80631126fe77116102315780631126fe771461032457806315f77edc14610340578063177d2a741461037057806318160ddd1461038c57806320c50c34146103aa57610269565b806301ffc9a71461026e57806306d6dfc81461029e57806306fdde03146102ba578063081812fc146102d8578063095ea7b314610308575b600080fd5b61028860048036038101906102839190614165565b6107f8565b60405161029591906141ad565b60405180910390f35b6102b860048036038101906102b39190614226565b61080a565b005b6102c261092e565b6040516102cf91906142e3565b60405180910390f35b6102f260048036038101906102ed919061433b565b6109c0565b6040516102ff9190614377565b60405180910390f35b610322600480360381019061031d9190614392565b610a06565b005b61033e600480360381019061033991906143fe565b610b1d565b005b61035a60048036038101906103559190614680565b610d18565b6040516103679190614787565b60405180910390f35b61038a60048036038101906103859190614226565b6110d1565b005b610394611134565b6040516103a191906147b8565b60405180910390f35b6103c460048036038101906103bf9190614392565b611141565b005b6103e060048036038101906103db91906147d3565b611264565b005b6103ea6112c4565b005b61040660048036038101906104019190614392565b6112d8565b60405161041391906147b8565b60405180910390f35b610436600480360381019061043191906147d3565b61137d565b005b610452600480360381019061044d919061433b565b61139d565b60405161045f91906147b8565b60405180910390f35b61047061140e565b60405161047d91906147b8565b60405180910390f35b6104a0600480360381019061049b9190614392565b61141f565b005b6104aa611530565b6040516104b79190614377565b60405180910390f35b6104da60048036038101906104d5919061433b565b611538565b6040516104e79190614377565b60405180910390f35b61050a60048036038101906105059190614826565b6115be565b60405161051791906147b8565b60405180910390f35b61053a60048036038101906105359190614226565b6118c1565b60405161054791906147b8565b60405180910390f35b610558611978565b005b610574600480360381019061056f919061486f565b61198c565b005b610590600480360381019061058b9190614392565b611a63565b005b6105ac60048036038101906105a79190614226565b611b7c565b005b6105b6611bdf565b6040516105c39190614377565b60405180910390f35b6105d4611c09565b6040516105e89897969594939291906148cb565b60405180910390f35b6105f9611e17565b60405161060691906142e3565b60405180910390f35b61062960048036038101906106249190614392565b611ea9565b005b61064560048036038101906106409190614226565b611fba565b005b610661600480360381019061065c9190614949565b61201d565b005b61067d60048036038101906106789190614392565b612033565b005b61069960048036038101906106949190614949565b612083565b005b6106b560048036038101906106b09190614a2a565b6121a7565b005b6106d160048036038101906106cc9190614226565b612209565b005b6106ed60048036038101906106e89190614392565b61232d565b005b61070960048036038101906107049190614226565b61243e565b005b6107256004803603810190610720919061433b565b6124a1565b60405161073291906142e3565b60405180910390f35b61075560048036038101906107509190614aad565b6124b3565b60405161076291906141ad565b60405180910390f35b6107856004803603810190610780919061433b565b612547565b60405161079291906147b8565b60405180910390f35b6107a361263f565b005b6107bf60048036038101906107ba9190614226565b612653565b005b6107db60048036038101906107d69190614226565b6126d6565b6040516107ef9897969594939291906148cb565b60405180910390f35b6000610803826129ae565b9050919050565b3373ffffffffffffffffffffffffffffffffffffffff16610829611bdf565b73ffffffffffffffffffffffffffffffffffffffff1614806108945750601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b6108d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614b39565b60405180910390fd5b6000600d60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60606000805461093d90614b88565b80601f016020809104026020016040519081016040528092919081815260200182805461096990614b88565b80156109b65780601f1061098b576101008083540402835291602001916109b6565b820191906000526020600020905b81548152906001019060200180831161099957829003601f168201915b5050505050905090565b60006109cb82612a28565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610a1182611538565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610a81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7890614c2b565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610aa0612a73565b73ffffffffffffffffffffffffffffffffffffffff161480610acf5750610ace81610ac9612a73565b6124b3565b5b610b0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0590614cbd565b60405180910390fd5b610b188383612a7b565b505050565b3373ffffffffffffffffffffffffffffffffffffffff16610b3c611bdf565b73ffffffffffffffffffffffffffffffffffffffff161480610ba75750601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b610be6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bdd90614b39565b60405180910390fd5b6000600f60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081601060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610c7881612547565b601160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555082600d60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050505050565b6060600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610da6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d9d90614d4f565b60405180910390fd5b60106000610db2612a73565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548251600f6000610dfb612a73565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e409190614d9e565b1115610e81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e7890614e1e565b60405180910390fd5b60116000610e8d612a73565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054421115610f0a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f0190614eb0565b60405180910390fd5b6000825167ffffffffffffffff811115610f2757610f2661446a565b5b604051908082528060200260200182016040528015610f555781602001602082028036833780820191505090505b50905060005b83518110156110c7576000610f70600c612b34565b90505b610f7c81612b42565b15610f9c57610f8b600c612b83565b610f95600c612b34565b9050610f73565b610fa6600c612b83565b610fb7610fb1612a73565b82612b99565b610fdb81868481518110610fce57610fcd614ed0565b5b6020026020010151612bb7565b600f6000610fe7612a73565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081548092919061103290614eff565b9190505550600e6000611043612a73565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081548092919061108e90614eff565b9190505550808383815181106110a7576110a6614ed0565b5b6020026020010181815250505080806110bf90614eff565b915050610f5b565b5080915050919050565b6110d9612c24565b6001601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b6000600880549050905090565b3373ffffffffffffffffffffffffffffffffffffffff16611160611bdf565b73ffffffffffffffffffffffffffffffffffffffff1614806111cb5750601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b61120a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120190614b39565b60405180910390fd5b80601060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546112599190614d9e565b925050819055505050565b61127561126f612a73565b82612ca2565b6112b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ab90614fb9565b60405180910390fd5b6112bf838383612d37565b505050565b6112cc612c24565b6112d6600c612b83565b565b60006112e3836118c1565b8210611324576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161131b9061504b565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b611398838383604051806020016040528060008152506121a7565b505050565b60006113a7611134565b82106113e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113df906150dd565b60405180910390fd5b600882815481106113fc576113fb614ed0565b5b90600052602060002001549050919050565b600061141a600c612b34565b905090565b3373ffffffffffffffffffffffffffffffffffffffff1661143e611bdf565b73ffffffffffffffffffffffffffffffffffffffff1614806114a95750601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b6114e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114df90614b39565b60405180910390fd5b80600f60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505050565b600033905090565b60008061154483613030565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036115b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115ac90615149565b60405180910390fd5b80915050919050565b6000600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661164c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161164390614d4f565b60405180910390fd5b60106000611658612a73565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600f600061169f612a73565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541061171a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161171190614e1e565b60405180910390fd5b60116000611726612a73565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020544211156117a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161179a90614eb0565b60405180910390fd5b60006117af600c612b34565b90505b6117bb81612b42565b156117db576117ca600c612b83565b6117d4600c612b34565b90506117b2565b6117e5600c612b83565b6117f66117f0612a73565b82612b99565b6118008184612bb7565b600f600061180c612a73565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081548092919061185790614eff565b9190505550600e6000611868612a73565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154809291906118b390614eff565b919050555080915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611931576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611928906151db565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611980612c24565b61198a600061306d565b565b3373ffffffffffffffffffffffffffffffffffffffff166119ab611bdf565b73ffffffffffffffffffffffffffffffffffffffff161480611a165750601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b611a55576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a4c90615247565b60405180910390fd5b611a5f8282612bb7565b5050565b3373ffffffffffffffffffffffffffffffffffffffff16611a82611bdf565b73ffffffffffffffffffffffffffffffffffffffff161480611aed5750601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b611b2c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b2390614b39565b60405180910390fd5b611b3581612547565b601160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505050565b611b84612c24565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600080600080600080600080339750600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169650600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549550600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549450601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549350601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549250601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169150601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1690509091929394959697565b606060018054611e2690614b88565b80601f0160208091040260200160405190810160405280929190818152602001828054611e5290614b88565b8015611e9f5780601f10611e7457610100808354040283529160200191611e9f565b820191906000526020600020905b815481529060010190602001808311611e8257829003601f168201915b5050505050905090565b3373ffffffffffffffffffffffffffffffffffffffff16611ec8611bdf565b73ffffffffffffffffffffffffffffffffffffffff161480611f335750601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b611f72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6990614b39565b60405180910390fd5b80601060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505050565b611fc2612c24565b6001601360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b61202f612028612a73565b8383613133565b5050565b61203b612c24565b80600e60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505050565b3373ffffffffffffffffffffffffffffffffffffffff166120a2611bdf565b73ffffffffffffffffffffffffffffffffffffffff16148061210d5750601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b61214c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161214390614b39565b60405180910390fd5b80600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b6121b86121b2612a73565b83612ca2565b6121f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121ee90614fb9565b60405180910390fd5b6122038484848461329f565b50505050565b3373ffffffffffffffffffffffffffffffffffffffff16612228611bdf565b73ffffffffffffffffffffffffffffffffffffffff1614806122935750601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b6122d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c990614b39565b60405180910390fd5b6001600d60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b3373ffffffffffffffffffffffffffffffffffffffff1661234c611bdf565b73ffffffffffffffffffffffffffffffffffffffff1614806123b75750601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b6123f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123ed90614b39565b60405180910390fd5b80601160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505050565b612446612c24565b6000601360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60606124ac826132fb565b9050919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60003373ffffffffffffffffffffffffffffffffffffffff16612568611bdf565b73ffffffffffffffffffffffffffffffffffffffff1614806125d35750601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b612612576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161260990614b39565b60405180910390fd5b6000620151809050600081846126289190615267565b426126339190614d9e565b90508092505050919050565b612647612c24565b612651600c61340d565b565b61265b612c24565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036126ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126c19061531b565b60405180910390fd5b6126d38161306d565b50565b6000806000806000806000803373ffffffffffffffffffffffffffffffffffffffff16612701611bdf565b73ffffffffffffffffffffffffffffffffffffffff16148061276c5750601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b6127ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127a290614b39565b60405180910390fd5b889750600d60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169650600e60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549550600f60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549450601060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549350601160008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549250601260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169150601360008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919395975091939597565b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612a215750612a2082613469565b5b9050919050565b612a3181612b42565b612a70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a6790615149565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16612aee83611538565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600081600001549050919050565b60008073ffffffffffffffffffffffffffffffffffffffff16612b6483613030565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6001816000016000828254019250508190555050565b612bb382826040518060200160405280600081525061354b565b5050565b612bc082612b42565b612bff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bf6906153ad565b60405180910390fd5b80600a60008481526020019081526020016000209081612c1f9190615579565b505050565b612c2c612a73565b73ffffffffffffffffffffffffffffffffffffffff16612c4a611bdf565b73ffffffffffffffffffffffffffffffffffffffff1614612ca0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c9790615697565b60405180910390fd5b565b600080612cae83611538565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612cf05750612cef81856124b3565b5b80612d2e57508373ffffffffffffffffffffffffffffffffffffffff16612d16846109c0565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16612d5782611538565b73ffffffffffffffffffffffffffffffffffffffff1614612dad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612da490615729565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612e1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e13906157bb565b60405180910390fd5b612e2983838360016135a6565b8273ffffffffffffffffffffffffffffffffffffffff16612e4982611538565b73ffffffffffffffffffffffffffffffffffffffff1614612e9f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e9690615729565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461302b83838360016135b8565b505050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036131a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161319890615827565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161329291906141ad565b60405180910390a3505050565b6132aa848484612d37565b6132b6848484846135be565b6132f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132ec906158b9565b60405180910390fd5b50505050565b606061330682612a28565b6000600a6000848152602001908152602001600020805461332690614b88565b80601f016020809104026020016040519081016040528092919081815260200182805461335290614b88565b801561339f5780601f106133745761010080835404028352916020019161339f565b820191906000526020600020905b81548152906001019060200180831161338257829003601f168201915b5050505050905060006133b0613745565b905060008151036133c5578192505050613408565b6000825111156133fa5780826040516020016133e2929190615915565b60405160208183030381529060405292505050613408565b6134038461375c565b925050505b919050565b60008160000154905060008111613459576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161345090615985565b60405180910390fd5b6001810382600001819055505050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061353457507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806135445750613543826137c4565b5b9050919050565b613555838361382e565b61356260008484846135be565b6135a1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613598906158b9565b60405180910390fd5b505050565b6135b284848484613a4b565b50505050565b50505050565b60006135df8473ffffffffffffffffffffffffffffffffffffffff16613ba9565b15613738578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613608612a73565b8786866040518563ffffffff1660e01b815260040161362a94939291906159fa565b6020604051808303816000875af192505050801561366657506040513d601f19601f820116820180604052508101906136639190615a5b565b60015b6136e8573d8060008114613696576040519150601f19603f3d011682016040523d82523d6000602084013e61369b565b606091505b5060008151036136e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136d7906158b9565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061373d565b600190505b949350505050565b606060405180602001604052806000815250905090565b606061376782612a28565b6000613771613745565b9050600081511161379157604051806020016040528060008152506137bc565b8061379b84613bcc565b6040516020016137ac929190615915565b6040516020818303038152906040525b915050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361389d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161389490615ad4565b60405180910390fd5b6138a681612b42565b156138e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138dd90615b40565b60405180910390fd5b6138f46000838360016135a6565b6138fd81612b42565b1561393d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161393490615b40565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4613a476000838360016135b8565b5050565b613a5784848484613c9a565b6001811115613a9b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a9290615bd2565b60405180910390fd5b6000829050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603613ae257613add81613ca0565b613b21565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614613b2057613b1f8582613ce9565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603613b6357613b5e81613e56565b613ba2565b8473ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614613ba157613ba08482613f27565b5b5b5050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606060006001613bdb84613fa6565b01905060008167ffffffffffffffff811115613bfa57613bf961446a565b5b6040519080825280601f01601f191660200182016040528015613c2c5781602001600182028036833780820191505090505b509050600082602001820190505b600115613c8f578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581613c8357613c82615bf2565b5b04945060008503613c3a575b819350505050919050565b50505050565b6008805490506009600083815260200190815260200160002081905550600881908060018154018082558091505060019003906000526020600020016000909190919091505550565b60006001613cf6846118c1565b613d009190615c21565b9050600060076000848152602001908152602001600020549050818114613de5576000600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816007600083815260200190815260200160002081905550505b6007600084815260200190815260200160002060009055600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b60006001600880549050613e6a9190615c21565b9050600060096000848152602001908152602001600020549050600060088381548110613e9a57613e99614ed0565b5b906000526020600020015490508060088381548110613ebc57613ebb614ed0565b5b906000526020600020018190555081600960008381526020019081526020016000208190555060096000858152602001908152602001600020600090556008805480613f0b57613f0a615c55565b5b6001900381819060005260206000200160009055905550505050565b6000613f32836118c1565b905081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806007600084815260200190815260200160002081905550505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310614004577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381613ffa57613ff9615bf2565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310614041576d04ee2d6d415b85acef8100000000838161403757614036615bf2565b5b0492506020810190505b662386f26fc10000831061407057662386f26fc10000838161406657614065615bf2565b5b0492506010810190505b6305f5e1008310614099576305f5e100838161408f5761408e615bf2565b5b0492506008810190505b61271083106140be5761271083816140b4576140b3615bf2565b5b0492506004810190505b606483106140e157606483816140d7576140d6615bf2565b5b0492506002810190505b600a83106140f0576001810190505b80915050919050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6141428161410d565b811461414d57600080fd5b50565b60008135905061415f81614139565b92915050565b60006020828403121561417b5761417a614103565b5b600061418984828501614150565b91505092915050565b60008115159050919050565b6141a781614192565b82525050565b60006020820190506141c2600083018461419e565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006141f3826141c8565b9050919050565b614203816141e8565b811461420e57600080fd5b50565b600081359050614220816141fa565b92915050565b60006020828403121561423c5761423b614103565b5b600061424a84828501614211565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561428d578082015181840152602081019050614272565b60008484015250505050565b6000601f19601f8301169050919050565b60006142b582614253565b6142bf818561425e565b93506142cf81856020860161426f565b6142d881614299565b840191505092915050565b600060208201905081810360008301526142fd81846142aa565b905092915050565b6000819050919050565b61431881614305565b811461432357600080fd5b50565b6000813590506143358161430f565b92915050565b60006020828403121561435157614350614103565b5b600061435f84828501614326565b91505092915050565b614371816141e8565b82525050565b600060208201905061438c6000830184614368565b92915050565b600080604083850312156143a9576143a8614103565b5b60006143b785828601614211565b92505060206143c885828601614326565b9150509250929050565b6143db81614192565b81146143e657600080fd5b50565b6000813590506143f8816143d2565b92915050565b6000806000806080858703121561441857614417614103565b5b600061442687828801614211565b9450506020614437878288016143e9565b935050604061444887828801614326565b925050606061445987828801614326565b91505092959194509250565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6144a282614299565b810181811067ffffffffffffffff821117156144c1576144c061446a565b5b80604052505050565b60006144d46140f9565b90506144e08282614499565b919050565b600067ffffffffffffffff821115614500576144ff61446a565b5b602082029050602081019050919050565b600080fd5b600080fd5b600067ffffffffffffffff8211156145365761453561446a565b5b61453f82614299565b9050602081019050919050565b82818337600083830152505050565b600061456e6145698461451b565b6144ca565b90508281526020810184848401111561458a57614589614516565b5b61459584828561454c565b509392505050565b600082601f8301126145b2576145b1614465565b5b81356145c284826020860161455b565b91505092915050565b60006145de6145d9846144e5565b6144ca565b9050808382526020820190506020840283018581111561460157614600614511565b5b835b8181101561464857803567ffffffffffffffff81111561462657614625614465565b5b808601614633898261459d565b85526020850194505050602081019050614603565b5050509392505050565b600082601f83011261466757614666614465565b5b81356146778482602086016145cb565b91505092915050565b60006020828403121561469657614695614103565b5b600082013567ffffffffffffffff8111156146b4576146b3614108565b5b6146c084828501614652565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6146fe81614305565b82525050565b600061471083836146f5565b60208301905092915050565b6000602082019050919050565b6000614734826146c9565b61473e81856146d4565b9350614749836146e5565b8060005b8381101561477a5781516147618882614704565b975061476c8361471c565b92505060018101905061474d565b5085935050505092915050565b600060208201905081810360008301526147a18184614729565b905092915050565b6147b281614305565b82525050565b60006020820190506147cd60008301846147a9565b92915050565b6000806000606084860312156147ec576147eb614103565b5b60006147fa86828701614211565b935050602061480b86828701614211565b925050604061481c86828701614326565b9150509250925092565b60006020828403121561483c5761483b614103565b5b600082013567ffffffffffffffff81111561485a57614859614108565b5b6148668482850161459d565b91505092915050565b6000806040838503121561488657614885614103565b5b600061489485828601614326565b925050602083013567ffffffffffffffff8111156148b5576148b4614108565b5b6148c18582860161459d565b9150509250929050565b6000610100820190506148e1600083018b614368565b6148ee602083018a61419e565b6148fb60408301896147a9565b61490860608301886147a9565b61491560808301876147a9565b61492260a08301866147a9565b61492f60c083018561419e565b61493c60e083018461419e565b9998505050505050505050565b600080604083850312156149605761495f614103565b5b600061496e85828601614211565b925050602061497f858286016143e9565b9150509250929050565b600067ffffffffffffffff8211156149a4576149a361446a565b5b6149ad82614299565b9050602081019050919050565b60006149cd6149c884614989565b6144ca565b9050828152602081018484840111156149e9576149e8614516565b5b6149f484828561454c565b509392505050565b600082601f830112614a1157614a10614465565b5b8135614a218482602086016149ba565b91505092915050565b60008060008060808587031215614a4457614a43614103565b5b6000614a5287828801614211565b9450506020614a6387828801614211565b9350506040614a7487828801614326565b925050606085013567ffffffffffffffff811115614a9557614a94614108565b5b614aa1878288016149fc565b91505092959194509250565b60008060408385031215614ac457614ac3614103565b5b6000614ad285828601614211565b9250506020614ae385828601614211565b9150509250929050565b7f43616c6c6572206973206e6f7420617574686f72697a65640000000000000000600082015250565b6000614b2360188361425e565b9150614b2e82614aed565b602082019050919050565b60006020820190508181036000830152614b5281614b16565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680614ba057607f821691505b602082108103614bb357614bb2614b59565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b6000614c1560218361425e565b9150614c2082614bb9565b604082019050919050565b60006020820190508181036000830152614c4481614c08565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b6000614ca7603d8361425e565b9150614cb282614c4b565b604082019050919050565b60006020820190508181036000830152614cd681614c9a565b9050919050565b7f4d696e74696e67204e4654206973206e6f7420616c6c6f77656420666f72207460008201527f6869732075736572000000000000000000000000000000000000000000000000602082015250565b6000614d3960288361425e565b9150614d4482614cdd565b604082019050919050565b60006020820190508181036000830152614d6881614d2c565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614da982614305565b9150614db483614305565b9250828201905080821115614dcc57614dcb614d6f565b5b92915050565b7f55736572206861732072656163686564206d6178204e4654206c696d69740000600082015250565b6000614e08601e8361425e565b9150614e1382614dd2565b602082019050919050565b60006020820190508181036000830152614e3781614dfb565b9050919050565b7f557365722773206d696e74696e67207065726d697373696f6e2068617320657860008201527f7069726564000000000000000000000000000000000000000000000000000000602082015250565b6000614e9a60258361425e565b9150614ea582614e3e565b604082019050919050565b60006020820190508181036000830152614ec981614e8d565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000614f0a82614305565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614f3c57614f3b614d6f565b5b600182019050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b6000614fa3602d8361425e565b9150614fae82614f47565b604082019050919050565b60006020820190508181036000830152614fd281614f96565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b6000615035602b8361425e565b915061504082614fd9565b604082019050919050565b6000602082019050818103600083015261506481615028565b9050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b60006150c7602c8361425e565b91506150d28261506b565b604082019050919050565b600060208201905081810360008301526150f6816150ba565b9050919050565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b600061513360188361425e565b915061513e826150fd565b602082019050919050565b6000602082019050818103600083015261516281615126565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b60006151c560298361425e565b91506151d082615169565b604082019050919050565b600060208201905081810360008301526151f4816151b8565b9050919050565b7f43616c6c6572206973206e6f742070726f20617574686f72697a656400000000600082015250565b6000615231601c8361425e565b915061523c826151fb565b602082019050919050565b6000602082019050818103600083015261526081615224565b9050919050565b600061527282614305565b915061527d83614305565b925082820261528b81614305565b915082820484148315176152a2576152a1614d6f565b5b5092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061530560268361425e565b9150615310826152a9565b604082019050919050565b60006020820190508181036000830152615334816152f8565b9050919050565b7f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60008201527f6578697374656e7420746f6b656e000000000000000000000000000000000000602082015250565b6000615397602e8361425e565b91506153a28261533b565b604082019050919050565b600060208201905081810360008301526153c68161538a565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b60006008830261542f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826153f2565b61543986836153f2565b95508019841693508086168417925050509392505050565b6000819050919050565b600061547661547161546c84614305565b615451565b614305565b9050919050565b6000819050919050565b6154908361545b565b6154a461549c8261547d565b8484546153ff565b825550505050565b600090565b6154b96154ac565b6154c4818484615487565b505050565b5b818110156154e8576154dd6000826154b1565b6001810190506154ca565b5050565b601f82111561552d576154fe816153cd565b615507846153e2565b81016020851015615516578190505b61552a615522856153e2565b8301826154c9565b50505b505050565b600082821c905092915050565b600061555060001984600802615532565b1980831691505092915050565b6000615569838361553f565b9150826002028217905092915050565b61558282614253565b67ffffffffffffffff81111561559b5761559a61446a565b5b6155a58254614b88565b6155b08282856154ec565b600060209050601f8311600181146155e357600084156155d1578287015190505b6155db858261555d565b865550615643565b601f1984166155f1866153cd565b60005b82811015615619578489015182556001820191506020850194506020810190506155f4565b868310156156365784890151615632601f89168261553f565b8355505b6001600288020188555050505b505050505050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061568160208361425e565b915061568c8261564b565b602082019050919050565b600060208201905081810360008301526156b081615674565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b600061571360258361425e565b915061571e826156b7565b604082019050919050565b6000602082019050818103600083015261574281615706565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006157a560248361425e565b91506157b082615749565b604082019050919050565b600060208201905081810360008301526157d481615798565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b600061581160198361425e565b915061581c826157db565b602082019050919050565b6000602082019050818103600083015261584081615804565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006158a360328361425e565b91506158ae82615847565b604082019050919050565b600060208201905081810360008301526158d281615896565b9050919050565b600081905092915050565b60006158ef82614253565b6158f981856158d9565b935061590981856020860161426f565b80840191505092915050565b600061592182856158e4565b915061592d82846158e4565b91508190509392505050565b7f436f756e7465723a2064656372656d656e74206f766572666c6f770000000000600082015250565b600061596f601b8361425e565b915061597a82615939565b602082019050919050565b6000602082019050818103600083015261599e81615962565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006159cc826159a5565b6159d681856159b0565b93506159e681856020860161426f565b6159ef81614299565b840191505092915050565b6000608082019050615a0f6000830187614368565b615a1c6020830186614368565b615a2960408301856147a9565b8181036060830152615a3b81846159c1565b905095945050505050565b600081519050615a5581614139565b92915050565b600060208284031215615a7157615a70614103565b5b6000615a7f84828501615a46565b91505092915050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000615abe60208361425e565b9150615ac982615a88565b602082019050919050565b60006020820190508181036000830152615aed81615ab1565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000615b2a601c8361425e565b9150615b3582615af4565b602082019050919050565b60006020820190508181036000830152615b5981615b1d565b9050919050565b7f455243373231456e756d657261626c653a20636f6e736563757469766520747260008201527f616e7366657273206e6f7420737570706f727465640000000000000000000000602082015250565b6000615bbc60358361425e565b9150615bc782615b60565b604082019050919050565b60006020820190508181036000830152615beb81615baf565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000615c2c82614305565b9150615c3783614305565b9250828203905081811115615c4f57615c4e614d6f565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea2646970667358221220b3938949c453fdefad1d533c9c694d7da82de387ec75d568831c6b9f3928346c64736f6c63430008120033

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102695760003560e01c8063715018a611610151578063b6f4b345116100c3578063c87b56dd11610087578063c87b56dd1461070b578063e985e9c51461073b578063edea4ed71461076b578063f25b62091461079b578063f2fde38b146107a5578063ffc9896b146107c157610269565b8063b6f4b3451461067f578063b88d4fde1461069b578063ba3adc3f146106b7578063c2919947146106d3578063c70c7c67146106ef57610269565b806392146b8b1161011557806392146b8b146105cc57806395d89b41146105f1578063991f453e1461060f5780639fece0981461062b578063a22cb46514610647578063b366a1f01461066357610269565b8063715018a6146105505780637fb3a9a21461055a5780638483c4ad1461057657806389fabc80146105925780638da5cb5b146105ae57610269565b806323b872dd116101ea57806356189236116101ae57806356189236146104685780635ab29cf7146104865780635e01eb5a146104a25780636352211e146104c0578063695850fb146104f057806370a082311461052057610269565b806323b872dd146103c6578063262ec85d146103e25780632f745c59146103ec57806342842e0e1461041c5780634f6ccce71461043857610269565b80631126fe77116102315780631126fe771461032457806315f77edc14610340578063177d2a741461037057806318160ddd1461038c57806320c50c34146103aa57610269565b806301ffc9a71461026e57806306d6dfc81461029e57806306fdde03146102ba578063081812fc146102d8578063095ea7b314610308575b600080fd5b61028860048036038101906102839190614165565b6107f8565b60405161029591906141ad565b60405180910390f35b6102b860048036038101906102b39190614226565b61080a565b005b6102c261092e565b6040516102cf91906142e3565b60405180910390f35b6102f260048036038101906102ed919061433b565b6109c0565b6040516102ff9190614377565b60405180910390f35b610322600480360381019061031d9190614392565b610a06565b005b61033e600480360381019061033991906143fe565b610b1d565b005b61035a60048036038101906103559190614680565b610d18565b6040516103679190614787565b60405180910390f35b61038a60048036038101906103859190614226565b6110d1565b005b610394611134565b6040516103a191906147b8565b60405180910390f35b6103c460048036038101906103bf9190614392565b611141565b005b6103e060048036038101906103db91906147d3565b611264565b005b6103ea6112c4565b005b61040660048036038101906104019190614392565b6112d8565b60405161041391906147b8565b60405180910390f35b610436600480360381019061043191906147d3565b61137d565b005b610452600480360381019061044d919061433b565b61139d565b60405161045f91906147b8565b60405180910390f35b61047061140e565b60405161047d91906147b8565b60405180910390f35b6104a0600480360381019061049b9190614392565b61141f565b005b6104aa611530565b6040516104b79190614377565b60405180910390f35b6104da60048036038101906104d5919061433b565b611538565b6040516104e79190614377565b60405180910390f35b61050a60048036038101906105059190614826565b6115be565b60405161051791906147b8565b60405180910390f35b61053a60048036038101906105359190614226565b6118c1565b60405161054791906147b8565b60405180910390f35b610558611978565b005b610574600480360381019061056f919061486f565b61198c565b005b610590600480360381019061058b9190614392565b611a63565b005b6105ac60048036038101906105a79190614226565b611b7c565b005b6105b6611bdf565b6040516105c39190614377565b60405180910390f35b6105d4611c09565b6040516105e89897969594939291906148cb565b60405180910390f35b6105f9611e17565b60405161060691906142e3565b60405180910390f35b61062960048036038101906106249190614392565b611ea9565b005b61064560048036038101906106409190614226565b611fba565b005b610661600480360381019061065c9190614949565b61201d565b005b61067d60048036038101906106789190614392565b612033565b005b61069960048036038101906106949190614949565b612083565b005b6106b560048036038101906106b09190614a2a565b6121a7565b005b6106d160048036038101906106cc9190614226565b612209565b005b6106ed60048036038101906106e89190614392565b61232d565b005b61070960048036038101906107049190614226565b61243e565b005b6107256004803603810190610720919061433b565b6124a1565b60405161073291906142e3565b60405180910390f35b61075560048036038101906107509190614aad565b6124b3565b60405161076291906141ad565b60405180910390f35b6107856004803603810190610780919061433b565b612547565b60405161079291906147b8565b60405180910390f35b6107a361263f565b005b6107bf60048036038101906107ba9190614226565b612653565b005b6107db60048036038101906107d69190614226565b6126d6565b6040516107ef9897969594939291906148cb565b60405180910390f35b6000610803826129ae565b9050919050565b3373ffffffffffffffffffffffffffffffffffffffff16610829611bdf565b73ffffffffffffffffffffffffffffffffffffffff1614806108945750601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b6108d3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ca90614b39565b60405180910390fd5b6000600d60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60606000805461093d90614b88565b80601f016020809104026020016040519081016040528092919081815260200182805461096990614b88565b80156109b65780601f1061098b576101008083540402835291602001916109b6565b820191906000526020600020905b81548152906001019060200180831161099957829003601f168201915b5050505050905090565b60006109cb82612a28565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610a1182611538565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610a81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a7890614c2b565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610aa0612a73565b73ffffffffffffffffffffffffffffffffffffffff161480610acf5750610ace81610ac9612a73565b6124b3565b5b610b0e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b0590614cbd565b60405180910390fd5b610b188383612a7b565b505050565b3373ffffffffffffffffffffffffffffffffffffffff16610b3c611bdf565b73ffffffffffffffffffffffffffffffffffffffff161480610ba75750601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b610be6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bdd90614b39565b60405180910390fd5b6000600f60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555081601060008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550610c7881612547565b601160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000208190555082600d60008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050505050565b6060600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16610da6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d9d90614d4f565b60405180910390fd5b60106000610db2612a73565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020548251600f6000610dfb612a73565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054610e409190614d9e565b1115610e81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e7890614e1e565b60405180910390fd5b60116000610e8d612a73565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054421115610f0a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f0190614eb0565b60405180910390fd5b6000825167ffffffffffffffff811115610f2757610f2661446a565b5b604051908082528060200260200182016040528015610f555781602001602082028036833780820191505090505b50905060005b83518110156110c7576000610f70600c612b34565b90505b610f7c81612b42565b15610f9c57610f8b600c612b83565b610f95600c612b34565b9050610f73565b610fa6600c612b83565b610fb7610fb1612a73565b82612b99565b610fdb81868481518110610fce57610fcd614ed0565b5b6020026020010151612bb7565b600f6000610fe7612a73565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081548092919061103290614eff565b9190505550600e6000611043612a73565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081548092919061108e90614eff565b9190505550808383815181106110a7576110a6614ed0565b5b6020026020010181815250505080806110bf90614eff565b915050610f5b565b5080915050919050565b6110d9612c24565b6001601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b6000600880549050905090565b3373ffffffffffffffffffffffffffffffffffffffff16611160611bdf565b73ffffffffffffffffffffffffffffffffffffffff1614806111cb5750601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b61120a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120190614b39565b60405180910390fd5b80601060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546112599190614d9e565b925050819055505050565b61127561126f612a73565b82612ca2565b6112b4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112ab90614fb9565b60405180910390fd5b6112bf838383612d37565b505050565b6112cc612c24565b6112d6600c612b83565b565b60006112e3836118c1565b8210611324576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161131b9061504b565b60405180910390fd5b600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b611398838383604051806020016040528060008152506121a7565b505050565b60006113a7611134565b82106113e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113df906150dd565b60405180910390fd5b600882815481106113fc576113fb614ed0565b5b90600052602060002001549050919050565b600061141a600c612b34565b905090565b3373ffffffffffffffffffffffffffffffffffffffff1661143e611bdf565b73ffffffffffffffffffffffffffffffffffffffff1614806114a95750601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b6114e8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016114df90614b39565b60405180910390fd5b80600f60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505050565b600033905090565b60008061154483613030565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036115b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115ac90615149565b60405180910390fd5b80915050919050565b6000600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1661164c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161164390614d4f565b60405180910390fd5b60106000611658612a73565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054600f600061169f612a73565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020541061171a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161171190614e1e565b60405180910390fd5b60116000611726612a73565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020544211156117a3576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161179a90614eb0565b60405180910390fd5b60006117af600c612b34565b90505b6117bb81612b42565b156117db576117ca600c612b83565b6117d4600c612b34565b90506117b2565b6117e5600c612b83565b6117f66117f0612a73565b82612b99565b6118008184612bb7565b600f600061180c612a73565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081548092919061185790614eff565b9190505550600e6000611868612a73565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008154809291906118b390614eff565b919050555080915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611931576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611928906151db565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b611980612c24565b61198a600061306d565b565b3373ffffffffffffffffffffffffffffffffffffffff166119ab611bdf565b73ffffffffffffffffffffffffffffffffffffffff161480611a165750601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b611a55576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a4c90615247565b60405180910390fd5b611a5f8282612bb7565b5050565b3373ffffffffffffffffffffffffffffffffffffffff16611a82611bdf565b73ffffffffffffffffffffffffffffffffffffffff161480611aed5750601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b611b2c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b2390614b39565b60405180910390fd5b611b3581612547565b601160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505050565b611b84612c24565b6000601260008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600080600080600080600080339750600d60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169650600e60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549550600f60003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549450601060003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549350601160003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549250601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169150601360003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff1690509091929394959697565b606060018054611e2690614b88565b80601f0160208091040260200160405190810160405280929190818152602001828054611e5290614b88565b8015611e9f5780601f10611e7457610100808354040283529160200191611e9f565b820191906000526020600020905b815481529060010190602001808311611e8257829003601f168201915b5050505050905090565b3373ffffffffffffffffffffffffffffffffffffffff16611ec8611bdf565b73ffffffffffffffffffffffffffffffffffffffff161480611f335750601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b611f72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611f6990614b39565b60405180910390fd5b80601060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505050565b611fc2612c24565b6001601360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b61202f612028612a73565b8383613133565b5050565b61203b612c24565b80600e60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505050565b3373ffffffffffffffffffffffffffffffffffffffff166120a2611bdf565b73ffffffffffffffffffffffffffffffffffffffff16148061210d5750601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b61214c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161214390614b39565b60405180910390fd5b80600d60008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055505050565b6121b86121b2612a73565b83612ca2565b6121f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121ee90614fb9565b60405180910390fd5b6122038484848461329f565b50505050565b3373ffffffffffffffffffffffffffffffffffffffff16612228611bdf565b73ffffffffffffffffffffffffffffffffffffffff1614806122935750601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b6122d2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122c990614b39565b60405180910390fd5b6001600d60008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b3373ffffffffffffffffffffffffffffffffffffffff1661234c611bdf565b73ffffffffffffffffffffffffffffffffffffffff1614806123b75750601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b6123f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123ed90614b39565b60405180910390fd5b80601160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020819055505050565b612446612c24565b6000601360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b60606124ac826132fb565b9050919050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b60003373ffffffffffffffffffffffffffffffffffffffff16612568611bdf565b73ffffffffffffffffffffffffffffffffffffffff1614806125d35750601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b612612576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161260990614b39565b60405180910390fd5b6000620151809050600081846126289190615267565b426126339190614d9e565b90508092505050919050565b612647612c24565b612651600c61340d565b565b61265b612c24565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036126ca576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126c19061531b565b60405180910390fd5b6126d38161306d565b50565b6000806000806000806000803373ffffffffffffffffffffffffffffffffffffffff16612701611bdf565b73ffffffffffffffffffffffffffffffffffffffff16148061276c5750601260003373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff165b6127ab576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016127a290614b39565b60405180910390fd5b889750600d60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169650600e60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549550600f60008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549450601060008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549350601160008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549250601260008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169150601360008a73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff169050919395975091939597565b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480612a215750612a2082613469565b5b9050919050565b612a3181612b42565b612a70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a6790615149565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16612aee83611538565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600081600001549050919050565b60008073ffffffffffffffffffffffffffffffffffffffff16612b6483613030565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b6001816000016000828254019250508190555050565b612bb382826040518060200160405280600081525061354b565b5050565b612bc082612b42565b612bff576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bf6906153ad565b60405180910390fd5b80600a60008481526020019081526020016000209081612c1f9190615579565b505050565b612c2c612a73565b73ffffffffffffffffffffffffffffffffffffffff16612c4a611bdf565b73ffffffffffffffffffffffffffffffffffffffff1614612ca0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612c9790615697565b60405180910390fd5b565b600080612cae83611538565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480612cf05750612cef81856124b3565b5b80612d2e57508373ffffffffffffffffffffffffffffffffffffffff16612d16846109c0565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16612d5782611538565b73ffffffffffffffffffffffffffffffffffffffff1614612dad576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612da490615729565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612e1c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e13906157bb565b60405180910390fd5b612e2983838360016135a6565b8273ffffffffffffffffffffffffffffffffffffffff16612e4982611538565b73ffffffffffffffffffffffffffffffffffffffff1614612e9f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e9690615729565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461302b83838360016135b8565b505050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036131a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161319890615827565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161329291906141ad565b60405180910390a3505050565b6132aa848484612d37565b6132b6848484846135be565b6132f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132ec906158b9565b60405180910390fd5b50505050565b606061330682612a28565b6000600a6000848152602001908152602001600020805461332690614b88565b80601f016020809104026020016040519081016040528092919081815260200182805461335290614b88565b801561339f5780601f106133745761010080835404028352916020019161339f565b820191906000526020600020905b81548152906001019060200180831161338257829003601f168201915b5050505050905060006133b0613745565b905060008151036133c5578192505050613408565b6000825111156133fa5780826040516020016133e2929190615915565b60405160208183030381529060405292505050613408565b6134038461375c565b925050505b919050565b60008160000154905060008111613459576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161345090615985565b60405180910390fd5b6001810382600001819055505050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061353457507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806135445750613543826137c4565b5b9050919050565b613555838361382e565b61356260008484846135be565b6135a1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613598906158b9565b60405180910390fd5b505050565b6135b284848484613a4b565b50505050565b50505050565b60006135df8473ffffffffffffffffffffffffffffffffffffffff16613ba9565b15613738578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02613608612a73565b8786866040518563ffffffff1660e01b815260040161362a94939291906159fa565b6020604051808303816000875af192505050801561366657506040513d601f19601f820116820180604052508101906136639190615a5b565b60015b6136e8573d8060008114613696576040519150601f19603f3d011682016040523d82523d6000602084013e61369b565b606091505b5060008151036136e0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016136d7906158b9565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061373d565b600190505b949350505050565b606060405180602001604052806000815250905090565b606061376782612a28565b6000613771613745565b9050600081511161379157604051806020016040528060008152506137bc565b8061379b84613bcc565b6040516020016137ac929190615915565b6040516020818303038152906040525b915050919050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160361389d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161389490615ad4565b60405180910390fd5b6138a681612b42565b156138e6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016138dd90615b40565b60405180910390fd5b6138f46000838360016135a6565b6138fd81612b42565b1561393d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161393490615b40565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4613a476000838360016135b8565b5050565b613a5784848484613c9a565b6001811115613a9b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401613a9290615bd2565b60405180910390fd5b6000829050600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603613ae257613add81613ca0565b613b21565b8373ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1614613b2057613b1f8582613ce9565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603613b6357613b5e81613e56565b613ba2565b8473ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614613ba157613ba08482613f27565b5b5b5050505050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b606060006001613bdb84613fa6565b01905060008167ffffffffffffffff811115613bfa57613bf961446a565b5b6040519080825280601f01601f191660200182016040528015613c2c5781602001600182028036833780820191505090505b509050600082602001820190505b600115613c8f578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581613c8357613c82615bf2565b5b04945060008503613c3a575b819350505050919050565b50505050565b6008805490506009600083815260200190815260200160002081905550600881908060018154018082558091505060019003906000526020600020016000909190919091505550565b60006001613cf6846118c1565b613d009190615c21565b9050600060076000848152602001908152602001600020549050818114613de5576000600660008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600660008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816007600083815260200190815260200160002081905550505b6007600084815260200190815260200160002060009055600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b60006001600880549050613e6a9190615c21565b9050600060096000848152602001908152602001600020549050600060088381548110613e9a57613e99614ed0565b5b906000526020600020015490508060088381548110613ebc57613ebb614ed0565b5b906000526020600020018190555081600960008381526020019081526020016000208190555060096000858152602001908152602001600020600090556008805480613f0b57613f0a615c55565b5b6001900381819060005260206000200160009055905550505050565b6000613f32836118c1565b905081600660008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806007600084815260200190815260200160002081905550505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310614004577a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008381613ffa57613ff9615bf2565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310614041576d04ee2d6d415b85acef8100000000838161403757614036615bf2565b5b0492506020810190505b662386f26fc10000831061407057662386f26fc10000838161406657614065615bf2565b5b0492506010810190505b6305f5e1008310614099576305f5e100838161408f5761408e615bf2565b5b0492506008810190505b61271083106140be5761271083816140b4576140b3615bf2565b5b0492506004810190505b606483106140e157606483816140d7576140d6615bf2565b5b0492506002810190505b600a83106140f0576001810190505b80915050919050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6141428161410d565b811461414d57600080fd5b50565b60008135905061415f81614139565b92915050565b60006020828403121561417b5761417a614103565b5b600061418984828501614150565b91505092915050565b60008115159050919050565b6141a781614192565b82525050565b60006020820190506141c2600083018461419e565b92915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006141f3826141c8565b9050919050565b614203816141e8565b811461420e57600080fd5b50565b600081359050614220816141fa565b92915050565b60006020828403121561423c5761423b614103565b5b600061424a84828501614211565b91505092915050565b600081519050919050565b600082825260208201905092915050565b60005b8381101561428d578082015181840152602081019050614272565b60008484015250505050565b6000601f19601f8301169050919050565b60006142b582614253565b6142bf818561425e565b93506142cf81856020860161426f565b6142d881614299565b840191505092915050565b600060208201905081810360008301526142fd81846142aa565b905092915050565b6000819050919050565b61431881614305565b811461432357600080fd5b50565b6000813590506143358161430f565b92915050565b60006020828403121561435157614350614103565b5b600061435f84828501614326565b91505092915050565b614371816141e8565b82525050565b600060208201905061438c6000830184614368565b92915050565b600080604083850312156143a9576143a8614103565b5b60006143b785828601614211565b92505060206143c885828601614326565b9150509250929050565b6143db81614192565b81146143e657600080fd5b50565b6000813590506143f8816143d2565b92915050565b6000806000806080858703121561441857614417614103565b5b600061442687828801614211565b9450506020614437878288016143e9565b935050604061444887828801614326565b925050606061445987828801614326565b91505092959194509250565b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6144a282614299565b810181811067ffffffffffffffff821117156144c1576144c061446a565b5b80604052505050565b60006144d46140f9565b90506144e08282614499565b919050565b600067ffffffffffffffff821115614500576144ff61446a565b5b602082029050602081019050919050565b600080fd5b600080fd5b600067ffffffffffffffff8211156145365761453561446a565b5b61453f82614299565b9050602081019050919050565b82818337600083830152505050565b600061456e6145698461451b565b6144ca565b90508281526020810184848401111561458a57614589614516565b5b61459584828561454c565b509392505050565b600082601f8301126145b2576145b1614465565b5b81356145c284826020860161455b565b91505092915050565b60006145de6145d9846144e5565b6144ca565b9050808382526020820190506020840283018581111561460157614600614511565b5b835b8181101561464857803567ffffffffffffffff81111561462657614625614465565b5b808601614633898261459d565b85526020850194505050602081019050614603565b5050509392505050565b600082601f83011261466757614666614465565b5b81356146778482602086016145cb565b91505092915050565b60006020828403121561469657614695614103565b5b600082013567ffffffffffffffff8111156146b4576146b3614108565b5b6146c084828501614652565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b6146fe81614305565b82525050565b600061471083836146f5565b60208301905092915050565b6000602082019050919050565b6000614734826146c9565b61473e81856146d4565b9350614749836146e5565b8060005b8381101561477a5781516147618882614704565b975061476c8361471c565b92505060018101905061474d565b5085935050505092915050565b600060208201905081810360008301526147a18184614729565b905092915050565b6147b281614305565b82525050565b60006020820190506147cd60008301846147a9565b92915050565b6000806000606084860312156147ec576147eb614103565b5b60006147fa86828701614211565b935050602061480b86828701614211565b925050604061481c86828701614326565b9150509250925092565b60006020828403121561483c5761483b614103565b5b600082013567ffffffffffffffff81111561485a57614859614108565b5b6148668482850161459d565b91505092915050565b6000806040838503121561488657614885614103565b5b600061489485828601614326565b925050602083013567ffffffffffffffff8111156148b5576148b4614108565b5b6148c18582860161459d565b9150509250929050565b6000610100820190506148e1600083018b614368565b6148ee602083018a61419e565b6148fb60408301896147a9565b61490860608301886147a9565b61491560808301876147a9565b61492260a08301866147a9565b61492f60c083018561419e565b61493c60e083018461419e565b9998505050505050505050565b600080604083850312156149605761495f614103565b5b600061496e85828601614211565b925050602061497f858286016143e9565b9150509250929050565b600067ffffffffffffffff8211156149a4576149a361446a565b5b6149ad82614299565b9050602081019050919050565b60006149cd6149c884614989565b6144ca565b9050828152602081018484840111156149e9576149e8614516565b5b6149f484828561454c565b509392505050565b600082601f830112614a1157614a10614465565b5b8135614a218482602086016149ba565b91505092915050565b60008060008060808587031215614a4457614a43614103565b5b6000614a5287828801614211565b9450506020614a6387828801614211565b9350506040614a7487828801614326565b925050606085013567ffffffffffffffff811115614a9557614a94614108565b5b614aa1878288016149fc565b91505092959194509250565b60008060408385031215614ac457614ac3614103565b5b6000614ad285828601614211565b9250506020614ae385828601614211565b9150509250929050565b7f43616c6c6572206973206e6f7420617574686f72697a65640000000000000000600082015250565b6000614b2360188361425e565b9150614b2e82614aed565b602082019050919050565b60006020820190508181036000830152614b5281614b16565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680614ba057607f821691505b602082108103614bb357614bb2614b59565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b6000614c1560218361425e565b9150614c2082614bb9565b604082019050919050565b60006020820190508181036000830152614c4481614c08565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b6000614ca7603d8361425e565b9150614cb282614c4b565b604082019050919050565b60006020820190508181036000830152614cd681614c9a565b9050919050565b7f4d696e74696e67204e4654206973206e6f7420616c6c6f77656420666f72207460008201527f6869732075736572000000000000000000000000000000000000000000000000602082015250565b6000614d3960288361425e565b9150614d4482614cdd565b604082019050919050565b60006020820190508181036000830152614d6881614d2c565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b6000614da982614305565b9150614db483614305565b9250828201905080821115614dcc57614dcb614d6f565b5b92915050565b7f55736572206861732072656163686564206d6178204e4654206c696d69740000600082015250565b6000614e08601e8361425e565b9150614e1382614dd2565b602082019050919050565b60006020820190508181036000830152614e3781614dfb565b9050919050565b7f557365722773206d696e74696e67207065726d697373696f6e2068617320657860008201527f7069726564000000000000000000000000000000000000000000000000000000602082015250565b6000614e9a60258361425e565b9150614ea582614e3e565b604082019050919050565b60006020820190508181036000830152614ec981614e8d565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6000614f0a82614305565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203614f3c57614f3b614d6f565b5b600182019050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b6000614fa3602d8361425e565b9150614fae82614f47565b604082019050919050565b60006020820190508181036000830152614fd281614f96565b9050919050565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b6000615035602b8361425e565b915061504082614fd9565b604082019050919050565b6000602082019050818103600083015261506481615028565b9050919050565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b60006150c7602c8361425e565b91506150d28261506b565b604082019050919050565b600060208201905081810360008301526150f6816150ba565b9050919050565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b600061513360188361425e565b915061513e826150fd565b602082019050919050565b6000602082019050818103600083015261516281615126565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b60006151c560298361425e565b91506151d082615169565b604082019050919050565b600060208201905081810360008301526151f4816151b8565b9050919050565b7f43616c6c6572206973206e6f742070726f20617574686f72697a656400000000600082015250565b6000615231601c8361425e565b915061523c826151fb565b602082019050919050565b6000602082019050818103600083015261526081615224565b9050919050565b600061527282614305565b915061527d83614305565b925082820261528b81614305565b915082820484148315176152a2576152a1614d6f565b5b5092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061530560268361425e565b9150615310826152a9565b604082019050919050565b60006020820190508181036000830152615334816152f8565b9050919050565b7f45524337323155524953746f726167653a2055524920736574206f66206e6f6e60008201527f6578697374656e7420746f6b656e000000000000000000000000000000000000602082015250565b6000615397602e8361425e565b91506153a28261533b565b604082019050919050565b600060208201905081810360008301526153c68161538a565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b60006008830261542f7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826153f2565b61543986836153f2565b95508019841693508086168417925050509392505050565b6000819050919050565b600061547661547161546c84614305565b615451565b614305565b9050919050565b6000819050919050565b6154908361545b565b6154a461549c8261547d565b8484546153ff565b825550505050565b600090565b6154b96154ac565b6154c4818484615487565b505050565b5b818110156154e8576154dd6000826154b1565b6001810190506154ca565b5050565b601f82111561552d576154fe816153cd565b615507846153e2565b81016020851015615516578190505b61552a615522856153e2565b8301826154c9565b50505b505050565b600082821c905092915050565b600061555060001984600802615532565b1980831691505092915050565b6000615569838361553f565b9150826002028217905092915050565b61558282614253565b67ffffffffffffffff81111561559b5761559a61446a565b5b6155a58254614b88565b6155b08282856154ec565b600060209050601f8311600181146155e357600084156155d1578287015190505b6155db858261555d565b865550615643565b601f1984166155f1866153cd565b60005b82811015615619578489015182556001820191506020850194506020810190506155f4565b868310156156365784890151615632601f89168261553f565b8355505b6001600288020188555050505b505050505050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061568160208361425e565b915061568c8261564b565b602082019050919050565b600060208201905081810360008301526156b081615674565b9050919050565b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b600061571360258361425e565b915061571e826156b7565b604082019050919050565b6000602082019050818103600083015261574281615706565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b60006157a560248361425e565b91506157b082615749565b604082019050919050565b600060208201905081810360008301526157d481615798565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b600061581160198361425e565b915061581c826157db565b602082019050919050565b6000602082019050818103600083015261584081615804565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006158a360328361425e565b91506158ae82615847565b604082019050919050565b600060208201905081810360008301526158d281615896565b9050919050565b600081905092915050565b60006158ef82614253565b6158f981856158d9565b935061590981856020860161426f565b80840191505092915050565b600061592182856158e4565b915061592d82846158e4565b91508190509392505050565b7f436f756e7465723a2064656372656d656e74206f766572666c6f770000000000600082015250565b600061596f601b8361425e565b915061597a82615939565b602082019050919050565b6000602082019050818103600083015261599e81615962565b9050919050565b600081519050919050565b600082825260208201905092915050565b60006159cc826159a5565b6159d681856159b0565b93506159e681856020860161426f565b6159ef81614299565b840191505092915050565b6000608082019050615a0f6000830187614368565b615a1c6020830186614368565b615a2960408301856147a9565b8181036060830152615a3b81846159c1565b905095945050505050565b600081519050615a5581614139565b92915050565b600060208284031215615a7157615a70614103565b5b6000615a7f84828501615a46565b91505092915050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000615abe60208361425e565b9150615ac982615a88565b602082019050919050565b60006020820190508181036000830152615aed81615ab1565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b6000615b2a601c8361425e565b9150615b3582615af4565b602082019050919050565b60006020820190508181036000830152615b5981615b1d565b9050919050565b7f455243373231456e756d657261626c653a20636f6e736563757469766520747260008201527f616e7366657273206e6f7420737570706f727465640000000000000000000000602082015250565b6000615bbc60358361425e565b9150615bc782615b60565b604082019050919050565b60006020820190508181036000830152615beb81615baf565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b6000615c2c82614305565b9150615c3783614305565b9250828203905081811115615c4f57615c4e614d6f565b5b92915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fdfea2646970667358221220b3938949c453fdefad1d533c9c694d7da82de387ec75d568831c6b9f3928346c64736f6c63430008120033

Deployed Bytecode Sourcemap

66387:13354:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79526:212;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73114:155;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;42050:100;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43562:171;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43080:416;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;75300:429;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;71053:1272;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;77222:106;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;60944:113;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;76189:201;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;44262:335;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;76506:94;;;:::i;:::-;;60612:256;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44668:185;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;61134:233;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;76710:110;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73606:209;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67735:87;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41760:223;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69932:1113;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;41491:207;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;19473:103;;;:::i;:::-;;78514:159;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;75838:199;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;77439:110;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;18825:87;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67830:978;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;;;;;;;;42219:104;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73980:201;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;78022:112;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;43805:155;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;73352:154;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72536:164;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;44924:322;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;72845:126;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;74422:199;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;78252:116;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;78745:196;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44031:164;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74839:293;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;76608:94;;;:::i;:::-;;19731:201;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;68816:1021;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;;;;;;;;79526:212;79665:4;79694:36;79718:11;79694:23;:36::i;:::-;79687:43;;79526:212;;;:::o;73114:155::-;76993:10;76982:21;;:7;:5;:7::i;:::-;:21;;;:53;;;;77007:16;:28;77024:10;77007:28;;;;;;;;;;;;;;;;;;;;;;;;;76982:53;76960:127;;;;;;;;;;;;:::i;:::-;;;;;;;;;73256:5:::1;73225:15;:28;73241:11;73225:28;;;;;;;;;;;;;;;;:36;;;;;;;;;;;;;;;;;;73114:155:::0;:::o;42050:100::-;42104:13;42137:5;42130:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42050:100;:::o;43562:171::-;43638:7;43658:23;43673:7;43658:14;:23::i;:::-;43701:15;:24;43717:7;43701:24;;;;;;;;;;;;;;;;;;;;;43694:31;;43562:171;;;:::o;43080:416::-;43161:13;43177:23;43192:7;43177:14;:23::i;:::-;43161:39;;43225:5;43219:11;;:2;:11;;;43211:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;43319:5;43303:21;;:12;:10;:12::i;:::-;:21;;;:62;;;;43328:37;43345:5;43352:12;:10;:12::i;:::-;43328:16;:37::i;:::-;43303:62;43281:173;;;;;;;;;;;;:::i;:::-;;;;;;;;;43467:21;43476:2;43480:7;43467:8;:21::i;:::-;43150:346;43080:416;;:::o;75300:429::-;76993:10;76982:21;;:7;:5;:7::i;:::-;:21;;;:53;;;;77007:16;:28;77024:10;77007:28;;;;;;;;;;;;;;;;;;;;;;;;;76982:53;76960:127;;;;;;;;;;;;:::i;:::-;;;;;;;;;75528:1:::1;75478:34;:47;75513:11;75478:47;;;;;;;;;;;;;;;:51;;;;75586:11;75540:30;:43;75571:11;75540:43;;;;;;;;;;;;;;;:57;;;;75647:25;75662:9;75647:14;:25::i;:::-;75608:23;:36;75632:11;75608:36;;;;;;;;;;;;;;;:64;;;;75714:7;75683:15;:28;75699:11;75683:28;;;;;;;;;;;;;;;;:38;;;;;;;;;;;;;;;;;;75300:429:::0;;;;:::o;71053:1272::-;71135:16;71191:15;:27;71207:10;71191:27;;;;;;;;;;;;;;;;;;;;;;;;;71169:117;;;;;;;;;;;;:::i;:::-;;;;;;;;;71404:30;:44;71435:12;:10;:12::i;:::-;71404:44;;;;;;;;;;;;;;;;71372:4;:11;71321:34;:48;71356:12;:10;:12::i;:::-;71321:48;;;;;;;;;;;;;;;;:62;;;;:::i;:::-;:127;;71299:207;;;;;;;;;;;;:::i;:::-;;;;;;;;;71560:23;:37;71584:12;:10;:12::i;:::-;71560:37;;;;;;;;;;;;;;;;71541:15;:56;;71519:143;;;;;;;;;;;;:::i;:::-;;;;;;;;;71675:25;71717:4;:11;71703:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;71675:54;;71747:9;71742:548;71766:4;:11;71762:1;:15;71742:548;;;71799:15;71817:25;:15;:23;:25::i;:::-;71799:43;;71857:141;71864:16;71872:7;71864;:16::i;:::-;71857:141;;;71901:27;:15;:25;:27::i;:::-;71957:25;:15;:23;:25::i;:::-;71947:35;;71857:141;;;72012:27;:15;:25;:27::i;:::-;72054:32;72064:12;:10;:12::i;:::-;72078:7;72054:9;:32::i;:::-;72101:30;72114:7;72123:4;72128:1;72123:7;;;;;;;;:::i;:::-;;;;;;;;72101:12;:30::i;:::-;72146:34;:48;72181:12;:10;:12::i;:::-;72146:48;;;;;;;;;;;;;;;;:50;;;;;;;;;:::i;:::-;;;;;;72211:13;:27;72225:12;:10;:12::i;:::-;72211:27;;;;;;;;;;;;;;;;:29;;;;;;;;;:::i;:::-;;;;;;72271:7;72257:8;72266:1;72257:11;;;;;;;;:::i;:::-;;;;;;;:21;;;;;71784:506;71779:3;;;;;:::i;:::-;;;;71742:548;;;;72309:8;72302:15;;;71053:1272;;;:::o;77222:106::-;18711:13;:11;:13::i;:::-;77316:4:::1;77291:16;:22;77308:4;77291:22;;;;;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;77222:106:::0;:::o;60944:113::-;61005:7;61032:10;:17;;;;61025:24;;60944:113;:::o;76189:201::-;76993:10;76982:21;;:7;:5;:7::i;:::-;:21;;;:53;;;;77007:16;:28;77024:10;77007:28;;;;;;;;;;;;;;;;;;;;;;;;;76982:53;76960:127;;;;;;;;;;;;:::i;:::-;;;;;;;;;76369:13:::1;76322:30;:43;76353:11;76322:43;;;;;;;;;;;;;;;;:60;;;;;;;:::i;:::-;;;;;;;;76189:201:::0;;:::o;44262:335::-;44457:41;44476:12;:10;:12::i;:::-;44490:7;44457:18;:41::i;:::-;44449:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;44561:28;44571:4;44577:2;44581:7;44561:9;:28::i;:::-;44262:335;;;:::o;76506:94::-;18711:13;:11;:13::i;:::-;76565:27:::1;:15;:25;:27::i;:::-;76506:94::o:0;60612:256::-;60709:7;60745:23;60762:5;60745:16;:23::i;:::-;60737:5;:31;60729:87;;;;;;;;;;;;:::i;:::-;;;;;;;;;60834:12;:19;60847:5;60834:19;;;;;;;;;;;;;;;:26;60854:5;60834:26;;;;;;;;;;;;60827:33;;60612:256;;;;:::o;44668:185::-;44806:39;44823:4;44829:2;44833:7;44806:39;;;;;;;;;;;;:16;:39::i;:::-;44668:185;;;:::o;61134:233::-;61209:7;61245:30;:28;:30::i;:::-;61237:5;:38;61229:95;;;;;;;;;;;;:::i;:::-;;;;;;;;;61342:10;61353:5;61342:17;;;;;;;;:::i;:::-;;;;;;;;;;61335:24;;61134:233;;;:::o;76710:110::-;76760:7;76787:25;:15;:23;:25::i;:::-;76780:32;;76710:110;:::o;73606:209::-;76993:10;76982:21;;:7;:5;:7::i;:::-;:21;;;:53;;;;77007:16;:28;77024:10;77007:28;;;;;;;;;;;;;;;;;;;;;;;;;76982:53;76960:127;;;;;;;;;;;;:::i;:::-;;;;;;;;;73799:8:::1;73749:34;:47;73784:11;73749:47;;;;;;;;;;;;;;;:58;;;;73606:209:::0;;:::o;67735:87::-;67777:7;67804:10;67797:17;;67735:87;:::o;41760:223::-;41832:7;41852:13;41868:17;41877:7;41868:8;:17::i;:::-;41852:33;;41921:1;41904:19;;:5;:19;;;41896:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;41970:5;41963:12;;;41760:223;;;:::o;69932:1113::-;69985:7;70027:15;:27;70043:10;70027:27;;;;;;;;;;;;;;;;;;;;;;;;;70005:117;;;;;;;;;;;;:::i;:::-;;;;;;;;;70225:30;:44;70256:12;:10;:12::i;:::-;70225:44;;;;;;;;;;;;;;;;70157:34;:48;70192:12;:10;:12::i;:::-;70157:48;;;;;;;;;;;;;;;;:112;70135:192;;;;;;;;;;;;:::i;:::-;;;;;;;;;70381:23;:37;70405:12;:10;:12::i;:::-;70381:37;;;;;;;;;;;;;;;;70362:15;:56;;70340:143;;;;;;;;;;;;:::i;:::-;;;;;;;;;70496:15;70514:25;:15;:23;:25::i;:::-;70496:43;;70661:129;70668:16;70676:7;70668;:16::i;:::-;70661:129;;;70701:27;:15;:25;:27::i;:::-;70753:25;:15;:23;:25::i;:::-;70743:35;;70661:129;;;70802:27;:15;:25;:27::i;:::-;70840:32;70850:12;:10;:12::i;:::-;70864:7;70840:9;:32::i;:::-;70883:26;70896:7;70905:3;70883:12;:26::i;:::-;70920:34;:48;70955:12;:10;:12::i;:::-;70920:48;;;;;;;;;;;;;;;;:50;;;;;;;;;:::i;:::-;;;;;;70981:13;:27;70995:12;:10;:12::i;:::-;70981:27;;;;;;;;;;;;;;;;:29;;;;;;;;;:::i;:::-;;;;;;71030:7;71023:14;;;69932:1113;;;:::o;41491:207::-;41563:7;41608:1;41591:19;;:5;:19;;;41583:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;41674:9;:16;41684:5;41674:16;;;;;;;;;;;;;;;;41667:23;;41491:207;;;:::o;19473:103::-;18711:13;:11;:13::i;:::-;19538:30:::1;19565:1;19538:18;:30::i;:::-;19473:103::o:0;78514:159::-;77779:10;77768:21;;:7;:5;:7::i;:::-;:21;;;:56;;;;77793:19;:31;77813:10;77793:31;;;;;;;;;;;;;;;;;;;;;;;;;77768:56;77746:134;;;;;;;;;;;;:::i;:::-;;;;;;;;;78636:29:::1;78649:7;78658:6;78636:12;:29::i;:::-;78514:159:::0;;:::o;75838:199::-;76993:10;76982:21;;:7;:5;:7::i;:::-;:21;;;:53;;;;77007:16;:28;77024:10;77007:28;;;;;;;;;;;;;;;;;;;;;;;;;76982:53;76960:127;;;;;;;;;;;;:::i;:::-;;;;;;;;;76004:25:::1;76019:9;76004:14;:25::i;:::-;75965:23;:36;75989:11;75965:36;;;;;;;;;;;;;;;:64;;;;75838:199:::0;;:::o;77439:110::-;18711:13;:11;:13::i;:::-;77536:5:::1;77511:16;:22;77528:4;77511:22;;;;;;;;;;;;;;;;:30;;;;;;;;;;;;;;;;;;77439:110:::0;:::o;18825:87::-;18871:7;18898:6;;;;;;;;;;;18891:13;;18825:87;:::o;67830:978::-;67917:18;67950:19;67984:20;68019:41;68075:37;68127:30;68172:19;68206:22;68269:10;68256:23;;68307:15;:27;68323:10;68307:27;;;;;;;;;;;;;;;;;;;;;;;;;68290:44;;68360:13;:25;68374:10;68360:25;;;;;;;;;;;;;;;;68345:40;;68432:34;:70;68481:10;68432:70;;;;;;;;;;;;;;;;68396:106;;68545:30;:66;68590:10;68545:66;;;;;;;;;;;;;;;;68513:98;;68647:23;:35;68671:10;68647:35;;;;;;;;;;;;;;;;68622:60;;68710:16;:28;68727:10;68710:28;;;;;;;;;;;;;;;;;;;;;;;;;68693:45;;68769:19;:31;68789:10;68769:31;;;;;;;;;;;;;;;;;;;;;;;;;68749:51;;67830:978;;;;;;;;:::o;42219:104::-;42275:13;42308:7;42301:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42219:104;:::o;73980:201::-;76993:10;76982:21;;:7;:5;:7::i;:::-;:21;;;:53;;;;77007:16;:28;77024:10;77007:28;;;;;;;;;;;;;;;;;;;;;;;;;76982:53;76960:127;;;;;;;;;;;;:::i;:::-;;;;;;;;;74165:8:::1;74119:30;:43;74150:11;74119:43;;;;;;;;;;;;;;;:54;;;;73980:201:::0;;:::o;78022:112::-;18711:13;:11;:13::i;:::-;78122:4:::1;78094:19;:25;78114:4;78094:25;;;;;;;;;;;;;;;;:32;;;;;;;;;;;;;;;;;;78022:112:::0;:::o;43805:155::-;43900:52;43919:12;:10;:12::i;:::-;43933:8;43943;43900:18;:52::i;:::-;43805:155;;:::o;73352:154::-;18711:13;:11;:13::i;:::-;73493:5:::1;73464:13;:26;73478:11;73464:26;;;;;;;;;;;;;;;:34;;;;73352:154:::0;;:::o;72536:164::-;76993:10;76982:21;;:7;:5;:7::i;:::-;:21;;;:53;;;;77007:16;:28;77024:10;77007:28;;;;;;;;;;;;;;;;;;;;;;;;;76982:53;76960:127;;;;;;;;;;;;:::i;:::-;;;;;;;;;72685:7:::1;72654:15;:28;72670:11;72654:28;;;;;;;;;;;;;;;;:38;;;;;;;;;;;;;;;;;;72536:164:::0;;:::o;44924:322::-;45098:41;45117:12;:10;:12::i;:::-;45131:7;45098:18;:41::i;:::-;45090:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;45200:38;45214:4;45220:2;45224:7;45233:4;45200:13;:38::i;:::-;44924:322;;;;:::o;72845:126::-;76993:10;76982:21;;:7;:5;:7::i;:::-;:21;;;:53;;;;77007:16;:28;77024:10;77007:28;;;;;;;;;;;;;;;;;;;;;;;;;76982:53;76960:127;;;;;;;;;;;;:::i;:::-;;;;;;;;;72959:4:::1;72928:15;:28;72944:11;72928:28;;;;;;;;;;;;;;;;:35;;;;;;;;;;;;;;;;;;72845:126:::0;:::o;74422:199::-;76993:10;76982:21;;:7;:5;:7::i;:::-;:21;;;:53;;;;77007:16;:28;77024:10;77007:28;;;;;;;;;;;;;;;;;;;;;;;;;76982:53;76960:127;;;;;;;;;;;;:::i;:::-;;;;;;;;;74599:14:::1;74560:23;:36;74584:11;74560:36;;;;;;;;;;;;;;;:53;;;;74422:199:::0;;:::o;78252:116::-;18711:13;:11;:13::i;:::-;78355:5:::1;78327:19;:25;78347:4;78327:25;;;;;;;;;;;;;;;;:33;;;;;;;;;;;;;;;;;;78252:116:::0;:::o;78745:196::-;78872:13;78910:23;78925:7;78910:14;:23::i;:::-;78903:30;;78745:196;;;:::o;44031:164::-;44128:4;44152:18;:25;44171:5;44152:25;;;;;;;;;;;;;;;:35;44178:8;44152:35;;;;;;;;;;;;;;;;;;;;;;;;;44145:42;;44031:164;;;;:::o;74839:293::-;74954:7;76993:10;76982:21;;:7;:5;:7::i;:::-;:21;;;:53;;;;77007:16;:28;77024:10;77007:28;;;;;;;;;;;;;;;;;;;;;;;;;76982:53;76960:127;;;;;;;;;;;;:::i;:::-;;;;;;;;;74979:21:::1;75003:12;74979:36;;75026:20;75080:13;75068:9;:25;;;;:::i;:::-;75049:15;:45;;;;:::i;:::-;75026:68;;75112:12;75105:19;;;;74839:293:::0;;;:::o;76608:94::-;18711:13;:11;:13::i;:::-;76667:27:::1;:15;:25;:27::i;:::-;76608:94::o:0;19731:201::-;18711:13;:11;:13::i;:::-;19840:1:::1;19820:22;;:8;:22;;::::0;19812:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;19896:28;19915:8;19896:18;:28::i;:::-;19731:201:::0;:::o;68816:1021::-;68944:15;68974:19;69008:20;69043:41;69099:37;69151:30;69196:19;69230:22;76993:10;76982:21;;:7;:5;:7::i;:::-;:21;;;:53;;;;77007:16;:28;77024:10;77007:28;;;;;;;;;;;;;;;;;;;;;;;;;76982:53;76960:127;;;;;;;;;;;;:::i;:::-;;;;;;;;;69290:11:::1;69280:21;;69329:15;:28;69345:11;69329:28;;;;;;;;;;;;;;;;;;;;;;;;;69312:45;;69383:13;:26;69397:11;69383:26;;;;;;;;;;;;;;;;69368:41;;69456:34;:71;69505:11;69456:71;;;;;;;;;;;;;;;;69420:107;;69570:30;:67;69615:11;69570:67;;;;;;;;;;;;;;;;69538:99;;69673:23;:36;69697:11;69673:36;;;;;;;;;;;;;;;;69648:61;;69737:16;:29;69754:11;69737:29;;;;;;;;;;;;;;;;;;;;;;;;;69720:46;;69797:19;:32;69817:11;69797:32;;;;;;;;;;;;;;;;;;;;;;;;;69777:52;;68816:1021:::0;;;;;;;;;:::o;60304:224::-;60406:4;60445:35;60430:50;;;:11;:50;;;;:90;;;;60484:36;60508:11;60484:23;:36::i;:::-;60430:90;60423:97;;60304:224;;;:::o;53381:135::-;53463:16;53471:7;53463;:16::i;:::-;53455:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;53381:135;:::o;17376:98::-;17429:7;17456:10;17449:17;;17376:98;:::o;52660:174::-;52762:2;52735:15;:24;52751:7;52735:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;52818:7;52814:2;52780:46;;52789:23;52804:7;52789:14;:23::i;:::-;52780:46;;;;;;;;;;;;52660:174;;:::o;905:114::-;970:7;997;:14;;;990:21;;905:114;;;:::o;46984:128::-;47049:4;47102:1;47073:31;;:17;47082:7;47073:8;:17::i;:::-;:31;;;;47066:38;;46984:128;;;:::o;1027:127::-;1134:1;1116:7;:14;;;:19;;;;;;;;;;;1027:127;:::o;47885:110::-;47961:26;47971:2;47975:7;47961:26;;;;;;;;;;;;:9;:26::i;:::-;47885:110;;:::o;58623:217::-;58723:16;58731:7;58723;:16::i;:::-;58715:75;;;;;;;;;;;;:::i;:::-;;;;;;;;;58823:9;58801:10;:19;58812:7;58801:19;;;;;;;;;;;:31;;;;;;:::i;:::-;;58623:217;;:::o;18990:132::-;19065:12;:10;:12::i;:::-;19054:23;;:7;:5;:7::i;:::-;:23;;;19046:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;18990:132::o;47279:264::-;47372:4;47389:13;47405:23;47420:7;47405:14;:23::i;:::-;47389:39;;47458:5;47447:16;;:7;:16;;;:52;;;;47467:32;47484:5;47491:7;47467:16;:32::i;:::-;47447:52;:87;;;;47527:7;47503:31;;:20;47515:7;47503:11;:20::i;:::-;:31;;;47447:87;47439:96;;;47279:264;;;;:::o;51278:1263::-;51437:4;51410:31;;:23;51425:7;51410:14;:23::i;:::-;:31;;;51402:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;51516:1;51502:16;;:2;:16;;;51494:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;51572:42;51593:4;51599:2;51603:7;51612:1;51572:20;:42::i;:::-;51744:4;51717:31;;:23;51732:7;51717:14;:23::i;:::-;:31;;;51709:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;51862:15;:24;51878:7;51862:24;;;;;;;;;;;;51855:31;;;;;;;;;;;52357:1;52338:9;:15;52348:4;52338:15;;;;;;;;;;;;;;;;:20;;;;;;;;;;;52390:1;52373:9;:13;52383:2;52373:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;52432:2;52413:7;:16;52421:7;52413:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;52471:7;52467:2;52452:27;;52461:4;52452:27;;;;;;;;;;;;52492:41;52512:4;52518:2;52522:7;52531:1;52492:19;:41::i;:::-;51278:1263;;;:::o;46554:117::-;46620:7;46647;:16;46655:7;46647:16;;;;;;;;;;;;;;;;;;;;;46640:23;;46554:117;;;:::o;20092:191::-;20166:16;20185:6;;;;;;;;;;;20166:25;;20211:8;20202:6;;:17;;;;;;;;;;;;;;;;;;20266:8;20235:40;;20256:8;20235:40;;;;;;;;;;;;20155:128;20092:191;:::o;52977:315::-;53132:8;53123:17;;:5;:17;;;53115:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;53219:8;53181:18;:25;53200:5;53181:25;;;;;;;;;;;;;;;:35;53207:8;53181:35;;;;;;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;53265:8;53243:41;;53258:5;53243:41;;;53275:8;53243:41;;;;;;:::i;:::-;;;;;;;;52977:315;;;:::o;46127:313::-;46283:28;46293:4;46299:2;46303:7;46283:9;:28::i;:::-;46330:47;46353:4;46359:2;46363:7;46372:4;46330:22;:47::i;:::-;46322:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;46127:313;;;;:::o;57843:624::-;57916:13;57942:23;57957:7;57942:14;:23::i;:::-;57978;58004:10;:19;58015:7;58004:19;;;;;;;;;;;57978:45;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58034:18;58055:10;:8;:10::i;:::-;58034:31;;58163:1;58147:4;58141:18;:23;58137:72;;58188:9;58181:16;;;;;;58137:72;58339:1;58319:9;58313:23;:27;58309:108;;;58388:4;58394:9;58371:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;58357:48;;;;;;58309:108;58436:23;58451:7;58436:14;:23::i;:::-;58429:30;;;;57843:624;;;;:::o;1162:235::-;1226:13;1242:7;:14;;;1226:30;;1283:1;1275:5;:9;1267:49;;;;;;;;;;;;:::i;:::-;;;;;;;;;1377:1;1369:5;:9;1352:7;:14;;:26;;;;1215:182;1162:235;:::o;41122:305::-;41224:4;41276:25;41261:40;;;:11;:40;;;;:105;;;;41333:33;41318:48;;;:11;:48;;;;41261:105;:158;;;;41383:36;41407:11;41383:23;:36::i;:::-;41261:158;41241:178;;41122:305;;;:::o;48222:319::-;48351:18;48357:2;48361:7;48351:5;:18::i;:::-;48402:53;48433:1;48437:2;48441:7;48450:4;48402:22;:53::i;:::-;48380:153;;;;;;;;;;;;:::i;:::-;;;;;;;;;48222:319;;;:::o;79264:254::-;79454:56;79481:4;79487:2;79491:7;79500:9;79454:26;:56::i;:::-;79264:254;;;;:::o;56546:158::-;;;;;:::o;54080:853::-;54234:4;54255:15;:2;:13;;;:15::i;:::-;54251:675;;;54307:2;54291:36;;;54328:12;:10;:12::i;:::-;54342:4;54348:7;54357:4;54291:71;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;54287:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54549:1;54532:6;:13;:18;54528:328;;54575:60;;;;;;;;;;:::i;:::-;;;;;;;;54528:328;54806:6;54800:13;54791:6;54787:2;54783:15;54776:38;54287:584;54423:41;;;54413:51;;;:6;:51;;;;54406:58;;;;;54251:675;54910:4;54903:11;;54080:853;;;;;;;:::o;42924:94::-;42975:13;43001:9;;;;;;;;;;;;;;42924:94;:::o;42394:281::-;42467:13;42493:23;42508:7;42493:14;:23::i;:::-;42529:21;42553:10;:8;:10::i;:::-;42529:34;;42605:1;42587:7;42581:21;:25;:86;;;;;;;;;;;;;;;;;42633:7;42642:18;:7;:16;:18::i;:::-;42616:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;42581:86;42574:93;;;42394:281;;;:::o;32554:157::-;32639:4;32678:25;32663:40;;;:11;:40;;;;32656:47;;32554:157;;;:::o;48877:942::-;48971:1;48957:16;;:2;:16;;;48949:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;49030:16;49038:7;49030;:16::i;:::-;49029:17;49021:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;49092:48;49121:1;49125:2;49129:7;49138:1;49092:20;:48::i;:::-;49239:16;49247:7;49239;:16::i;:::-;49238:17;49230:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;49654:1;49637:9;:13;49647:2;49637:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;49698:2;49679:7;:16;49687:7;49679:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;49743:7;49739:2;49718:33;;49735:1;49718:33;;;;;;;;;;;;49764:47;49792:1;49796:2;49800:7;49809:1;49764:19;:47::i;:::-;48877:942;;:::o;61441:915::-;61618:61;61645:4;61651:2;61655:12;61669:9;61618:26;:61::i;:::-;61708:1;61696:9;:13;61692:222;;;61839:63;;;;;;;;;;:::i;:::-;;;;;;;;61692:222;61926:15;61944:12;61926:30;;61989:1;61973:18;;:4;:18;;;61969:187;;62008:40;62040:7;62008:31;:40::i;:::-;61969:187;;;62078:2;62070:10;;:4;:10;;;62066:90;;62097:47;62130:4;62136:7;62097:32;:47::i;:::-;62066:90;61969:187;62184:1;62170:16;;:2;:16;;;62166:183;;62203:45;62240:7;62203:36;:45::i;:::-;62166:183;;;62276:4;62270:10;;:2;:10;;;62266:83;;62297:40;62325:2;62329:7;62297:27;:40::i;:::-;62266:83;62166:183;61607:749;61441:915;;;;:::o;21523:326::-;21583:4;21840:1;21818:7;:19;;;:23;21811:30;;21523:326;;;:::o;14803:716::-;14859:13;14910:14;14947:1;14927:17;14938:5;14927:10;:17::i;:::-;:21;14910:38;;14963:20;14997:6;14986:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14963:41;;15019:11;15148:6;15144:2;15140:15;15132:6;15128:28;15121:35;;15185:288;15192:4;15185:288;;;15217:5;;;;;;;;15359:8;15354:2;15347:5;15343:14;15338:30;15333:3;15325:44;15415:2;15406:11;;;;;;:::i;:::-;;;;;15449:1;15440:5;:10;15185:288;15436:21;15185:288;15494:6;15487:13;;;;;14803:716;;;:::o;55665:159::-;;;;;:::o;63079:164::-;63183:10;:17;;;;63156:15;:24;63172:7;63156:24;;;;;;;;;;;:44;;;;63211:10;63227:7;63211:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63079:164;:::o;63870:988::-;64136:22;64186:1;64161:22;64178:4;64161:16;:22::i;:::-;:26;;;;:::i;:::-;64136:51;;64198:18;64219:17;:26;64237:7;64219:26;;;;;;;;;;;;64198:47;;64366:14;64352:10;:28;64348:328;;64397:19;64419:12;:18;64432:4;64419:18;;;;;;;;;;;;;;;:34;64438:14;64419:34;;;;;;;;;;;;64397:56;;64503:11;64470:12;:18;64483:4;64470:18;;;;;;;;;;;;;;;:30;64489:10;64470:30;;;;;;;;;;;:44;;;;64620:10;64587:17;:30;64605:11;64587:30;;;;;;;;;;;:43;;;;64382:294;64348:328;64772:17;:26;64790:7;64772:26;;;;;;;;;;;64765:33;;;64816:12;:18;64829:4;64816:18;;;;;;;;;;;;;;;:34;64835:14;64816:34;;;;;;;;;;;64809:41;;;63951:907;;63870:988;;:::o;65153:1079::-;65406:22;65451:1;65431:10;:17;;;;:21;;;;:::i;:::-;65406:46;;65463:18;65484:15;:24;65500:7;65484:24;;;;;;;;;;;;65463:45;;65835:19;65857:10;65868:14;65857:26;;;;;;;;:::i;:::-;;;;;;;;;;65835:48;;65921:11;65896:10;65907;65896:22;;;;;;;;:::i;:::-;;;;;;;;;:36;;;;66032:10;66001:15;:28;66017:11;66001:28;;;;;;;;;;;:41;;;;66173:15;:24;66189:7;66173:24;;;;;;;;;;;66166:31;;;66208:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;65224:1008;;;65153:1079;:::o;62657:221::-;62742:14;62759:20;62776:2;62759:16;:20::i;:::-;62742:37;;62817:7;62790:12;:16;62803:2;62790:16;;;;;;;;;;;;;;;:24;62807:6;62790:24;;;;;;;;;;;:34;;;;62864:6;62835:17;:26;62853:7;62835:26;;;;;;;;;;;:35;;;;62731:147;62657:221;;:::o;11669:922::-;11722:7;11742:14;11759:1;11742:18;;11809:6;11800:5;:15;11796:102;;11845:6;11836:15;;;;;;:::i;:::-;;;;;11880:2;11870:12;;;;11796:102;11925:6;11916:5;:15;11912:102;;11961:6;11952:15;;;;;;:::i;:::-;;;;;11996:2;11986:12;;;;11912:102;12041:6;12032:5;:15;12028:102;;12077:6;12068:15;;;;;;:::i;:::-;;;;;12112:2;12102:12;;;;12028:102;12157:5;12148;:14;12144:99;;12192:5;12183:14;;;;;;:::i;:::-;;;;;12226:1;12216:11;;;;12144:99;12270:5;12261;:14;12257:99;;12305:5;12296:14;;;;;;:::i;:::-;;;;;12339:1;12329:11;;;;12257:99;12383:5;12374;:14;12370:99;;12418:5;12409:14;;;;;;:::i;:::-;;;;;12452:1;12442:11;;;;12370:99;12496:5;12487;:14;12483:66;;12532:1;12522:11;;;;12483:66;12577:6;12570:13;;;11669:922;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:126::-;1555:7;1595:42;1588:5;1584:54;1573:65;;1518:126;;;:::o;1650:96::-;1687:7;1716:24;1734:5;1716:24;:::i;:::-;1705:35;;1650:96;;;:::o;1752:122::-;1825:24;1843:5;1825:24;:::i;:::-;1818:5;1815:35;1805:63;;1864:1;1861;1854:12;1805:63;1752:122;:::o;1880:139::-;1926:5;1964:6;1951:20;1942:29;;1980:33;2007:5;1980:33;:::i;:::-;1880:139;;;;:::o;2025:329::-;2084:6;2133:2;2121:9;2112:7;2108:23;2104:32;2101:119;;;2139:79;;:::i;:::-;2101:119;2259:1;2284:53;2329:7;2320:6;2309:9;2305:22;2284:53;:::i;:::-;2274:63;;2230:117;2025:329;;;;:::o;2360:99::-;2412:6;2446:5;2440:12;2430:22;;2360:99;;;:::o;2465:169::-;2549:11;2583:6;2578:3;2571:19;2623:4;2618:3;2614:14;2599:29;;2465:169;;;;:::o;2640:246::-;2721:1;2731:113;2745:6;2742:1;2739:13;2731:113;;;2830:1;2825:3;2821:11;2815:18;2811:1;2806:3;2802:11;2795:39;2767:2;2764:1;2760:10;2755:15;;2731:113;;;2878:1;2869:6;2864:3;2860:16;2853:27;2702:184;2640:246;;;:::o;2892:102::-;2933:6;2984:2;2980:7;2975:2;2968:5;2964:14;2960:28;2950:38;;2892:102;;;:::o;3000:377::-;3088:3;3116:39;3149:5;3116:39;:::i;:::-;3171:71;3235:6;3230:3;3171:71;:::i;:::-;3164:78;;3251:65;3309:6;3304:3;3297:4;3290:5;3286:16;3251:65;:::i;:::-;3341:29;3363:6;3341:29;:::i;:::-;3336:3;3332:39;3325:46;;3092:285;3000:377;;;;:::o;3383:313::-;3496:4;3534:2;3523:9;3519:18;3511:26;;3583:9;3577:4;3573:20;3569:1;3558:9;3554:17;3547:47;3611:78;3684:4;3675:6;3611:78;:::i;:::-;3603:86;;3383:313;;;;:::o;3702:77::-;3739:7;3768:5;3757:16;;3702:77;;;:::o;3785:122::-;3858:24;3876:5;3858:24;:::i;:::-;3851:5;3848:35;3838:63;;3897:1;3894;3887:12;3838:63;3785:122;:::o;3913:139::-;3959:5;3997:6;3984:20;3975:29;;4013:33;4040:5;4013:33;:::i;:::-;3913:139;;;;:::o;4058:329::-;4117:6;4166:2;4154:9;4145:7;4141:23;4137:32;4134:119;;;4172:79;;:::i;:::-;4134:119;4292:1;4317:53;4362:7;4353:6;4342:9;4338:22;4317:53;:::i;:::-;4307:63;;4263:117;4058:329;;;;:::o;4393:118::-;4480:24;4498:5;4480:24;:::i;:::-;4475:3;4468:37;4393:118;;:::o;4517:222::-;4610:4;4648:2;4637:9;4633:18;4625:26;;4661:71;4729:1;4718:9;4714:17;4705:6;4661:71;:::i;:::-;4517:222;;;;:::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:116::-;5295:21;5310:5;5295:21;:::i;:::-;5288:5;5285:32;5275:60;;5331:1;5328;5321:12;5275:60;5225:116;:::o;5347:133::-;5390:5;5428:6;5415:20;5406:29;;5444:30;5468:5;5444:30;:::i;:::-;5347:133;;;;:::o;5486:759::-;5569:6;5577;5585;5593;5642:3;5630:9;5621:7;5617:23;5613:33;5610:120;;;5649:79;;:::i;:::-;5610:120;5769:1;5794:53;5839:7;5830:6;5819:9;5815:22;5794:53;:::i;:::-;5784:63;;5740:117;5896:2;5922:50;5964:7;5955:6;5944:9;5940:22;5922:50;:::i;:::-;5912:60;;5867:115;6021:2;6047:53;6092:7;6083:6;6072:9;6068:22;6047:53;:::i;:::-;6037:63;;5992:118;6149:2;6175:53;6220:7;6211:6;6200:9;6196:22;6175:53;:::i;:::-;6165:63;;6120:118;5486:759;;;;;;;:::o;6251:117::-;6360:1;6357;6350:12;6374:180;6422:77;6419:1;6412:88;6519:4;6516:1;6509:15;6543:4;6540:1;6533:15;6560:281;6643:27;6665:4;6643:27;:::i;:::-;6635:6;6631:40;6773:6;6761:10;6758:22;6737:18;6725:10;6722:34;6719:62;6716:88;;;6784:18;;:::i;:::-;6716:88;6824:10;6820:2;6813:22;6603:238;6560:281;;:::o;6847:129::-;6881:6;6908:20;;:::i;:::-;6898:30;;6937:33;6965:4;6957:6;6937:33;:::i;:::-;6847:129;;;:::o;6982:321::-;7069:4;7159:18;7151:6;7148:30;7145:56;;;7181:18;;:::i;:::-;7145:56;7231:4;7223:6;7219:17;7211:25;;7291:4;7285;7281:15;7273:23;;6982:321;;;:::o;7309:117::-;7418:1;7415;7408:12;7432:117;7541:1;7538;7531:12;7555:308;7617:4;7707:18;7699:6;7696:30;7693:56;;;7729:18;;:::i;:::-;7693:56;7767:29;7789:6;7767:29;:::i;:::-;7759:37;;7851:4;7845;7841:15;7833:23;;7555:308;;;:::o;7869:146::-;7966:6;7961:3;7956;7943:30;8007:1;7998:6;7993:3;7989:16;7982:27;7869:146;;;:::o;8021:425::-;8099:5;8124:66;8140:49;8182:6;8140:49;:::i;:::-;8124:66;:::i;:::-;8115:75;;8213:6;8206:5;8199:21;8251:4;8244:5;8240:16;8289:3;8280:6;8275:3;8271:16;8268:25;8265:112;;;8296:79;;:::i;:::-;8265:112;8386:54;8433:6;8428:3;8423;8386:54;:::i;:::-;8105:341;8021:425;;;;;:::o;8466:340::-;8522:5;8571:3;8564:4;8556:6;8552:17;8548:27;8538:122;;8579:79;;:::i;:::-;8538:122;8696:6;8683:20;8721:79;8796:3;8788:6;8781:4;8773:6;8769:17;8721:79;:::i;:::-;8712:88;;8528:278;8466:340;;;;:::o;8828:945::-;8934:5;8959:91;8975:74;9042:6;8975:74;:::i;:::-;8959:91;:::i;:::-;8950:100;;9070:5;9099:6;9092:5;9085:21;9133:4;9126:5;9122:16;9115:23;;9186:4;9178:6;9174:17;9166:6;9162:30;9215:3;9207:6;9204:15;9201:122;;;9234:79;;:::i;:::-;9201:122;9349:6;9332:435;9366:6;9361:3;9358:15;9332:435;;;9455:3;9442:17;9491:18;9478:11;9475:35;9472:122;;;9513:79;;:::i;:::-;9472:122;9637:11;9629:6;9625:24;9675:47;9718:3;9706:10;9675:47;:::i;:::-;9670:3;9663:60;9752:4;9747:3;9743:14;9736:21;;9408:359;;9392:4;9387:3;9383:14;9376:21;;9332:435;;;9336:21;8940:833;;8828:945;;;;;:::o;9795:390::-;9876:5;9925:3;9918:4;9910:6;9906:17;9902:27;9892:122;;9933:79;;:::i;:::-;9892:122;10050:6;10037:20;10075:104;10175:3;10167:6;10160:4;10152:6;10148:17;10075:104;:::i;:::-;10066:113;;9882:303;9795:390;;;;:::o;10191:559::-;10285:6;10334:2;10322:9;10313:7;10309:23;10305:32;10302:119;;;10340:79;;:::i;:::-;10302:119;10488:1;10477:9;10473:17;10460:31;10518:18;10510:6;10507:30;10504:117;;;10540:79;;:::i;:::-;10504:117;10645:88;10725:7;10716:6;10705:9;10701:22;10645:88;:::i;:::-;10635:98;;10431:312;10191:559;;;;:::o;10756:114::-;10823:6;10857:5;10851:12;10841:22;;10756:114;;;:::o;10876:184::-;10975:11;11009:6;11004:3;10997:19;11049:4;11044:3;11040:14;11025:29;;10876:184;;;;:::o;11066:132::-;11133:4;11156:3;11148:11;;11186:4;11181:3;11177:14;11169:22;;11066:132;;;:::o;11204:108::-;11281:24;11299:5;11281:24;:::i;:::-;11276:3;11269:37;11204:108;;:::o;11318:179::-;11387:10;11408:46;11450:3;11442:6;11408:46;:::i;:::-;11486:4;11481:3;11477:14;11463:28;;11318:179;;;;:::o;11503:113::-;11573:4;11605;11600:3;11596:14;11588:22;;11503:113;;;:::o;11652:732::-;11771:3;11800:54;11848:5;11800:54;:::i;:::-;11870:86;11949:6;11944:3;11870:86;:::i;:::-;11863:93;;11980:56;12030:5;11980:56;:::i;:::-;12059:7;12090:1;12075:284;12100:6;12097:1;12094:13;12075:284;;;12176:6;12170:13;12203:63;12262:3;12247:13;12203:63;:::i;:::-;12196:70;;12289:60;12342:6;12289:60;:::i;:::-;12279:70;;12135:224;12122:1;12119;12115:9;12110:14;;12075:284;;;12079:14;12375:3;12368:10;;11776:608;;;11652:732;;;;:::o;12390:373::-;12533:4;12571:2;12560:9;12556:18;12548:26;;12620:9;12614:4;12610:20;12606:1;12595:9;12591:17;12584:47;12648:108;12751:4;12742:6;12648:108;:::i;:::-;12640:116;;12390:373;;;;:::o;12769:118::-;12856:24;12874:5;12856:24;:::i;:::-;12851:3;12844:37;12769:118;;:::o;12893:222::-;12986:4;13024:2;13013:9;13009:18;13001:26;;13037:71;13105:1;13094:9;13090:17;13081:6;13037:71;:::i;:::-;12893:222;;;;:::o;13121:619::-;13198:6;13206;13214;13263:2;13251:9;13242:7;13238:23;13234:32;13231:119;;;13269:79;;:::i;:::-;13231:119;13389:1;13414:53;13459:7;13450:6;13439:9;13435:22;13414:53;:::i;:::-;13404:63;;13360:117;13516:2;13542:53;13587:7;13578:6;13567:9;13563:22;13542:53;:::i;:::-;13532:63;;13487:118;13644:2;13670:53;13715:7;13706:6;13695:9;13691:22;13670:53;:::i;:::-;13660:63;;13615:118;13121:619;;;;;:::o;13746:509::-;13815:6;13864:2;13852:9;13843:7;13839:23;13835:32;13832:119;;;13870:79;;:::i;:::-;13832:119;14018:1;14007:9;14003:17;13990:31;14048:18;14040:6;14037:30;14034:117;;;14070:79;;:::i;:::-;14034:117;14175:63;14230:7;14221:6;14210:9;14206:22;14175:63;:::i;:::-;14165:73;;13961:287;13746:509;;;;:::o;14261:654::-;14339:6;14347;14396:2;14384:9;14375:7;14371:23;14367:32;14364:119;;;14402:79;;:::i;:::-;14364:119;14522:1;14547:53;14592:7;14583:6;14572:9;14568:22;14547:53;:::i;:::-;14537:63;;14493:117;14677:2;14666:9;14662:18;14649:32;14708:18;14700:6;14697:30;14694:117;;;14730:79;;:::i;:::-;14694:117;14835:63;14890:7;14881:6;14870:9;14866:22;14835:63;:::i;:::-;14825:73;;14620:288;14261:654;;;;;:::o;14921:961::-;15192:4;15230:3;15219:9;15215:19;15207:27;;15244:71;15312:1;15301:9;15297:17;15288:6;15244:71;:::i;:::-;15325:66;15387:2;15376:9;15372:18;15363:6;15325:66;:::i;:::-;15401:72;15469:2;15458:9;15454:18;15445:6;15401:72;:::i;:::-;15483;15551:2;15540:9;15536:18;15527:6;15483:72;:::i;:::-;15565:73;15633:3;15622:9;15618:19;15609:6;15565:73;:::i;:::-;15648;15716:3;15705:9;15701:19;15692:6;15648:73;:::i;:::-;15731:67;15793:3;15782:9;15778:19;15769:6;15731:67;:::i;:::-;15808;15870:3;15859:9;15855:19;15846:6;15808:67;:::i;:::-;14921:961;;;;;;;;;;;:::o;15888:468::-;15953:6;15961;16010:2;15998:9;15989:7;15985:23;15981:32;15978:119;;;16016:79;;:::i;:::-;15978:119;16136:1;16161:53;16206:7;16197:6;16186:9;16182:22;16161:53;:::i;:::-;16151:63;;16107:117;16263:2;16289:50;16331:7;16322:6;16311:9;16307:22;16289:50;:::i;:::-;16279:60;;16234:115;15888:468;;;;;:::o;16362:307::-;16423:4;16513:18;16505:6;16502:30;16499:56;;;16535:18;;:::i;:::-;16499:56;16573:29;16595:6;16573:29;:::i;:::-;16565:37;;16657:4;16651;16647:15;16639:23;;16362:307;;;:::o;16675:423::-;16752:5;16777:65;16793:48;16834:6;16793:48;:::i;:::-;16777:65;:::i;:::-;16768:74;;16865:6;16858:5;16851:21;16903:4;16896:5;16892:16;16941:3;16932:6;16927:3;16923:16;16920:25;16917:112;;;16948:79;;:::i;:::-;16917:112;17038:54;17085:6;17080:3;17075;17038:54;:::i;:::-;16758:340;16675:423;;;;;:::o;17117:338::-;17172:5;17221:3;17214:4;17206:6;17202:17;17198:27;17188:122;;17229:79;;:::i;:::-;17188:122;17346:6;17333:20;17371:78;17445:3;17437:6;17430:4;17422:6;17418:17;17371:78;:::i;:::-;17362:87;;17178:277;17117:338;;;;:::o;17461:943::-;17556:6;17564;17572;17580;17629:3;17617:9;17608:7;17604:23;17600:33;17597:120;;;17636:79;;:::i;:::-;17597:120;17756:1;17781:53;17826:7;17817:6;17806:9;17802:22;17781:53;:::i;:::-;17771:63;;17727:117;17883:2;17909:53;17954:7;17945:6;17934:9;17930:22;17909:53;:::i;:::-;17899:63;;17854:118;18011:2;18037:53;18082:7;18073:6;18062:9;18058:22;18037:53;:::i;:::-;18027:63;;17982:118;18167:2;18156:9;18152:18;18139:32;18198:18;18190:6;18187:30;18184:117;;;18220:79;;:::i;:::-;18184:117;18325:62;18379:7;18370:6;18359:9;18355:22;18325:62;:::i;:::-;18315:72;;18110:287;17461:943;;;;;;;:::o;18410:474::-;18478:6;18486;18535:2;18523:9;18514:7;18510:23;18506:32;18503:119;;;18541:79;;:::i;:::-;18503:119;18661:1;18686:53;18731:7;18722:6;18711:9;18707:22;18686:53;:::i;:::-;18676:63;;18632:117;18788:2;18814:53;18859:7;18850:6;18839:9;18835:22;18814:53;:::i;:::-;18804:63;;18759:118;18410:474;;;;;:::o;18890:174::-;19030:26;19026:1;19018:6;19014:14;19007:50;18890:174;:::o;19070:366::-;19212:3;19233:67;19297:2;19292:3;19233:67;:::i;:::-;19226:74;;19309:93;19398:3;19309:93;:::i;:::-;19427:2;19422:3;19418:12;19411:19;;19070:366;;;:::o;19442:419::-;19608:4;19646:2;19635:9;19631:18;19623:26;;19695:9;19689:4;19685:20;19681:1;19670:9;19666:17;19659:47;19723:131;19849:4;19723:131;:::i;:::-;19715:139;;19442:419;;;:::o;19867:180::-;19915:77;19912:1;19905:88;20012:4;20009:1;20002:15;20036:4;20033:1;20026:15;20053:320;20097:6;20134:1;20128:4;20124:12;20114:22;;20181:1;20175:4;20171:12;20202:18;20192:81;;20258:4;20250:6;20246:17;20236:27;;20192:81;20320:2;20312:6;20309:14;20289:18;20286:38;20283:84;;20339:18;;:::i;:::-;20283:84;20104:269;20053:320;;;:::o;20379:220::-;20519:34;20515:1;20507:6;20503:14;20496:58;20588:3;20583:2;20575:6;20571:15;20564:28;20379:220;:::o;20605:366::-;20747:3;20768:67;20832:2;20827:3;20768:67;:::i;:::-;20761:74;;20844:93;20933:3;20844:93;:::i;:::-;20962:2;20957:3;20953:12;20946:19;;20605:366;;;:::o;20977:419::-;21143:4;21181:2;21170:9;21166:18;21158:26;;21230:9;21224:4;21220:20;21216:1;21205:9;21201:17;21194:47;21258:131;21384:4;21258:131;:::i;:::-;21250:139;;20977:419;;;:::o;21402:248::-;21542:34;21538:1;21530:6;21526:14;21519:58;21611:31;21606:2;21598:6;21594:15;21587:56;21402:248;:::o;21656:366::-;21798:3;21819:67;21883:2;21878:3;21819:67;:::i;:::-;21812:74;;21895:93;21984:3;21895:93;:::i;:::-;22013:2;22008:3;22004:12;21997:19;;21656:366;;;:::o;22028:419::-;22194:4;22232:2;22221:9;22217:18;22209:26;;22281:9;22275:4;22271:20;22267:1;22256:9;22252:17;22245:47;22309:131;22435:4;22309:131;:::i;:::-;22301:139;;22028:419;;;:::o;22453:227::-;22593:34;22589:1;22581:6;22577:14;22570:58;22662:10;22657:2;22649:6;22645:15;22638:35;22453:227;:::o;22686:366::-;22828:3;22849:67;22913:2;22908:3;22849:67;:::i;:::-;22842:74;;22925:93;23014:3;22925:93;:::i;:::-;23043:2;23038:3;23034:12;23027:19;;22686:366;;;:::o;23058:419::-;23224:4;23262:2;23251:9;23247:18;23239:26;;23311:9;23305:4;23301:20;23297:1;23286:9;23282:17;23275:47;23339:131;23465:4;23339:131;:::i;:::-;23331:139;;23058:419;;;:::o;23483:180::-;23531:77;23528:1;23521:88;23628:4;23625:1;23618:15;23652:4;23649:1;23642:15;23669:191;23709:3;23728:20;23746:1;23728:20;:::i;:::-;23723:25;;23762:20;23780:1;23762:20;:::i;:::-;23757:25;;23805:1;23802;23798:9;23791:16;;23826:3;23823:1;23820:10;23817:36;;;23833:18;;:::i;:::-;23817:36;23669:191;;;;:::o;23866:180::-;24006:32;24002:1;23994:6;23990:14;23983:56;23866:180;:::o;24052:366::-;24194:3;24215:67;24279:2;24274:3;24215:67;:::i;:::-;24208:74;;24291:93;24380:3;24291:93;:::i;:::-;24409:2;24404:3;24400:12;24393:19;;24052:366;;;:::o;24424:419::-;24590:4;24628:2;24617:9;24613:18;24605:26;;24677:9;24671:4;24667:20;24663:1;24652:9;24648:17;24641:47;24705:131;24831:4;24705:131;:::i;:::-;24697:139;;24424:419;;;:::o;24849:224::-;24989:34;24985:1;24977:6;24973:14;24966:58;25058:7;25053:2;25045:6;25041:15;25034:32;24849:224;:::o;25079:366::-;25221:3;25242:67;25306:2;25301:3;25242:67;:::i;:::-;25235:74;;25318:93;25407:3;25318:93;:::i;:::-;25436:2;25431:3;25427:12;25420:19;;25079:366;;;:::o;25451:419::-;25617:4;25655:2;25644:9;25640:18;25632:26;;25704:9;25698:4;25694:20;25690:1;25679:9;25675:17;25668:47;25732:131;25858:4;25732:131;:::i;:::-;25724:139;;25451:419;;;:::o;25876:180::-;25924:77;25921:1;25914:88;26021:4;26018:1;26011:15;26045:4;26042:1;26035:15;26062:233;26101:3;26124:24;26142:5;26124:24;:::i;:::-;26115:33;;26170:66;26163:5;26160:77;26157:103;;26240:18;;:::i;:::-;26157:103;26287:1;26280:5;26276:13;26269:20;;26062:233;;;:::o;26301:232::-;26441:34;26437:1;26429:6;26425:14;26418:58;26510:15;26505:2;26497:6;26493:15;26486:40;26301:232;:::o;26539:366::-;26681:3;26702:67;26766:2;26761:3;26702:67;:::i;:::-;26695:74;;26778:93;26867:3;26778:93;:::i;:::-;26896:2;26891:3;26887:12;26880:19;;26539:366;;;:::o;26911:419::-;27077:4;27115:2;27104:9;27100:18;27092:26;;27164:9;27158:4;27154:20;27150:1;27139:9;27135:17;27128:47;27192:131;27318:4;27192:131;:::i;:::-;27184:139;;26911:419;;;:::o;27336:230::-;27476:34;27472:1;27464:6;27460:14;27453:58;27545:13;27540:2;27532:6;27528:15;27521:38;27336:230;:::o;27572:366::-;27714:3;27735:67;27799:2;27794:3;27735:67;:::i;:::-;27728:74;;27811:93;27900:3;27811:93;:::i;:::-;27929:2;27924:3;27920:12;27913:19;;27572:366;;;:::o;27944:419::-;28110:4;28148:2;28137:9;28133:18;28125:26;;28197:9;28191:4;28187:20;28183:1;28172:9;28168:17;28161:47;28225:131;28351:4;28225:131;:::i;:::-;28217:139;;27944:419;;;:::o;28369:231::-;28509:34;28505:1;28497:6;28493:14;28486:58;28578:14;28573:2;28565:6;28561:15;28554:39;28369:231;:::o;28606:366::-;28748:3;28769:67;28833:2;28828:3;28769:67;:::i;:::-;28762:74;;28845:93;28934:3;28845:93;:::i;:::-;28963:2;28958:3;28954:12;28947:19;;28606:366;;;:::o;28978:419::-;29144:4;29182:2;29171:9;29167:18;29159:26;;29231:9;29225:4;29221:20;29217:1;29206:9;29202:17;29195:47;29259:131;29385:4;29259:131;:::i;:::-;29251:139;;28978:419;;;:::o;29403:174::-;29543:26;29539:1;29531:6;29527:14;29520:50;29403:174;:::o;29583:366::-;29725:3;29746:67;29810:2;29805:3;29746:67;:::i;:::-;29739:74;;29822:93;29911:3;29822:93;:::i;:::-;29940:2;29935:3;29931:12;29924:19;;29583:366;;;:::o;29955:419::-;30121:4;30159:2;30148:9;30144:18;30136:26;;30208:9;30202:4;30198:20;30194:1;30183:9;30179:17;30172:47;30236:131;30362:4;30236:131;:::i;:::-;30228:139;;29955:419;;;:::o;30380:228::-;30520:34;30516:1;30508:6;30504:14;30497:58;30589:11;30584:2;30576:6;30572:15;30565:36;30380:228;:::o;30614:366::-;30756:3;30777:67;30841:2;30836:3;30777:67;:::i;:::-;30770:74;;30853:93;30942:3;30853:93;:::i;:::-;30971:2;30966:3;30962:12;30955:19;;30614:366;;;:::o;30986:419::-;31152:4;31190:2;31179:9;31175:18;31167:26;;31239:9;31233:4;31229:20;31225:1;31214:9;31210:17;31203:47;31267:131;31393:4;31267:131;:::i;:::-;31259:139;;30986:419;;;:::o;31411:178::-;31551:30;31547:1;31539:6;31535:14;31528:54;31411:178;:::o;31595:366::-;31737:3;31758:67;31822:2;31817:3;31758:67;:::i;:::-;31751:74;;31834:93;31923:3;31834:93;:::i;:::-;31952:2;31947:3;31943:12;31936:19;;31595:366;;;:::o;31967:419::-;32133:4;32171:2;32160:9;32156:18;32148:26;;32220:9;32214:4;32210:20;32206:1;32195:9;32191:17;32184:47;32248:131;32374:4;32248:131;:::i;:::-;32240:139;;31967:419;;;:::o;32392:410::-;32432:7;32455:20;32473:1;32455:20;:::i;:::-;32450:25;;32489:20;32507:1;32489:20;:::i;:::-;32484:25;;32544:1;32541;32537:9;32566:30;32584:11;32566:30;:::i;:::-;32555:41;;32745:1;32736:7;32732:15;32729:1;32726:22;32706:1;32699:9;32679:83;32656:139;;32775:18;;:::i;:::-;32656:139;32440:362;32392:410;;;;:::o;32808:225::-;32948:34;32944:1;32936:6;32932:14;32925:58;33017:8;33012:2;33004:6;33000:15;32993:33;32808:225;:::o;33039:366::-;33181:3;33202:67;33266:2;33261:3;33202:67;:::i;:::-;33195:74;;33278:93;33367:3;33278:93;:::i;:::-;33396:2;33391:3;33387:12;33380:19;;33039:366;;;:::o;33411:419::-;33577:4;33615:2;33604:9;33600:18;33592:26;;33664:9;33658:4;33654:20;33650:1;33639:9;33635:17;33628:47;33692:131;33818:4;33692:131;:::i;:::-;33684:139;;33411:419;;;:::o;33836:233::-;33976:34;33972:1;33964:6;33960:14;33953:58;34045:16;34040:2;34032:6;34028:15;34021:41;33836:233;:::o;34075:366::-;34217:3;34238:67;34302:2;34297:3;34238:67;:::i;:::-;34231:74;;34314:93;34403:3;34314:93;:::i;:::-;34432:2;34427:3;34423:12;34416:19;;34075:366;;;:::o;34447:419::-;34613:4;34651:2;34640:9;34636:18;34628:26;;34700:9;34694:4;34690:20;34686:1;34675:9;34671:17;34664:47;34728:131;34854:4;34728:131;:::i;:::-;34720:139;;34447:419;;;:::o;34872:141::-;34921:4;34944:3;34936:11;;34967:3;34964:1;34957:14;35001:4;34998:1;34988:18;34980:26;;34872:141;;;:::o;35019:93::-;35056:6;35103:2;35098;35091:5;35087:14;35083:23;35073:33;;35019:93;;;:::o;35118:107::-;35162:8;35212:5;35206:4;35202:16;35181:37;;35118:107;;;;:::o;35231:393::-;35300:6;35350:1;35338:10;35334:18;35373:97;35403:66;35392:9;35373:97;:::i;:::-;35491:39;35521:8;35510:9;35491:39;:::i;:::-;35479:51;;35563:4;35559:9;35552:5;35548:21;35539:30;;35612:4;35602:8;35598:19;35591:5;35588:30;35578:40;;35307:317;;35231:393;;;;;:::o;35630:60::-;35658:3;35679:5;35672:12;;35630:60;;;:::o;35696:142::-;35746:9;35779:53;35797:34;35806:24;35824:5;35806:24;:::i;:::-;35797:34;:::i;:::-;35779:53;:::i;:::-;35766:66;;35696:142;;;:::o;35844:75::-;35887:3;35908:5;35901:12;;35844:75;;;:::o;35925:269::-;36035:39;36066:7;36035:39;:::i;:::-;36096:91;36145:41;36169:16;36145:41;:::i;:::-;36137:6;36130:4;36124:11;36096:91;:::i;:::-;36090:4;36083:105;36001:193;35925:269;;;:::o;36200:73::-;36245:3;36200:73;:::o;36279:189::-;36356:32;;:::i;:::-;36397:65;36455:6;36447;36441:4;36397:65;:::i;:::-;36332:136;36279:189;;:::o;36474:186::-;36534:120;36551:3;36544:5;36541:14;36534:120;;;36605:39;36642:1;36635:5;36605:39;:::i;:::-;36578:1;36571:5;36567:13;36558:22;;36534:120;;;36474:186;;:::o;36666:543::-;36767:2;36762:3;36759:11;36756:446;;;36801:38;36833:5;36801:38;:::i;:::-;36885:29;36903:10;36885:29;:::i;:::-;36875:8;36871:44;37068:2;37056:10;37053:18;37050:49;;;37089:8;37074:23;;37050:49;37112:80;37168:22;37186:3;37168:22;:::i;:::-;37158:8;37154:37;37141:11;37112:80;:::i;:::-;36771:431;;36756:446;36666:543;;;:::o;37215:117::-;37269:8;37319:5;37313:4;37309:16;37288:37;;37215:117;;;;:::o;37338:169::-;37382:6;37415:51;37463:1;37459:6;37451:5;37448:1;37444:13;37415:51;:::i;:::-;37411:56;37496:4;37490;37486:15;37476:25;;37389:118;37338:169;;;;:::o;37512:295::-;37588:4;37734:29;37759:3;37753:4;37734:29;:::i;:::-;37726:37;;37796:3;37793:1;37789:11;37783:4;37780:21;37772:29;;37512:295;;;;:::o;37812:1395::-;37929:37;37962:3;37929:37;:::i;:::-;38031:18;38023:6;38020:30;38017:56;;;38053:18;;:::i;:::-;38017:56;38097:38;38129:4;38123:11;38097:38;:::i;:::-;38182:67;38242:6;38234;38228:4;38182:67;:::i;:::-;38276:1;38300:4;38287:17;;38332:2;38324:6;38321:14;38349:1;38344:618;;;;39006:1;39023:6;39020:77;;;39072:9;39067:3;39063:19;39057:26;39048:35;;39020:77;39123:67;39183:6;39176:5;39123:67;:::i;:::-;39117:4;39110:81;38979:222;38314:887;;38344:618;38396:4;38392:9;38384:6;38380:22;38430:37;38462:4;38430:37;:::i;:::-;38489:1;38503:208;38517:7;38514:1;38511:14;38503:208;;;38596:9;38591:3;38587:19;38581:26;38573:6;38566:42;38647:1;38639:6;38635:14;38625:24;;38694:2;38683:9;38679:18;38666:31;;38540:4;38537:1;38533:12;38528:17;;38503:208;;;38739:6;38730:7;38727:19;38724:179;;;38797:9;38792:3;38788:19;38782:26;38840:48;38882:4;38874:6;38870:17;38859:9;38840:48;:::i;:::-;38832:6;38825:64;38747:156;38724:179;38949:1;38945;38937:6;38933:14;38929:22;38923:4;38916:36;38351:611;;;38314:887;;37904:1303;;;37812:1395;;:::o;39213:182::-;39353:34;39349:1;39341:6;39337:14;39330:58;39213:182;:::o;39401:366::-;39543:3;39564:67;39628:2;39623:3;39564:67;:::i;:::-;39557:74;;39640:93;39729:3;39640:93;:::i;:::-;39758:2;39753:3;39749:12;39742:19;;39401:366;;;:::o;39773:419::-;39939:4;39977:2;39966:9;39962:18;39954:26;;40026:9;40020:4;40016:20;40012:1;40001:9;39997:17;39990:47;40054:131;40180:4;40054:131;:::i;:::-;40046:139;;39773:419;;;:::o;40198:224::-;40338:34;40334:1;40326:6;40322:14;40315:58;40407:7;40402:2;40394:6;40390:15;40383:32;40198:224;:::o;40428:366::-;40570:3;40591:67;40655:2;40650:3;40591:67;:::i;:::-;40584:74;;40667:93;40756:3;40667:93;:::i;:::-;40785:2;40780:3;40776:12;40769:19;;40428:366;;;:::o;40800:419::-;40966:4;41004:2;40993:9;40989:18;40981:26;;41053:9;41047:4;41043:20;41039:1;41028:9;41024:17;41017:47;41081:131;41207:4;41081:131;:::i;:::-;41073:139;;40800:419;;;:::o;41225:223::-;41365:34;41361:1;41353:6;41349:14;41342:58;41434:6;41429:2;41421:6;41417:15;41410:31;41225:223;:::o;41454:366::-;41596:3;41617:67;41681:2;41676:3;41617:67;:::i;:::-;41610:74;;41693:93;41782:3;41693:93;:::i;:::-;41811:2;41806:3;41802:12;41795:19;;41454:366;;;:::o;41826:419::-;41992:4;42030:2;42019:9;42015:18;42007:26;;42079:9;42073:4;42069:20;42065:1;42054:9;42050:17;42043:47;42107:131;42233:4;42107:131;:::i;:::-;42099:139;;41826:419;;;:::o;42251:175::-;42391:27;42387:1;42379:6;42375:14;42368:51;42251:175;:::o;42432:366::-;42574:3;42595:67;42659:2;42654:3;42595:67;:::i;:::-;42588:74;;42671:93;42760:3;42671:93;:::i;:::-;42789:2;42784:3;42780:12;42773:19;;42432:366;;;:::o;42804:419::-;42970:4;43008:2;42997:9;42993:18;42985:26;;43057:9;43051:4;43047:20;43043:1;43032:9;43028:17;43021:47;43085:131;43211:4;43085:131;:::i;:::-;43077:139;;42804:419;;;:::o;43229:237::-;43369:34;43365:1;43357:6;43353:14;43346:58;43438:20;43433:2;43425:6;43421:15;43414:45;43229:237;:::o;43472:366::-;43614:3;43635:67;43699:2;43694:3;43635:67;:::i;:::-;43628:74;;43711:93;43800:3;43711:93;:::i;:::-;43829:2;43824:3;43820:12;43813:19;;43472:366;;;:::o;43844:419::-;44010:4;44048:2;44037:9;44033:18;44025:26;;44097:9;44091:4;44087:20;44083:1;44072:9;44068:17;44061:47;44125:131;44251:4;44125:131;:::i;:::-;44117:139;;43844:419;;;:::o;44269:148::-;44371:11;44408:3;44393:18;;44269:148;;;;:::o;44423:390::-;44529:3;44557:39;44590:5;44557:39;:::i;:::-;44612:89;44694:6;44689:3;44612:89;:::i;:::-;44605:96;;44710:65;44768:6;44763:3;44756:4;44749:5;44745:16;44710:65;:::i;:::-;44800:6;44795:3;44791:16;44784:23;;44533:280;44423:390;;;;:::o;44819:435::-;44999:3;45021:95;45112:3;45103:6;45021:95;:::i;:::-;45014:102;;45133:95;45224:3;45215:6;45133:95;:::i;:::-;45126:102;;45245:3;45238:10;;44819:435;;;;;:::o;45260:177::-;45400:29;45396:1;45388:6;45384:14;45377:53;45260:177;:::o;45443:366::-;45585:3;45606:67;45670:2;45665:3;45606:67;:::i;:::-;45599:74;;45682:93;45771:3;45682:93;:::i;:::-;45800:2;45795:3;45791:12;45784:19;;45443:366;;;:::o;45815:419::-;45981:4;46019:2;46008:9;46004:18;45996:26;;46068:9;46062:4;46058:20;46054:1;46043:9;46039:17;46032:47;46096:131;46222:4;46096:131;:::i;:::-;46088:139;;45815:419;;;:::o;46240:98::-;46291:6;46325:5;46319:12;46309:22;;46240:98;;;:::o;46344:168::-;46427:11;46461:6;46456:3;46449:19;46501:4;46496:3;46492:14;46477:29;;46344:168;;;;:::o;46518:373::-;46604:3;46632:38;46664:5;46632:38;:::i;:::-;46686:70;46749:6;46744:3;46686:70;:::i;:::-;46679:77;;46765:65;46823:6;46818:3;46811:4;46804:5;46800:16;46765:65;:::i;:::-;46855:29;46877:6;46855:29;:::i;:::-;46850:3;46846:39;46839:46;;46608:283;46518:373;;;;:::o;46897:640::-;47092:4;47130:3;47119:9;47115:19;47107:27;;47144:71;47212:1;47201:9;47197:17;47188:6;47144:71;:::i;:::-;47225:72;47293:2;47282:9;47278:18;47269:6;47225:72;:::i;:::-;47307;47375:2;47364:9;47360:18;47351:6;47307:72;:::i;:::-;47426:9;47420:4;47416:20;47411:2;47400:9;47396:18;47389:48;47454:76;47525:4;47516:6;47454:76;:::i;:::-;47446:84;;46897:640;;;;;;;:::o;47543:141::-;47599:5;47630:6;47624:13;47615:22;;47646:32;47672:5;47646:32;:::i;:::-;47543:141;;;;:::o;47690:349::-;47759:6;47808:2;47796:9;47787:7;47783:23;47779:32;47776:119;;;47814:79;;:::i;:::-;47776:119;47934:1;47959:63;48014:7;48005:6;47994:9;47990:22;47959:63;:::i;:::-;47949:73;;47905:127;47690:349;;;;:::o;48045:182::-;48185:34;48181:1;48173:6;48169:14;48162:58;48045:182;:::o;48233:366::-;48375:3;48396:67;48460:2;48455:3;48396:67;:::i;:::-;48389:74;;48472:93;48561:3;48472:93;:::i;:::-;48590:2;48585:3;48581:12;48574:19;;48233:366;;;:::o;48605:419::-;48771:4;48809:2;48798:9;48794:18;48786:26;;48858:9;48852:4;48848:20;48844:1;48833:9;48829:17;48822:47;48886:131;49012:4;48886:131;:::i;:::-;48878:139;;48605:419;;;:::o;49030:178::-;49170:30;49166:1;49158:6;49154:14;49147:54;49030:178;:::o;49214:366::-;49356:3;49377:67;49441:2;49436:3;49377:67;:::i;:::-;49370:74;;49453:93;49542:3;49453:93;:::i;:::-;49571:2;49566:3;49562:12;49555:19;;49214:366;;;:::o;49586:419::-;49752:4;49790:2;49779:9;49775:18;49767:26;;49839:9;49833:4;49829:20;49825:1;49814:9;49810:17;49803:47;49867:131;49993:4;49867:131;:::i;:::-;49859:139;;49586:419;;;:::o;50011:240::-;50151:34;50147:1;50139:6;50135:14;50128:58;50220:23;50215:2;50207:6;50203:15;50196:48;50011:240;:::o;50257:366::-;50399:3;50420:67;50484:2;50479:3;50420:67;:::i;:::-;50413:74;;50496:93;50585:3;50496:93;:::i;:::-;50614:2;50609:3;50605:12;50598:19;;50257:366;;;:::o;50629:419::-;50795:4;50833:2;50822:9;50818:18;50810:26;;50882:9;50876:4;50872:20;50868:1;50857:9;50853:17;50846:47;50910:131;51036:4;50910:131;:::i;:::-;50902:139;;50629:419;;;:::o;51054:180::-;51102:77;51099:1;51092:88;51199:4;51196:1;51189:15;51223:4;51220:1;51213:15;51240:194;51280:4;51300:20;51318:1;51300:20;:::i;:::-;51295:25;;51334:20;51352:1;51334:20;:::i;:::-;51329:25;;51378:1;51375;51371:9;51363:17;;51402:1;51396:4;51393:11;51390:37;;;51407:18;;:::i;:::-;51390:37;51240:194;;;;:::o;51440:180::-;51488:77;51485:1;51478:88;51585:4;51582:1;51575:15;51609:4;51606:1;51599:15

Swarm Source

ipfs://b3938949c453fdefad1d533c9c694d7da82de387ec75d568831c6b9f3928346c
Loading...
Loading
[ Download: CSV Export  ]

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