ETH Price: $2,400.95 (-0.87%)

Token

Sus Mfers by Doomscroller (SUSMFS)
 

Overview

Max Total Supply

303 SUSMFS

Holders

74

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A

Other Info

Balance
4 SUSMFS
0x60bf7f5d66321935294ddfb99588c5e42511ce78
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
SusMfersByDoomscroller

Compiler Version
v0.8.17+commit.8df45f5f

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-01-07
*/

// SPDX-License-Identifier: MIT

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


// OpenZeppelin Contracts (last updated v4.8.0) (utils/structs/EnumerableSet.sol)
// This file was procedurally generated from scripts/generate/templates/EnumerableSet.js.

pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 *
 * [WARNING]
 * ====
 * Trying to delete such a structure from storage will likely result in data corruption, rendering the structure
 * unusable.
 * See https://github.com/ethereum/solidity/pull/11843[ethereum/solidity#11843] for more info.
 *
 * In order to clean an EnumerableSet, you can either remove all elements one by one or create a fresh instance using an
 * array of EnumerableSet.
 * ====
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

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

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

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

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

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

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

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

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

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

            return true;
        } else {
            return false;
        }
    }

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

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

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

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

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

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

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

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

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

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

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

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

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

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

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

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

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

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

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }

    // UintSet

    struct UintSet {
        Set _inner;
    }

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

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

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

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

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

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

        /// @solidity memory-safe-assembly
        assembly {
            result := store
        }

        return result;
    }
}

// File: contracts/IOperatorFilterRegistry.sol


pragma solidity ^0.8.13;


interface IOperatorFilterRegistry {
    function isOperatorAllowed(address registrant, address operator) external returns (bool);
    function register(address registrant) external;
    function registerAndSubscribe(address registrant, address subscription) external;
    function registerAndCopyEntries(address registrant, address registrantToCopy) external;
    function updateOperator(address registrant, address operator, bool filtered) external;
    function updateOperators(address registrant, address[] calldata operators, bool filtered) external;
    function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;
    function subscribe(address registrant, address registrantToSubscribe) external;
    function unsubscribe(address registrant, bool copyExistingEntries) external;
    function subscriptionOf(address addr) external returns (address registrant);
    function subscribers(address registrant) external returns (address[] memory);
    function subscriberAt(address registrant, uint256 index) external returns (address);
    function copyEntriesOf(address registrant, address registrantToCopy) external;
    function isOperatorFiltered(address registrant, address operator) external returns (bool);
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);
    function filteredOperators(address addr) external returns (address[] memory);
    function filteredCodeHashes(address addr) external returns (bytes32[] memory);
    function filteredOperatorAt(address registrant, uint256 index) external returns (address);
    function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);
    function isRegistered(address addr) external returns (bool);
    function codeHashOf(address addr) external returns (bytes32);
}
// File: contracts/OperatorFilterer.sol


pragma solidity ^0.8.13;


contract OperatorFilterer {
    error OperatorNotAllowed(address operator);

    IOperatorFilterRegistry constant operatorFilterRegistry =
        IOperatorFilterRegistry(0x000000000000AAeB6D7670E522A718067333cd4E);

    constructor(address subscriptionOrRegistrantToCopy, bool subscribe) {
        // If an inheriting token contract is deployed to a network without the registry deployed, the modifier
        // will not revert, but the contract will need to be registered with the registry once it is deployed in
        // order for the modifier to filter addresses.
        if (address(operatorFilterRegistry).code.length > 0) {
            if (subscribe) {
                operatorFilterRegistry.registerAndSubscribe(address(this), subscriptionOrRegistrantToCopy);
            } else {
                if (subscriptionOrRegistrantToCopy != address(0)) {
                    operatorFilterRegistry.registerAndCopyEntries(address(this), subscriptionOrRegistrantToCopy);
                } else {
                    operatorFilterRegistry.register(address(this));
                }
            }
        }
    }

    modifier onlyAllowedOperator() virtual {
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(operatorFilterRegistry).code.length > 0) {
            if (!operatorFilterRegistry.isOperatorAllowed(address(this), msg.sender)) {
                revert OperatorNotAllowed(msg.sender);
            }
        }
        _;
    }
}
// File: contracts/DefaultOperatorFilterer.sol


pragma solidity ^0.8.13;


contract DefaultOperatorFilterer is OperatorFilterer {
    address constant DEFAULT_SUBSCRIPTION = address(0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6);

    constructor() OperatorFilterer(DEFAULT_SUBSCRIPTION, true) {}
}
// 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/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.0) (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;








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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: 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 {
        if (batchSize > 1) {
            if (from != address(0)) {
                _balances[from] -= batchSize;
            }
            if (to != address(0)) {
                _balances[to] += batchSize;
            }
        }
    }

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

// File: contracts/SusMfersByDoomscroller.sol



pragma solidity >=0.7.0 <0.9.0;





contract SusMfersByDoomscroller is ERC721, DefaultOperatorFilterer, Ownable {
  using Strings for uint256;
  using Counters for Counters.Counter;

  Counters.Counter private supply;

  string public uriPrefix = "ipfs://Qme1GpSvci7FHYW2DfQRZsQ8Pgh6crbzL1ra8Em9grbBFd/";
  string public uriSuffix = ".json";
  string public hiddenMetadataUri;
  
  uint256 public cost = 0.0042 ether;
  uint256 public maxSupply = 1000;
  uint256 public maxMintAmountPerTx = 10;

  bool public paused = true;
  bool public revealed = false;

  constructor() ERC721("Sus Mfers by Doomscroller", "SUSMFS") {
    setHiddenMetadataUri("ipfs://QmUUVhFtvMLaK5WYM8GNqYpiVtiLKxMFSdsWeB17pbyMdk/hidden.json");
  }

  modifier mintCompliance(uint256 _mintAmount) {
    require(_mintAmount > 0 && _mintAmount <= maxMintAmountPerTx, "Invalid mint amount!");
    require(supply.current() + _mintAmount <= maxSupply, "Max supply exceeded!");
    _;
  }

  function totalSupply() public view returns (uint256) {
    return supply.current();
  }

  function mint(uint256 _mintAmount) public payable mintCompliance(_mintAmount) {
    require(!paused, "The contract is paused!");
    require(msg.value >= cost * _mintAmount, "Insufficient funds!");

    _mintLoop(msg.sender, _mintAmount);
  }
  
  function mintForAddress(uint256 _mintAmount, address _receiver) public mintCompliance(_mintAmount) onlyOwner {
    _mintLoop(_receiver, _mintAmount);
  }

  function walletOfOwner(address _owner)
    public
    view
    returns (uint256[] memory)
  {
    uint256 ownerTokenCount = balanceOf(_owner);
    uint256[] memory ownedTokenIds = new uint256[](ownerTokenCount);
    uint256 currentTokenId = 1;
    uint256 ownedTokenIndex = 0;

    while (ownedTokenIndex < ownerTokenCount && currentTokenId <= maxSupply) {
      address currentTokenOwner = ownerOf(currentTokenId);

      if (currentTokenOwner == _owner) {
        ownedTokenIds[ownedTokenIndex] = currentTokenId;

        ownedTokenIndex++;
      }

      currentTokenId++;
    }

    return ownedTokenIds;
  }

  function tokenURI(uint256 _tokenId)
    public
    view
    virtual
    override
    returns (string memory)
  {
    require(
      _exists(_tokenId),
      "ERC721Metadata: URI query for nonexistent token"
    );

    if (revealed == false) {
      return hiddenMetadataUri;
    }

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

  function setRevealed(bool _state) public onlyOwner {
    revealed = _state;
  }

  function setCost(uint256 _cost) public onlyOwner {
    cost = _cost;
  }

  function setMaxMintAmountPerTx(uint256 _maxMintAmountPerTx) public onlyOwner {
    maxMintAmountPerTx = _maxMintAmountPerTx;
  }

  function setHiddenMetadataUri(string memory _hiddenMetadataUri) public onlyOwner {
    hiddenMetadataUri = _hiddenMetadataUri;
  }

  function setUriPrefix(string memory _uriPrefix) public onlyOwner {
    uriPrefix = _uriPrefix;
  }

  function setUriSuffix(string memory _uriSuffix) public onlyOwner {
    uriSuffix = _uriSuffix;
  }

  function setPaused(bool _state) public onlyOwner {
    paused = _state;
  }

  function withdraw() public onlyOwner {
    // This will transfer the remaining contract balance to the owner.
    // Do not remove this otherwise you will not be able to withdraw the funds.
    // =============================================================================
    (bool os, ) = payable(owner()).call{value: address(this).balance}("");
    require(os);
    // =============================================================================
  }

  function _mintLoop(address _receiver, uint256 _mintAmount) internal {
    for (uint256 i = 0; i < _mintAmount; i++) {
      supply.increment();
      _safeMint(_receiver, supply.current());
    }
  }

  function _baseURI() internal view virtual override returns (string memory) {
    return uriPrefix;
  }
    function transferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator {
        super.transferFrom(from, to, tokenId);
    }

    function safeTransferFrom(address from, address to, uint256 tokenId) public override onlyAllowedOperator {
        super.safeTransferFrom(from, to, tokenId);
    }

    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data)
        public
        override
        onlyAllowedOperator
    {
        super.safeTransferFrom(from, to, tokenId, data);
    }

}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"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":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hiddenMetadataUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxMintAmountPerTx","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"mintForAddress","outputs":[],"stateMutability":"nonpayable","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":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cost","type":"uint256"}],"name":"setCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_hiddenMetadataUri","type":"string"}],"name":"setHiddenMetadataUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxMintAmountPerTx","type":"uint256"}],"name":"setMaxMintAmountPerTx","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"setPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"setRevealed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uriPrefix","type":"string"}],"name":"setUriPrefix","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uriSuffix","type":"string"}],"name":"setUriSuffix","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":"_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"},{"inputs":[],"name":"uriPrefix","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uriSuffix","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"walletOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405260405180606001604052806036815260200162004d0d60369139600890816200002e9190620007e8565b506040518060400160405280600581526020017f2e6a736f6e00000000000000000000000000000000000000000000000000000081525060099081620000759190620007e8565b50660eebe0b40e8000600b556103e8600c55600a600d556001600e60006101000a81548160ff0219169083151502179055506000600e60016101000a81548160ff021916908315150217905550348015620000cf57600080fd5b50733cc6cdda760b79bafa08df41ecfa224f810dceb660016040518060400160405280601981526020017f537573204d6665727320627920446f6f6d7363726f6c6c6572000000000000008152506040518060400160405280600681526020017f5355534d465300000000000000000000000000000000000000000000000000008152508160009081620001649190620007e8565b508060019081620001769190620007e8565b50505060006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b11156200036e57801562000234576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16637d3e3dbe30846040518363ffffffff1660e01b8152600401620001fa92919062000914565b600060405180830381600087803b1580156200021557600080fd5b505af11580156200022a573d6000803e3d6000fd5b505050506200036d565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614620002ee576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663a0af290330846040518363ffffffff1660e01b8152600401620002b492919062000914565b600060405180830381600087803b158015620002cf57600080fd5b505af1158015620002e4573d6000803e3d6000fd5b505050506200036c565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16634420e486306040518263ffffffff1660e01b815260040162000337919062000941565b600060405180830381600087803b1580156200035257600080fd5b505af115801562000367573d6000803e3d6000fd5b505050505b5b5b50506200039062000384620003c060201b60201c565b620003c860201b60201c565b620003ba60405180608001604052806041815260200162004d43604191396200048e60201b60201c565b620009e1565b600033905090565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b6200049e620004b360201b60201c565b80600a9081620004af9190620007e8565b5050565b620004c3620003c060201b60201c565b73ffffffffffffffffffffffffffffffffffffffff16620004e96200054460201b60201c565b73ffffffffffffffffffffffffffffffffffffffff161462000542576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200053990620009bf565b60405180910390fd5b565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680620005f057607f821691505b602082108103620006065762000605620005a8565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620006707fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000631565b6200067c868362000631565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620006c9620006c3620006bd8462000694565b6200069e565b62000694565b9050919050565b6000819050919050565b620006e583620006a8565b620006fd620006f482620006d0565b8484546200063e565b825550505050565b600090565b6200071462000705565b62000721818484620006da565b505050565b5b8181101562000749576200073d6000826200070a565b60018101905062000727565b5050565b601f821115620007985762000762816200060c565b6200076d8462000621565b810160208510156200077d578190505b620007956200078c8562000621565b83018262000726565b50505b505050565b600082821c905092915050565b6000620007bd600019846008026200079d565b1980831691505092915050565b6000620007d88383620007aa565b9150826002028217905092915050565b620007f3826200056e565b67ffffffffffffffff8111156200080f576200080e62000579565b5b6200081b8254620005d7565b620008288282856200074d565b600060209050601f8311600181146200086057600084156200084b578287015190505b620008578582620007ca565b865550620008c7565b601f19841662000870866200060c565b60005b828110156200089a5784890151825560018201915060208501945060208101905062000873565b86831015620008ba5784890151620008b6601f891682620007aa565b8355505b6001600288020188555050505b505050505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620008fc82620008cf565b9050919050565b6200090e81620008ef565b82525050565b60006040820190506200092b600083018562000903565b6200093a602083018462000903565b9392505050565b600060208201905062000958600083018462000903565b92915050565b600082825260208201905092915050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000620009a76020836200095e565b9150620009b4826200096f565b602082019050919050565b60006020820190508181036000830152620009da8162000998565b9050919050565b61431c80620009f16000396000f3fe60806040526004361061020f5760003560e01c80636352211e11610118578063a45ba8e7116100a0578063d5abeb011161006f578063d5abeb0114610768578063e0a8085314610793578063e985e9c5146107bc578063efbd73f4146107f9578063f2fde38b146108225761020f565b8063a45ba8e7146106ae578063b071401b146106d9578063b88d4fde14610702578063c87b56dd1461072b5761020f565b80638da5cb5b116100e75780638da5cb5b146105e857806394354fd01461061357806395d89b411461063e578063a0712d6814610669578063a22cb465146106855761020f565b80636352211e1461052e57806370a082311461056b578063715018a6146105a85780637ec4a659146105bf5761020f565b80633ccfd60b1161019b5780634fdd43cb1161016a5780634fdd43cb1461045957806351830227146104825780635503a0e8146104ad5780635c975abb146104d857806362b99ad4146105035761020f565b80633ccfd60b146103b357806342842e0e146103ca578063438b6300146103f357806344a0d68a146104305761020f565b806313faede6116101e257806313faede6146102e257806316ba10e01461030d57806316c38b3c1461033657806318160ddd1461035f57806323b872dd1461038a5761020f565b806301ffc9a71461021457806306fdde0314610251578063081812fc1461027c578063095ea7b3146102b9575b600080fd5b34801561022057600080fd5b5061023b60048036038101906102369190612b92565b61084b565b6040516102489190612bda565b60405180910390f35b34801561025d57600080fd5b5061026661092d565b6040516102739190612c85565b60405180910390f35b34801561028857600080fd5b506102a3600480360381019061029e9190612cdd565b6109bf565b6040516102b09190612d4b565b60405180910390f35b3480156102c557600080fd5b506102e060048036038101906102db9190612d92565b610a05565b005b3480156102ee57600080fd5b506102f7610b1c565b6040516103049190612de1565b60405180910390f35b34801561031957600080fd5b50610334600480360381019061032f9190612f31565b610b22565b005b34801561034257600080fd5b5061035d60048036038101906103589190612fa6565b610b3d565b005b34801561036b57600080fd5b50610374610b62565b6040516103819190612de1565b60405180910390f35b34801561039657600080fd5b506103b160048036038101906103ac9190612fd3565b610b73565b005b3480156103bf57600080fd5b506103c8610c7f565b005b3480156103d657600080fd5b506103f160048036038101906103ec9190612fd3565b610d07565b005b3480156103ff57600080fd5b5061041a60048036038101906104159190613026565b610e13565b6040516104279190613111565b60405180910390f35b34801561043c57600080fd5b5061045760048036038101906104529190612cdd565b610f1d565b005b34801561046557600080fd5b50610480600480360381019061047b9190612f31565b610f2f565b005b34801561048e57600080fd5b50610497610f4a565b6040516104a49190612bda565b60405180910390f35b3480156104b957600080fd5b506104c2610f5d565b6040516104cf9190612c85565b60405180910390f35b3480156104e457600080fd5b506104ed610feb565b6040516104fa9190612bda565b60405180910390f35b34801561050f57600080fd5b50610518610ffe565b6040516105259190612c85565b60405180910390f35b34801561053a57600080fd5b5061055560048036038101906105509190612cdd565b61108c565b6040516105629190612d4b565b60405180910390f35b34801561057757600080fd5b50610592600480360381019061058d9190613026565b611112565b60405161059f9190612de1565b60405180910390f35b3480156105b457600080fd5b506105bd6111c9565b005b3480156105cb57600080fd5b506105e660048036038101906105e19190612f31565b6111dd565b005b3480156105f457600080fd5b506105fd6111f8565b60405161060a9190612d4b565b60405180910390f35b34801561061f57600080fd5b50610628611222565b6040516106359190612de1565b60405180910390f35b34801561064a57600080fd5b50610653611228565b6040516106609190612c85565b60405180910390f35b610683600480360381019061067e9190612cdd565b6112ba565b005b34801561069157600080fd5b506106ac60048036038101906106a79190613133565b611413565b005b3480156106ba57600080fd5b506106c3611429565b6040516106d09190612c85565b60405180910390f35b3480156106e557600080fd5b5061070060048036038101906106fb9190612cdd565b6114b7565b005b34801561070e57600080fd5b5061072960048036038101906107249190613214565b6114c9565b005b34801561073757600080fd5b50610752600480360381019061074d9190612cdd565b6115d7565b60405161075f9190612c85565b60405180910390f35b34801561077457600080fd5b5061077d61172f565b60405161078a9190612de1565b60405180910390f35b34801561079f57600080fd5b506107ba60048036038101906107b59190612fa6565b611735565b005b3480156107c857600080fd5b506107e360048036038101906107de9190613297565b61175a565b6040516107f09190612bda565b60405180910390f35b34801561080557600080fd5b50610820600480360381019061081b91906132d7565b6117ee565b005b34801561082e57600080fd5b5061084960048036038101906108449190613026565b6118b0565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061091657507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610926575061092582611933565b5b9050919050565b60606000805461093c90613346565b80601f016020809104026020016040519081016040528092919081815260200182805461096890613346565b80156109b55780601f1061098a576101008083540402835291602001916109b5565b820191906000526020600020905b81548152906001019060200180831161099857829003601f168201915b5050505050905090565b60006109ca8261199d565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610a108261108c565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610a80576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a77906133e9565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610a9f6119e8565b73ffffffffffffffffffffffffffffffffffffffff161480610ace5750610acd81610ac86119e8565b61175a565b5b610b0d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b049061347b565b60405180910390fd5b610b1783836119f0565b505050565b600b5481565b610b2a611aa9565b8060099081610b399190613647565b5050565b610b45611aa9565b80600e60006101000a81548160ff02191690831515021790555050565b6000610b6e6007611b27565b905090565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115610c6f576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401610bea929190613719565b6020604051808303816000875af1158015610c09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2d9190613757565b610c6e57336040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401610c659190612d4b565b60405180910390fd5b5b610c7a838383611b35565b505050565b610c87611aa9565b6000610c916111f8565b73ffffffffffffffffffffffffffffffffffffffff1647604051610cb4906137b5565b60006040518083038185875af1925050503d8060008114610cf1576040519150601f19603f3d011682016040523d82523d6000602084013e610cf6565b606091505b5050905080610d0457600080fd5b50565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115610e03576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401610d7e929190613719565b6020604051808303816000875af1158015610d9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc19190613757565b610e0257336040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401610df99190612d4b565b60405180910390fd5b5b610e0e838383611b95565b505050565b60606000610e2083611112565b905060008167ffffffffffffffff811115610e3e57610e3d612e06565b5b604051908082528060200260200182016040528015610e6c5781602001602082028036833780820191505090505b50905060006001905060005b8381108015610e895750600c548211155b15610f11576000610e998361108c565b90508673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610efd5782848381518110610ee257610ee16137ca565b5b6020026020010181815250508180610ef990613828565b9250505b8280610f0890613828565b93505050610e78565b82945050505050919050565b610f25611aa9565b80600b8190555050565b610f37611aa9565b80600a9081610f469190613647565b5050565b600e60019054906101000a900460ff1681565b60098054610f6a90613346565b80601f0160208091040260200160405190810160405280929190818152602001828054610f9690613346565b8015610fe35780601f10610fb857610100808354040283529160200191610fe3565b820191906000526020600020905b815481529060010190602001808311610fc657829003601f168201915b505050505081565b600e60009054906101000a900460ff1681565b6008805461100b90613346565b80601f016020809104026020016040519081016040528092919081815260200182805461103790613346565b80156110845780601f1061105957610100808354040283529160200191611084565b820191906000526020600020905b81548152906001019060200180831161106757829003601f168201915b505050505081565b60008061109883611bb5565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611109576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611100906138bc565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611182576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111799061394e565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6111d1611aa9565b6111db6000611bf2565b565b6111e5611aa9565b80600890816111f49190613647565b5050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600d5481565b60606001805461123790613346565b80601f016020809104026020016040519081016040528092919081815260200182805461126390613346565b80156112b05780601f10611285576101008083540402835291602001916112b0565b820191906000526020600020905b81548152906001019060200180831161129357829003601f168201915b5050505050905090565b806000811180156112cd5750600d548111155b61130c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611303906139ba565b60405180910390fd5b600c548161131a6007611b27565b61132491906139da565b1115611365576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161135c90613a5a565b60405180910390fd5b600e60009054906101000a900460ff16156113b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ac90613ac6565b60405180910390fd5b81600b546113c39190613ae6565b341015611405576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113fc90613b74565b60405180910390fd5b61140f3383611cb8565b5050565b61142561141e6119e8565b8383611cf8565b5050565b600a805461143690613346565b80601f016020809104026020016040519081016040528092919081815260200182805461146290613346565b80156114af5780601f10611484576101008083540402835291602001916114af565b820191906000526020600020905b81548152906001019060200180831161149257829003601f168201915b505050505081565b6114bf611aa9565b80600d8190555050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b11156115c5576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401611540929190613719565b6020604051808303816000875af115801561155f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115839190613757565b6115c457336040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016115bb9190612d4b565b60405180910390fd5b5b6115d184848484611e64565b50505050565b60606115e282611ec6565b611621576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161890613c06565b60405180910390fd5b60001515600e60019054906101000a900460ff161515036116ce57600a805461164990613346565b80601f016020809104026020016040519081016040528092919081815260200182805461167590613346565b80156116c25780601f10611697576101008083540402835291602001916116c2565b820191906000526020600020905b8154815290600101906020018083116116a557829003601f168201915b5050505050905061172a565b60006116d8611f07565b905060008151116116f85760405180602001604052806000815250611726565b8061170284611f99565b600960405160200161171693929190613ce5565b6040516020818303038152906040525b9150505b919050565b600c5481565b61173d611aa9565b80600e60016101000a81548160ff02191690831515021790555050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b816000811180156118015750600d548111155b611840576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611837906139ba565b60405180910390fd5b600c548161184e6007611b27565b61185891906139da565b1115611899576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161189090613a5a565b60405180910390fd5b6118a1611aa9565b6118ab8284611cb8565b505050565b6118b8611aa9565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611927576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161191e90613d88565b60405180910390fd5b61193081611bf2565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6119a681611ec6565b6119e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119dc906138bc565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611a638361108c565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b611ab16119e8565b73ffffffffffffffffffffffffffffffffffffffff16611acf6111f8565b73ffffffffffffffffffffffffffffffffffffffff1614611b25576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b1c90613df4565b60405180910390fd5b565b600081600001549050919050565b611b46611b406119e8565b82612067565b611b85576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b7c90613e86565b60405180910390fd5b611b908383836120fc565b505050565b611bb0838383604051806020016040528060008152506114c9565b505050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60005b81811015611cf357611ccd60076123f5565b611ce083611cdb6007611b27565b61240b565b8080611ceb90613828565b915050611cbb565b505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d66576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d5d90613ef2565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611e579190612bda565b60405180910390a3505050565b611e75611e6f6119e8565b83612067565b611eb4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eab90613e86565b60405180910390fd5b611ec084848484612429565b50505050565b60008073ffffffffffffffffffffffffffffffffffffffff16611ee883611bb5565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b606060088054611f1690613346565b80601f0160208091040260200160405190810160405280929190818152602001828054611f4290613346565b8015611f8f5780601f10611f6457610100808354040283529160200191611f8f565b820191906000526020600020905b815481529060010190602001808311611f7257829003601f168201915b5050505050905090565b606060006001611fa884612485565b01905060008167ffffffffffffffff811115611fc757611fc6612e06565b5b6040519080825280601f01601f191660200182016040528015611ff95781602001600182028036833780820191505090505b509050600082602001820190505b60011561205c578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816120505761204f613f12565b5b04945060008503612007575b819350505050919050565b6000806120738361108c565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806120b557506120b4818561175a565b5b806120f357508373ffffffffffffffffffffffffffffffffffffffff166120db846109bf565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661211c8261108c565b73ffffffffffffffffffffffffffffffffffffffff1614612172576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161216990613fb3565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036121e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121d890614045565b60405180910390fd5b6121ee83838360016125d8565b8273ffffffffffffffffffffffffffffffffffffffff1661220e8261108c565b73ffffffffffffffffffffffffffffffffffffffff1614612264576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161225b90613fb3565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46123f083838360016126fe565b505050565b6001816000016000828254019250508190555050565b612425828260405180602001604052806000815250612704565b5050565b6124348484846120fc565b6124408484848461275f565b61247f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612476906140d7565b60405180910390fd5b50505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106124e3577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816124d9576124d8613f12565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612520576d04ee2d6d415b85acef8100000000838161251657612515613f12565b5b0492506020810190505b662386f26fc10000831061254f57662386f26fc10000838161254557612544613f12565b5b0492506010810190505b6305f5e1008310612578576305f5e100838161256e5761256d613f12565b5b0492506008810190505b612710831061259d57612710838161259357612592613f12565b5b0492506004810190505b606483106125c057606483816125b6576125b5613f12565b5b0492506002810190505b600a83106125cf576001810190505b80915050919050565b60018111156126f857600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461266c5780600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461266491906140f7565b925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146126f75780600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546126ef91906139da565b925050819055505b5b50505050565b50505050565b61270e83836128e6565b61271b600084848461275f565b61275a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612751906140d7565b60405180910390fd5b505050565b60006127808473ffffffffffffffffffffffffffffffffffffffff16612b03565b156128d9578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026127a96119e8565b8786866040518563ffffffff1660e01b81526004016127cb9493929190614180565b6020604051808303816000875af192505050801561280757506040513d601f19601f8201168201806040525081019061280491906141e1565b60015b612889573d8060008114612837576040519150601f19603f3d011682016040523d82523d6000602084013e61283c565b606091505b506000815103612881576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612878906140d7565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149150506128de565b600190505b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612955576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161294c9061425a565b60405180910390fd5b61295e81611ec6565b1561299e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612995906142c6565b60405180910390fd5b6129ac6000838360016125d8565b6129b581611ec6565b156129f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129ec906142c6565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612aff6000838360016126fe565b5050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612b6f81612b3a565b8114612b7a57600080fd5b50565b600081359050612b8c81612b66565b92915050565b600060208284031215612ba857612ba7612b30565b5b6000612bb684828501612b7d565b91505092915050565b60008115159050919050565b612bd481612bbf565b82525050565b6000602082019050612bef6000830184612bcb565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612c2f578082015181840152602081019050612c14565b60008484015250505050565b6000601f19601f8301169050919050565b6000612c5782612bf5565b612c618185612c00565b9350612c71818560208601612c11565b612c7a81612c3b565b840191505092915050565b60006020820190508181036000830152612c9f8184612c4c565b905092915050565b6000819050919050565b612cba81612ca7565b8114612cc557600080fd5b50565b600081359050612cd781612cb1565b92915050565b600060208284031215612cf357612cf2612b30565b5b6000612d0184828501612cc8565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612d3582612d0a565b9050919050565b612d4581612d2a565b82525050565b6000602082019050612d606000830184612d3c565b92915050565b612d6f81612d2a565b8114612d7a57600080fd5b50565b600081359050612d8c81612d66565b92915050565b60008060408385031215612da957612da8612b30565b5b6000612db785828601612d7d565b9250506020612dc885828601612cc8565b9150509250929050565b612ddb81612ca7565b82525050565b6000602082019050612df66000830184612dd2565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e3e82612c3b565b810181811067ffffffffffffffff82111715612e5d57612e5c612e06565b5b80604052505050565b6000612e70612b26565b9050612e7c8282612e35565b919050565b600067ffffffffffffffff821115612e9c57612e9b612e06565b5b612ea582612c3b565b9050602081019050919050565b82818337600083830152505050565b6000612ed4612ecf84612e81565b612e66565b905082815260208101848484011115612ef057612eef612e01565b5b612efb848285612eb2565b509392505050565b600082601f830112612f1857612f17612dfc565b5b8135612f28848260208601612ec1565b91505092915050565b600060208284031215612f4757612f46612b30565b5b600082013567ffffffffffffffff811115612f6557612f64612b35565b5b612f7184828501612f03565b91505092915050565b612f8381612bbf565b8114612f8e57600080fd5b50565b600081359050612fa081612f7a565b92915050565b600060208284031215612fbc57612fbb612b30565b5b6000612fca84828501612f91565b91505092915050565b600080600060608486031215612fec57612feb612b30565b5b6000612ffa86828701612d7d565b935050602061300b86828701612d7d565b925050604061301c86828701612cc8565b9150509250925092565b60006020828403121561303c5761303b612b30565b5b600061304a84828501612d7d565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61308881612ca7565b82525050565b600061309a838361307f565b60208301905092915050565b6000602082019050919050565b60006130be82613053565b6130c8818561305e565b93506130d38361306f565b8060005b838110156131045781516130eb888261308e565b97506130f6836130a6565b9250506001810190506130d7565b5085935050505092915050565b6000602082019050818103600083015261312b81846130b3565b905092915050565b6000806040838503121561314a57613149612b30565b5b600061315885828601612d7d565b925050602061316985828601612f91565b9150509250929050565b600067ffffffffffffffff82111561318e5761318d612e06565b5b61319782612c3b565b9050602081019050919050565b60006131b76131b284613173565b612e66565b9050828152602081018484840111156131d3576131d2612e01565b5b6131de848285612eb2565b509392505050565b600082601f8301126131fb576131fa612dfc565b5b813561320b8482602086016131a4565b91505092915050565b6000806000806080858703121561322e5761322d612b30565b5b600061323c87828801612d7d565b945050602061324d87828801612d7d565b935050604061325e87828801612cc8565b925050606085013567ffffffffffffffff81111561327f5761327e612b35565b5b61328b878288016131e6565b91505092959194509250565b600080604083850312156132ae576132ad612b30565b5b60006132bc85828601612d7d565b92505060206132cd85828601612d7d565b9150509250929050565b600080604083850312156132ee576132ed612b30565b5b60006132fc85828601612cc8565b925050602061330d85828601612d7d565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061335e57607f821691505b60208210810361337157613370613317565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b60006133d3602183612c00565b91506133de82613377565b604082019050919050565b60006020820190508181036000830152613402816133c6565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b6000613465603d83612c00565b915061347082613409565b604082019050919050565b6000602082019050818103600083015261349481613458565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026134fd7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826134c0565b61350786836134c0565b95508019841693508086168417925050509392505050565b6000819050919050565b600061354461353f61353a84612ca7565b61351f565b612ca7565b9050919050565b6000819050919050565b61355e83613529565b61357261356a8261354b565b8484546134cd565b825550505050565b600090565b61358761357a565b613592818484613555565b505050565b5b818110156135b6576135ab60008261357f565b600181019050613598565b5050565b601f8211156135fb576135cc8161349b565b6135d5846134b0565b810160208510156135e4578190505b6135f86135f0856134b0565b830182613597565b50505b505050565b600082821c905092915050565b600061361e60001984600802613600565b1980831691505092915050565b6000613637838361360d565b9150826002028217905092915050565b61365082612bf5565b67ffffffffffffffff81111561366957613668612e06565b5b6136738254613346565b61367e8282856135ba565b600060209050601f8311600181146136b1576000841561369f578287015190505b6136a9858261362b565b865550613711565b601f1984166136bf8661349b565b60005b828110156136e7578489015182556001820191506020850194506020810190506136c2565b868310156137045784890151613700601f89168261360d565b8355505b6001600288020188555050505b505050505050565b600060408201905061372e6000830185612d3c565b61373b6020830184612d3c565b9392505050565b60008151905061375181612f7a565b92915050565b60006020828403121561376d5761376c612b30565b5b600061377b84828501613742565b91505092915050565b600081905092915050565b50565b600061379f600083613784565b91506137aa8261378f565b600082019050919050565b60006137c082613792565b9150819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061383382612ca7565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613865576138646137f9565b5b600182019050919050565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b60006138a6601883612c00565b91506138b182613870565b602082019050919050565b600060208201905081810360008301526138d581613899565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000613938602983612c00565b9150613943826138dc565b604082019050919050565b600060208201905081810360008301526139678161392b565b9050919050565b7f496e76616c6964206d696e7420616d6f756e7421000000000000000000000000600082015250565b60006139a4601483612c00565b91506139af8261396e565b602082019050919050565b600060208201905081810360008301526139d381613997565b9050919050565b60006139e582612ca7565b91506139f083612ca7565b9250828201905080821115613a0857613a076137f9565b5b92915050565b7f4d617820737570706c7920657863656564656421000000000000000000000000600082015250565b6000613a44601483612c00565b9150613a4f82613a0e565b602082019050919050565b60006020820190508181036000830152613a7381613a37565b9050919050565b7f54686520636f6e74726163742069732070617573656421000000000000000000600082015250565b6000613ab0601783612c00565b9150613abb82613a7a565b602082019050919050565b60006020820190508181036000830152613adf81613aa3565b9050919050565b6000613af182612ca7565b9150613afc83612ca7565b9250828202613b0a81612ca7565b91508282048414831517613b2157613b206137f9565b5b5092915050565b7f496e73756666696369656e742066756e64732100000000000000000000000000600082015250565b6000613b5e601383612c00565b9150613b6982613b28565b602082019050919050565b60006020820190508181036000830152613b8d81613b51565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b6000613bf0602f83612c00565b9150613bfb82613b94565b604082019050919050565b60006020820190508181036000830152613c1f81613be3565b9050919050565b600081905092915050565b6000613c3c82612bf5565b613c468185613c26565b9350613c56818560208601612c11565b80840191505092915050565b60008154613c6f81613346565b613c798186613c26565b94506001821660008114613c945760018114613ca957613cdc565b60ff1983168652811515820286019350613cdc565b613cb28561349b565b60005b83811015613cd457815481890152600182019150602081019050613cb5565b838801955050505b50505092915050565b6000613cf18286613c31565b9150613cfd8285613c31565b9150613d098284613c62565b9150819050949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613d72602683612c00565b9150613d7d82613d16565b604082019050919050565b60006020820190508181036000830152613da181613d65565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000613dde602083612c00565b9150613de982613da8565b602082019050919050565b60006020820190508181036000830152613e0d81613dd1565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b6000613e70602d83612c00565b9150613e7b82613e14565b604082019050919050565b60006020820190508181036000830152613e9f81613e63565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000613edc601983612c00565b9150613ee782613ea6565b602082019050919050565b60006020820190508181036000830152613f0b81613ecf565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000613f9d602583612c00565b9150613fa882613f41565b604082019050919050565b60006020820190508181036000830152613fcc81613f90565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b600061402f602483612c00565b915061403a82613fd3565b604082019050919050565b6000602082019050818103600083015261405e81614022565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006140c1603283612c00565b91506140cc82614065565b604082019050919050565b600060208201905081810360008301526140f0816140b4565b9050919050565b600061410282612ca7565b915061410d83612ca7565b9250828203905081811115614125576141246137f9565b5b92915050565b600081519050919050565b600082825260208201905092915050565b60006141528261412b565b61415c8185614136565b935061416c818560208601612c11565b61417581612c3b565b840191505092915050565b60006080820190506141956000830187612d3c565b6141a26020830186612d3c565b6141af6040830185612dd2565b81810360608301526141c18184614147565b905095945050505050565b6000815190506141db81612b66565b92915050565b6000602082840312156141f7576141f6612b30565b5b6000614205848285016141cc565b91505092915050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000614244602083612c00565b915061424f8261420e565b602082019050919050565b6000602082019050818103600083015261427381614237565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b60006142b0601c83612c00565b91506142bb8261427a565b602082019050919050565b600060208201905081810360008301526142df816142a3565b905091905056fea26469706673582212205f4178fd6fc4e248c7e092bbf2c60e525be5860531b8d2342a4a158287e4e08f64736f6c63430008110033697066733a2f2f516d6531477053766369374648595732446651525a735138506768366372627a4c31726138456d396772624246642f697066733a2f2f516d555556684674764d4c614b3557594d38474e715970695674694c4b784d4653647357654231377062794d646b2f68696464656e2e6a736f6e

Deployed Bytecode

0x60806040526004361061020f5760003560e01c80636352211e11610118578063a45ba8e7116100a0578063d5abeb011161006f578063d5abeb0114610768578063e0a8085314610793578063e985e9c5146107bc578063efbd73f4146107f9578063f2fde38b146108225761020f565b8063a45ba8e7146106ae578063b071401b146106d9578063b88d4fde14610702578063c87b56dd1461072b5761020f565b80638da5cb5b116100e75780638da5cb5b146105e857806394354fd01461061357806395d89b411461063e578063a0712d6814610669578063a22cb465146106855761020f565b80636352211e1461052e57806370a082311461056b578063715018a6146105a85780637ec4a659146105bf5761020f565b80633ccfd60b1161019b5780634fdd43cb1161016a5780634fdd43cb1461045957806351830227146104825780635503a0e8146104ad5780635c975abb146104d857806362b99ad4146105035761020f565b80633ccfd60b146103b357806342842e0e146103ca578063438b6300146103f357806344a0d68a146104305761020f565b806313faede6116101e257806313faede6146102e257806316ba10e01461030d57806316c38b3c1461033657806318160ddd1461035f57806323b872dd1461038a5761020f565b806301ffc9a71461021457806306fdde0314610251578063081812fc1461027c578063095ea7b3146102b9575b600080fd5b34801561022057600080fd5b5061023b60048036038101906102369190612b92565b61084b565b6040516102489190612bda565b60405180910390f35b34801561025d57600080fd5b5061026661092d565b6040516102739190612c85565b60405180910390f35b34801561028857600080fd5b506102a3600480360381019061029e9190612cdd565b6109bf565b6040516102b09190612d4b565b60405180910390f35b3480156102c557600080fd5b506102e060048036038101906102db9190612d92565b610a05565b005b3480156102ee57600080fd5b506102f7610b1c565b6040516103049190612de1565b60405180910390f35b34801561031957600080fd5b50610334600480360381019061032f9190612f31565b610b22565b005b34801561034257600080fd5b5061035d60048036038101906103589190612fa6565b610b3d565b005b34801561036b57600080fd5b50610374610b62565b6040516103819190612de1565b60405180910390f35b34801561039657600080fd5b506103b160048036038101906103ac9190612fd3565b610b73565b005b3480156103bf57600080fd5b506103c8610c7f565b005b3480156103d657600080fd5b506103f160048036038101906103ec9190612fd3565b610d07565b005b3480156103ff57600080fd5b5061041a60048036038101906104159190613026565b610e13565b6040516104279190613111565b60405180910390f35b34801561043c57600080fd5b5061045760048036038101906104529190612cdd565b610f1d565b005b34801561046557600080fd5b50610480600480360381019061047b9190612f31565b610f2f565b005b34801561048e57600080fd5b50610497610f4a565b6040516104a49190612bda565b60405180910390f35b3480156104b957600080fd5b506104c2610f5d565b6040516104cf9190612c85565b60405180910390f35b3480156104e457600080fd5b506104ed610feb565b6040516104fa9190612bda565b60405180910390f35b34801561050f57600080fd5b50610518610ffe565b6040516105259190612c85565b60405180910390f35b34801561053a57600080fd5b5061055560048036038101906105509190612cdd565b61108c565b6040516105629190612d4b565b60405180910390f35b34801561057757600080fd5b50610592600480360381019061058d9190613026565b611112565b60405161059f9190612de1565b60405180910390f35b3480156105b457600080fd5b506105bd6111c9565b005b3480156105cb57600080fd5b506105e660048036038101906105e19190612f31565b6111dd565b005b3480156105f457600080fd5b506105fd6111f8565b60405161060a9190612d4b565b60405180910390f35b34801561061f57600080fd5b50610628611222565b6040516106359190612de1565b60405180910390f35b34801561064a57600080fd5b50610653611228565b6040516106609190612c85565b60405180910390f35b610683600480360381019061067e9190612cdd565b6112ba565b005b34801561069157600080fd5b506106ac60048036038101906106a79190613133565b611413565b005b3480156106ba57600080fd5b506106c3611429565b6040516106d09190612c85565b60405180910390f35b3480156106e557600080fd5b5061070060048036038101906106fb9190612cdd565b6114b7565b005b34801561070e57600080fd5b5061072960048036038101906107249190613214565b6114c9565b005b34801561073757600080fd5b50610752600480360381019061074d9190612cdd565b6115d7565b60405161075f9190612c85565b60405180910390f35b34801561077457600080fd5b5061077d61172f565b60405161078a9190612de1565b60405180910390f35b34801561079f57600080fd5b506107ba60048036038101906107b59190612fa6565b611735565b005b3480156107c857600080fd5b506107e360048036038101906107de9190613297565b61175a565b6040516107f09190612bda565b60405180910390f35b34801561080557600080fd5b50610820600480360381019061081b91906132d7565b6117ee565b005b34801561082e57600080fd5b5061084960048036038101906108449190613026565b6118b0565b005b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061091657507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610926575061092582611933565b5b9050919050565b60606000805461093c90613346565b80601f016020809104026020016040519081016040528092919081815260200182805461096890613346565b80156109b55780601f1061098a576101008083540402835291602001916109b5565b820191906000526020600020905b81548152906001019060200180831161099857829003601f168201915b5050505050905090565b60006109ca8261199d565b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610a108261108c565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603610a80576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a77906133e9565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610a9f6119e8565b73ffffffffffffffffffffffffffffffffffffffff161480610ace5750610acd81610ac86119e8565b61175a565b5b610b0d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b049061347b565b60405180910390fd5b610b1783836119f0565b505050565b600b5481565b610b2a611aa9565b8060099081610b399190613647565b5050565b610b45611aa9565b80600e60006101000a81548160ff02191690831515021790555050565b6000610b6e6007611b27565b905090565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115610c6f576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401610bea929190613719565b6020604051808303816000875af1158015610c09573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c2d9190613757565b610c6e57336040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401610c659190612d4b565b60405180910390fd5b5b610c7a838383611b35565b505050565b610c87611aa9565b6000610c916111f8565b73ffffffffffffffffffffffffffffffffffffffff1647604051610cb4906137b5565b60006040518083038185875af1925050503d8060008114610cf1576040519150601f19603f3d011682016040523d82523d6000602084013e610cf6565b606091505b5050905080610d0457600080fd5b50565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115610e03576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401610d7e929190613719565b6020604051808303816000875af1158015610d9d573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610dc19190613757565b610e0257336040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401610df99190612d4b565b60405180910390fd5b5b610e0e838383611b95565b505050565b60606000610e2083611112565b905060008167ffffffffffffffff811115610e3e57610e3d612e06565b5b604051908082528060200260200182016040528015610e6c5781602001602082028036833780820191505090505b50905060006001905060005b8381108015610e895750600c548211155b15610f11576000610e998361108c565b90508673ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610efd5782848381518110610ee257610ee16137ca565b5b6020026020010181815250508180610ef990613828565b9250505b8280610f0890613828565b93505050610e78565b82945050505050919050565b610f25611aa9565b80600b8190555050565b610f37611aa9565b80600a9081610f469190613647565b5050565b600e60019054906101000a900460ff1681565b60098054610f6a90613346565b80601f0160208091040260200160405190810160405280929190818152602001828054610f9690613346565b8015610fe35780601f10610fb857610100808354040283529160200191610fe3565b820191906000526020600020905b815481529060010190602001808311610fc657829003601f168201915b505050505081565b600e60009054906101000a900460ff1681565b6008805461100b90613346565b80601f016020809104026020016040519081016040528092919081815260200182805461103790613346565b80156110845780601f1061105957610100808354040283529160200191611084565b820191906000526020600020905b81548152906001019060200180831161106757829003601f168201915b505050505081565b60008061109883611bb5565b9050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611109576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611100906138bc565b60405180910390fd5b80915050919050565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611182576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016111799061394e565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b6111d1611aa9565b6111db6000611bf2565b565b6111e5611aa9565b80600890816111f49190613647565b5050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b600d5481565b60606001805461123790613346565b80601f016020809104026020016040519081016040528092919081815260200182805461126390613346565b80156112b05780601f10611285576101008083540402835291602001916112b0565b820191906000526020600020905b81548152906001019060200180831161129357829003601f168201915b5050505050905090565b806000811180156112cd5750600d548111155b61130c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611303906139ba565b60405180910390fd5b600c548161131a6007611b27565b61132491906139da565b1115611365576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161135c90613a5a565b60405180910390fd5b600e60009054906101000a900460ff16156113b5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ac90613ac6565b60405180910390fd5b81600b546113c39190613ae6565b341015611405576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113fc90613b74565b60405180910390fd5b61140f3383611cb8565b5050565b61142561141e6119e8565b8383611cf8565b5050565b600a805461143690613346565b80601f016020809104026020016040519081016040528092919081815260200182805461146290613346565b80156114af5780601f10611484576101008083540402835291602001916114af565b820191906000526020600020905b81548152906001019060200180831161149257829003601f168201915b505050505081565b6114bf611aa9565b80600d8190555050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b11156115c5576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430336040518363ffffffff1660e01b8152600401611540929190613719565b6020604051808303816000875af115801561155f573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906115839190613757565b6115c457336040517fede71dcc0000000000000000000000000000000000000000000000000000000081526004016115bb9190612d4b565b60405180910390fd5b5b6115d184848484611e64565b50505050565b60606115e282611ec6565b611621576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161161890613c06565b60405180910390fd5b60001515600e60019054906101000a900460ff161515036116ce57600a805461164990613346565b80601f016020809104026020016040519081016040528092919081815260200182805461167590613346565b80156116c25780601f10611697576101008083540402835291602001916116c2565b820191906000526020600020905b8154815290600101906020018083116116a557829003601f168201915b5050505050905061172a565b60006116d8611f07565b905060008151116116f85760405180602001604052806000815250611726565b8061170284611f99565b600960405160200161171693929190613ce5565b6040516020818303038152906040525b9150505b919050565b600c5481565b61173d611aa9565b80600e60016101000a81548160ff02191690831515021790555050565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b816000811180156118015750600d548111155b611840576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611837906139ba565b60405180910390fd5b600c548161184e6007611b27565b61185891906139da565b1115611899576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161189090613a5a565b60405180910390fd5b6118a1611aa9565b6118ab8284611cb8565b505050565b6118b8611aa9565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611927576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161191e90613d88565b60405180910390fd5b61193081611bf2565b50565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b6119a681611ec6565b6119e5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119dc906138bc565b60405180910390fd5b50565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611a638361108c565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b611ab16119e8565b73ffffffffffffffffffffffffffffffffffffffff16611acf6111f8565b73ffffffffffffffffffffffffffffffffffffffff1614611b25576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b1c90613df4565b60405180910390fd5b565b600081600001549050919050565b611b46611b406119e8565b82612067565b611b85576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b7c90613e86565b60405180910390fd5b611b908383836120fc565b505050565b611bb0838383604051806020016040528060008152506114c9565b505050565b60006002600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000600660009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60005b81811015611cf357611ccd60076123f5565b611ce083611cdb6007611b27565b61240b565b8080611ceb90613828565b915050611cbb565b505050565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d66576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d5d90613ef2565b60405180910390fd5b80600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051611e579190612bda565b60405180910390a3505050565b611e75611e6f6119e8565b83612067565b611eb4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611eab90613e86565b60405180910390fd5b611ec084848484612429565b50505050565b60008073ffffffffffffffffffffffffffffffffffffffff16611ee883611bb5565b73ffffffffffffffffffffffffffffffffffffffff1614159050919050565b606060088054611f1690613346565b80601f0160208091040260200160405190810160405280929190818152602001828054611f4290613346565b8015611f8f5780601f10611f6457610100808354040283529160200191611f8f565b820191906000526020600020905b815481529060010190602001808311611f7257829003601f168201915b5050505050905090565b606060006001611fa884612485565b01905060008167ffffffffffffffff811115611fc757611fc6612e06565b5b6040519080825280601f01601f191660200182016040528015611ff95781602001600182028036833780820191505090505b509050600082602001820190505b60011561205c578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a85816120505761204f613f12565b5b04945060008503612007575b819350505050919050565b6000806120738361108c565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806120b557506120b4818561175a565b5b806120f357508373ffffffffffffffffffffffffffffffffffffffff166120db846109bf565b73ffffffffffffffffffffffffffffffffffffffff16145b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661211c8261108c565b73ffffffffffffffffffffffffffffffffffffffff1614612172576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161216990613fb3565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16036121e1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016121d890614045565b60405180910390fd5b6121ee83838360016125d8565b8273ffffffffffffffffffffffffffffffffffffffff1661220e8261108c565b73ffffffffffffffffffffffffffffffffffffffff1614612264576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161225b90613fb3565b60405180910390fd5b6004600082815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff02191690556001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825403925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a46123f083838360016126fe565b505050565b6001816000016000828254019250508190555050565b612425828260405180602001604052806000815250612704565b5050565b6124348484846120fc565b6124408484848461275f565b61247f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612476906140d7565b60405180910390fd5b50505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083106124e3577a184f03e93ff9f4daa797ed6e38ed64bf6a1f01000000000000000083816124d9576124d8613f12565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310612520576d04ee2d6d415b85acef8100000000838161251657612515613f12565b5b0492506020810190505b662386f26fc10000831061254f57662386f26fc10000838161254557612544613f12565b5b0492506010810190505b6305f5e1008310612578576305f5e100838161256e5761256d613f12565b5b0492506008810190505b612710831061259d57612710838161259357612592613f12565b5b0492506004810190505b606483106125c057606483816125b6576125b5613f12565b5b0492506002810190505b600a83106125cf576001810190505b80915050919050565b60018111156126f857600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161461266c5780600360008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461266491906140f7565b925050819055505b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16146126f75780600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546126ef91906139da565b925050819055505b5b50505050565b50505050565b61270e83836128e6565b61271b600084848461275f565b61275a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612751906140d7565b60405180910390fd5b505050565b60006127808473ffffffffffffffffffffffffffffffffffffffff16612b03565b156128d9578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026127a96119e8565b8786866040518563ffffffff1660e01b81526004016127cb9493929190614180565b6020604051808303816000875af192505050801561280757506040513d601f19601f8201168201806040525081019061280491906141e1565b60015b612889573d8060008114612837576040519150601f19603f3d011682016040523d82523d6000602084013e61283c565b606091505b506000815103612881576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612878906140d7565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149150506128de565b600190505b949350505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603612955576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161294c9061425a565b60405180910390fd5b61295e81611ec6565b1561299e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612995906142c6565b60405180910390fd5b6129ac6000838360016125d8565b6129b581611ec6565b156129f5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016129ec906142c6565b60405180910390fd5b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4612aff6000838360016126fe565b5050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b612b6f81612b3a565b8114612b7a57600080fd5b50565b600081359050612b8c81612b66565b92915050565b600060208284031215612ba857612ba7612b30565b5b6000612bb684828501612b7d565b91505092915050565b60008115159050919050565b612bd481612bbf565b82525050565b6000602082019050612bef6000830184612bcb565b92915050565b600081519050919050565b600082825260208201905092915050565b60005b83811015612c2f578082015181840152602081019050612c14565b60008484015250505050565b6000601f19601f8301169050919050565b6000612c5782612bf5565b612c618185612c00565b9350612c71818560208601612c11565b612c7a81612c3b565b840191505092915050565b60006020820190508181036000830152612c9f8184612c4c565b905092915050565b6000819050919050565b612cba81612ca7565b8114612cc557600080fd5b50565b600081359050612cd781612cb1565b92915050565b600060208284031215612cf357612cf2612b30565b5b6000612d0184828501612cc8565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000612d3582612d0a565b9050919050565b612d4581612d2a565b82525050565b6000602082019050612d606000830184612d3c565b92915050565b612d6f81612d2a565b8114612d7a57600080fd5b50565b600081359050612d8c81612d66565b92915050565b60008060408385031215612da957612da8612b30565b5b6000612db785828601612d7d565b9250506020612dc885828601612cc8565b9150509250929050565b612ddb81612ca7565b82525050565b6000602082019050612df66000830184612dd2565b92915050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b612e3e82612c3b565b810181811067ffffffffffffffff82111715612e5d57612e5c612e06565b5b80604052505050565b6000612e70612b26565b9050612e7c8282612e35565b919050565b600067ffffffffffffffff821115612e9c57612e9b612e06565b5b612ea582612c3b565b9050602081019050919050565b82818337600083830152505050565b6000612ed4612ecf84612e81565b612e66565b905082815260208101848484011115612ef057612eef612e01565b5b612efb848285612eb2565b509392505050565b600082601f830112612f1857612f17612dfc565b5b8135612f28848260208601612ec1565b91505092915050565b600060208284031215612f4757612f46612b30565b5b600082013567ffffffffffffffff811115612f6557612f64612b35565b5b612f7184828501612f03565b91505092915050565b612f8381612bbf565b8114612f8e57600080fd5b50565b600081359050612fa081612f7a565b92915050565b600060208284031215612fbc57612fbb612b30565b5b6000612fca84828501612f91565b91505092915050565b600080600060608486031215612fec57612feb612b30565b5b6000612ffa86828701612d7d565b935050602061300b86828701612d7d565b925050604061301c86828701612cc8565b9150509250925092565b60006020828403121561303c5761303b612b30565b5b600061304a84828501612d7d565b91505092915050565b600081519050919050565b600082825260208201905092915050565b6000819050602082019050919050565b61308881612ca7565b82525050565b600061309a838361307f565b60208301905092915050565b6000602082019050919050565b60006130be82613053565b6130c8818561305e565b93506130d38361306f565b8060005b838110156131045781516130eb888261308e565b97506130f6836130a6565b9250506001810190506130d7565b5085935050505092915050565b6000602082019050818103600083015261312b81846130b3565b905092915050565b6000806040838503121561314a57613149612b30565b5b600061315885828601612d7d565b925050602061316985828601612f91565b9150509250929050565b600067ffffffffffffffff82111561318e5761318d612e06565b5b61319782612c3b565b9050602081019050919050565b60006131b76131b284613173565b612e66565b9050828152602081018484840111156131d3576131d2612e01565b5b6131de848285612eb2565b509392505050565b600082601f8301126131fb576131fa612dfc565b5b813561320b8482602086016131a4565b91505092915050565b6000806000806080858703121561322e5761322d612b30565b5b600061323c87828801612d7d565b945050602061324d87828801612d7d565b935050604061325e87828801612cc8565b925050606085013567ffffffffffffffff81111561327f5761327e612b35565b5b61328b878288016131e6565b91505092959194509250565b600080604083850312156132ae576132ad612b30565b5b60006132bc85828601612d7d565b92505060206132cd85828601612d7d565b9150509250929050565b600080604083850312156132ee576132ed612b30565b5b60006132fc85828601612cc8565b925050602061330d85828601612d7d565b9150509250929050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b6000600282049050600182168061335e57607f821691505b60208210810361337157613370613317565b5b50919050565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b60006133d3602183612c00565b91506133de82613377565b604082019050919050565b60006020820190508181036000830152613402816133c6565b9050919050565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60008201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c000000602082015250565b6000613465603d83612c00565b915061347082613409565b604082019050919050565b6000602082019050818103600083015261349481613458565b9050919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026134fd7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826134c0565b61350786836134c0565b95508019841693508086168417925050509392505050565b6000819050919050565b600061354461353f61353a84612ca7565b61351f565b612ca7565b9050919050565b6000819050919050565b61355e83613529565b61357261356a8261354b565b8484546134cd565b825550505050565b600090565b61358761357a565b613592818484613555565b505050565b5b818110156135b6576135ab60008261357f565b600181019050613598565b5050565b601f8211156135fb576135cc8161349b565b6135d5846134b0565b810160208510156135e4578190505b6135f86135f0856134b0565b830182613597565b50505b505050565b600082821c905092915050565b600061361e60001984600802613600565b1980831691505092915050565b6000613637838361360d565b9150826002028217905092915050565b61365082612bf5565b67ffffffffffffffff81111561366957613668612e06565b5b6136738254613346565b61367e8282856135ba565b600060209050601f8311600181146136b1576000841561369f578287015190505b6136a9858261362b565b865550613711565b601f1984166136bf8661349b565b60005b828110156136e7578489015182556001820191506020850194506020810190506136c2565b868310156137045784890151613700601f89168261360d565b8355505b6001600288020188555050505b505050505050565b600060408201905061372e6000830185612d3c565b61373b6020830184612d3c565b9392505050565b60008151905061375181612f7a565b92915050565b60006020828403121561376d5761376c612b30565b5b600061377b84828501613742565b91505092915050565b600081905092915050565b50565b600061379f600083613784565b91506137aa8261378f565b600082019050919050565b60006137c082613792565b9150819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061383382612ca7565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8203613865576138646137f9565b5b600182019050919050565b7f4552433732313a20696e76616c696420746f6b656e2049440000000000000000600082015250565b60006138a6601883612c00565b91506138b182613870565b602082019050919050565b600060208201905081810360008301526138d581613899565b9050919050565b7f4552433732313a2061646472657373207a65726f206973206e6f74206120766160008201527f6c6964206f776e65720000000000000000000000000000000000000000000000602082015250565b6000613938602983612c00565b9150613943826138dc565b604082019050919050565b600060208201905081810360008301526139678161392b565b9050919050565b7f496e76616c6964206d696e7420616d6f756e7421000000000000000000000000600082015250565b60006139a4601483612c00565b91506139af8261396e565b602082019050919050565b600060208201905081810360008301526139d381613997565b9050919050565b60006139e582612ca7565b91506139f083612ca7565b9250828201905080821115613a0857613a076137f9565b5b92915050565b7f4d617820737570706c7920657863656564656421000000000000000000000000600082015250565b6000613a44601483612c00565b9150613a4f82613a0e565b602082019050919050565b60006020820190508181036000830152613a7381613a37565b9050919050565b7f54686520636f6e74726163742069732070617573656421000000000000000000600082015250565b6000613ab0601783612c00565b9150613abb82613a7a565b602082019050919050565b60006020820190508181036000830152613adf81613aa3565b9050919050565b6000613af182612ca7565b9150613afc83612ca7565b9250828202613b0a81612ca7565b91508282048414831517613b2157613b206137f9565b5b5092915050565b7f496e73756666696369656e742066756e64732100000000000000000000000000600082015250565b6000613b5e601383612c00565b9150613b6982613b28565b602082019050919050565b60006020820190508181036000830152613b8d81613b51565b9050919050565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b6000613bf0602f83612c00565b9150613bfb82613b94565b604082019050919050565b60006020820190508181036000830152613c1f81613be3565b9050919050565b600081905092915050565b6000613c3c82612bf5565b613c468185613c26565b9350613c56818560208601612c11565b80840191505092915050565b60008154613c6f81613346565b613c798186613c26565b94506001821660008114613c945760018114613ca957613cdc565b60ff1983168652811515820286019350613cdc565b613cb28561349b565b60005b83811015613cd457815481890152600182019150602081019050613cb5565b838801955050505b50505092915050565b6000613cf18286613c31565b9150613cfd8285613c31565b9150613d098284613c62565b9150819050949350505050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b6000613d72602683612c00565b9150613d7d82613d16565b604082019050919050565b60006020820190508181036000830152613da181613d65565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b6000613dde602083612c00565b9150613de982613da8565b602082019050919050565b60006020820190508181036000830152613e0d81613dd1565b9050919050565b7f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560008201527f72206f7220617070726f76656400000000000000000000000000000000000000602082015250565b6000613e70602d83612c00565b9150613e7b82613e14565b604082019050919050565b60006020820190508181036000830152613e9f81613e63565b9050919050565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b6000613edc601983612c00565b9150613ee782613ea6565b602082019050919050565b60006020820190508181036000830152613f0b81613ecf565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4552433732313a207472616e736665722066726f6d20696e636f72726563742060008201527f6f776e6572000000000000000000000000000000000000000000000000000000602082015250565b6000613f9d602583612c00565b9150613fa882613f41565b604082019050919050565b60006020820190508181036000830152613fcc81613f90565b9050919050565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b600061402f602483612c00565b915061403a82613fd3565b604082019050919050565b6000602082019050818103600083015261405e81614022565b9050919050565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b60006140c1603283612c00565b91506140cc82614065565b604082019050919050565b600060208201905081810360008301526140f0816140b4565b9050919050565b600061410282612ca7565b915061410d83612ca7565b9250828203905081811115614125576141246137f9565b5b92915050565b600081519050919050565b600082825260208201905092915050565b60006141528261412b565b61415c8185614136565b935061416c818560208601612c11565b61417581612c3b565b840191505092915050565b60006080820190506141956000830187612d3c565b6141a26020830186612d3c565b6141af6040830185612dd2565b81810360608301526141c18184614147565b905095945050505050565b6000815190506141db81612b66565b92915050565b6000602082840312156141f7576141f6612b30565b5b6000614205848285016141cc565b91505092915050565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b6000614244602083612c00565b915061424f8261420e565b602082019050919050565b6000602082019050818103600083015261427381614237565b9050919050565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b60006142b0601c83612c00565b91506142bb8261427a565b602082019050919050565b600060208201905081810360008301526142df816142a3565b905091905056fea26469706673582212205f4178fd6fc4e248c7e092bbf2c60e525be5860531b8d2342a4a158287e4e08f64736f6c63430008110033

Deployed Bytecode Sourcemap

73422:4690:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57486:305;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58414:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;59926:171;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;59444:416;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;73778:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;76570:100;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;76676:77;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;74371:89;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;77547:157;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;76759:462;;;;;;;;;;;;;:::i;:::-;;77712:165;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;74882:635;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;76110:74;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;76326:132;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;73928:28;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73700:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73898:25;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73613:82;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58124:223;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57855:207;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;36917:103;;;;;;;;;;;;;:::i;:::-;;76464:100;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;36269:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73853:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58583:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74466:247;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;60169:155;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;73738:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;76190:130;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;77885:222;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;75523:494;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;73817:31;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;76023:81;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;60395:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;74721:155;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;37175:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57486:305;57588:4;57640:25;57625:40;;;:11;:40;;;;:105;;;;57697:33;57682:48;;;:11;:48;;;;57625:105;:158;;;;57747:36;57771:11;57747:23;:36::i;:::-;57625:158;57605:178;;57486:305;;;:::o;58414:100::-;58468:13;58501:5;58494:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58414:100;:::o;59926:171::-;60002:7;60022:23;60037:7;60022:14;:23::i;:::-;60065:15;:24;60081:7;60065:24;;;;;;;;;;;;;;;;;;;;;60058:31;;59926:171;;;:::o;59444:416::-;59525:13;59541:23;59556:7;59541:14;:23::i;:::-;59525:39;;59589:5;59583:11;;:2;:11;;;59575:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;59683:5;59667:21;;:12;:10;:12::i;:::-;:21;;;:62;;;;59692:37;59709:5;59716:12;:10;:12::i;:::-;59692:16;:37::i;:::-;59667:62;59645:173;;;;;;;;;;;;:::i;:::-;;;;;;;;;59831:21;59840:2;59844:7;59831:8;:21::i;:::-;59514:346;59444:416;;:::o;73778:34::-;;;;:::o;76570:100::-;36155:13;:11;:13::i;:::-;76654:10:::1;76642:9;:22;;;;;;:::i;:::-;;76570:100:::0;:::o;76676:77::-;36155:13;:11;:13::i;:::-;76741:6:::1;76732;;:15;;;;;;;;;;;;;;;;;;76676:77:::0;:::o;74371:89::-;74415:7;74438:16;:6;:14;:16::i;:::-;74431:23;;74371:89;:::o;77547:157::-;16970:1;15796:42;16924:43;;;:47;16920:225;;;15796:42;16993:40;;;17042:4;17049:10;16993:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;16988:146;;17107:10;17088:30;;;;;;;;;;;:::i;:::-;;;;;;;;16988:146;16920:225;77659:37:::1;77678:4;77684:2;77688:7;77659:18;:37::i;:::-;77547:157:::0;;;:::o;76759:462::-;36155:13;:11;:13::i;:::-;77043:7:::1;77064;:5;:7::i;:::-;77056:21;;77085;77056:55;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77042:69;;;77126:2;77118:11;;;::::0;::::1;;76796:425;76759:462::o:0;77712:165::-;16970:1;15796:42;16924:43;;;:47;16920:225;;;15796:42;16993:40;;;17042:4;17049:10;16993:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;16988:146;;17107:10;17088:30;;;;;;;;;;;:::i;:::-;;;;;;;;16988:146;16920:225;77828:41:::1;77851:4;77857:2;77861:7;77828:22;:41::i;:::-;77712:165:::0;;;:::o;74882:635::-;74957:16;74985:23;75011:17;75021:6;75011:9;:17::i;:::-;74985:43;;75035:30;75082:15;75068:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75035:63;;75105:22;75130:1;75105:26;;75138:23;75174:309;75199:15;75181;:33;:64;;;;;75236:9;;75218:14;:27;;75181:64;75174:309;;;75256:25;75284:23;75292:14;75284:7;:23::i;:::-;75256:51;;75343:6;75322:27;;:17;:27;;;75318:131;;75395:14;75362:13;75376:15;75362:30;;;;;;;;:::i;:::-;;;;;;;:47;;;;;75422:17;;;;;:::i;:::-;;;;75318:131;75459:16;;;;;:::i;:::-;;;;75247:236;75174:309;;;75498:13;75491:20;;;;;;74882:635;;;:::o;76110:74::-;36155:13;:11;:13::i;:::-;76173:5:::1;76166:4;:12;;;;76110:74:::0;:::o;76326:132::-;36155:13;:11;:13::i;:::-;76434:18:::1;76414:17;:38;;;;;;:::i;:::-;;76326:132:::0;:::o;73928:28::-;;;;;;;;;;;;;:::o;73700:33::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;73898:25::-;;;;;;;;;;;;;:::o;73613:82::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;58124:223::-;58196:7;58216:13;58232:17;58241:7;58232:8;:17::i;:::-;58216:33;;58285:1;58268:19;;:5;:19;;;58260:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;58334:5;58327:12;;;58124:223;;;:::o;57855:207::-;57927:7;57972:1;57955:19;;:5;:19;;;57947:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;58038:9;:16;58048:5;58038:16;;;;;;;;;;;;;;;;58031:23;;57855:207;;;:::o;36917:103::-;36155:13;:11;:13::i;:::-;36982:30:::1;37009:1;36982:18;:30::i;:::-;36917:103::o:0;76464:100::-;36155:13;:11;:13::i;:::-;76548:10:::1;76536:9;:22;;;;;;:::i;:::-;;76464:100:::0;:::o;36269:87::-;36315:7;36342:6;;;;;;;;;;;36335:13;;36269:87;:::o;73853:38::-;;;;:::o;58583:104::-;58639:13;58672:7;58665:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;58583:104;:::o;74466:247::-;74531:11;74205:1;74191:11;:15;:52;;;;;74225:18;;74210:11;:33;;74191:52;74183:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;74317:9;;74302:11;74283:16;:6;:14;:16::i;:::-;:30;;;;:::i;:::-;:43;;74275:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;74560:6:::1;;;;;;;;;;;74559:7;74551:43;;;;;;;;;;;;:::i;:::-;;;;;;;;;74629:11;74622:4;;:18;;;;:::i;:::-;74609:9;:31;;74601:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;74673:34;74683:10;74695:11;74673:9;:34::i;:::-;74466:247:::0;;:::o;60169:155::-;60264:52;60283:12;:10;:12::i;:::-;60297:8;60307;60264:18;:52::i;:::-;60169:155;;:::o;73738:31::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;76190:130::-;36155:13;:11;:13::i;:::-;76295:19:::1;76274:18;:40;;;;76190:130:::0;:::o;77885:222::-;16970:1;15796:42;16924:43;;;:47;16920:225;;;15796:42;16993:40;;;17042:4;17049:10;16993:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;16988:146;;17107:10;17088:30;;;;;;;;;;;:::i;:::-;;;;;;;;16988:146;16920:225;78052:47:::1;78075:4;78081:2;78085:7;78094:4;78052:22;:47::i;:::-;77885:222:::0;;;;:::o;75523:494::-;75622:13;75663:17;75671:8;75663:7;:17::i;:::-;75647:98;;;;;;;;;;;;:::i;:::-;;;;;;;;;75770:5;75758:17;;:8;;;;;;;;;;;:17;;;75754:64;;75793:17;75786:24;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;75754:64;75826:28;75857:10;:8;:10::i;:::-;75826:41;;75912:1;75887:14;75881:28;:32;:130;;;;;;;;;;;;;;;;;75949:14;75965:19;:8;:17;:19::i;:::-;75986:9;75932:64;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;75881:130;75874:137;;;75523:494;;;;:::o;73817:31::-;;;;:::o;76023:81::-;36155:13;:11;:13::i;:::-;76092:6:::1;76081:8;;:17;;;;;;;;;;;;;;;;;;76023:81:::0;:::o;60395:164::-;60492:4;60516:18;:25;60535:5;60516:25;;;;;;;;;;;;;;;:35;60542:8;60516:35;;;;;;;;;;;;;;;;;;;;;;;;;60509:42;;60395:164;;;;:::o;74721:155::-;74807:11;74205:1;74191:11;:15;:52;;;;;74225:18;;74210:11;:33;;74191:52;74183:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;74317:9;;74302:11;74283:16;:6;:14;:16::i;:::-;:30;;;;:::i;:::-;:43;;74275:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;36155:13:::1;:11;:13::i;:::-;74837:33:::2;74847:9;74858:11;74837:9;:33::i;:::-;74721:155:::0;;;:::o;37175:201::-;36155:13;:11;:13::i;:::-;37284:1:::1;37264:22;;:8;:22;;::::0;37256:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;37340:28;37359:8;37340:18;:28::i;:::-;37175:201:::0;:::o;49998:157::-;50083:4;50122:25;50107:40;;;:11;:40;;;;50100:47;;49998:157;;;:::o;69745:135::-;69827:16;69835:7;69827;:16::i;:::-;69819:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;69745:135;:::o;34820:98::-;34873:7;34900:10;34893:17;;34820:98;:::o;69024:174::-;69126:2;69099:15;:24;69115:7;69099:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;69182:7;69178:2;69144:46;;69153:23;69168:7;69153:14;:23::i;:::-;69144:46;;;;;;;;;;;;69024:174;;:::o;36434:132::-;36509:12;:10;:12::i;:::-;36498:23;;:7;:5;:7::i;:::-;:23;;;36490:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;36434:132::o;18349:114::-;18414:7;18441;:14;;;18434:21;;18349:114;;;:::o;60626:335::-;60821:41;60840:12;:10;:12::i;:::-;60854:7;60821:18;:41::i;:::-;60813:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;60925:28;60935:4;60941:2;60945:7;60925:9;:28::i;:::-;60626:335;;;:::o;61032:185::-;61170:39;61187:4;61193:2;61197:7;61170:39;;;;;;;;;;;;:16;:39::i;:::-;61032:185;;;:::o;62918:117::-;62984:7;63011;:16;63019:7;63011:16;;;;;;;;;;;;;;;;;;;;;63004:23;;62918:117;;;:::o;37536:191::-;37610:16;37629:6;;;;;;;;;;;37610:25;;37655:8;37646:6;;:17;;;;;;;;;;;;;;;;;;37710:8;37679:40;;37700:8;37679:40;;;;;;;;;;;;37599:128;37536:191;:::o;77227:204::-;77307:9;77302:124;77326:11;77322:1;:15;77302:124;;;77353:18;:6;:16;:18::i;:::-;77380:38;77390:9;77401:16;:6;:14;:16::i;:::-;77380:9;:38::i;:::-;77339:3;;;;;:::i;:::-;;;;77302:124;;;;77227:204;;:::o;69341:315::-;69496:8;69487:17;;:5;:17;;;69479:55;;;;;;;;;;;;:::i;:::-;;;;;;;;;69583:8;69545:18;:25;69564:5;69545:25;;;;;;;;;;;;;;;:35;69571:8;69545:35;;;;;;;;;;;;;;;;:46;;;;;;;;;;;;;;;;;;69629:8;69607:41;;69622:5;69607:41;;;69639:8;69607:41;;;;;;:::i;:::-;;;;;;;;69341:315;;;:::o;61288:322::-;61462:41;61481:12;:10;:12::i;:::-;61495:7;61462:18;:41::i;:::-;61454:99;;;;;;;;;;;;:::i;:::-;;;;;;;;;61564:38;61578:4;61584:2;61588:7;61597:4;61564:13;:38::i;:::-;61288:322;;;;:::o;63348:128::-;63413:4;63466:1;63437:31;;:17;63446:7;63437:8;:17::i;:::-;:31;;;;63430:38;;63348:128;;;:::o;77437:104::-;77497:13;77526:9;77519:16;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;77437:104;:::o;32247:716::-;32303:13;32354:14;32391:1;32371:17;32382:5;32371:10;:17::i;:::-;:21;32354:38;;32407:20;32441:6;32430:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32407:41;;32463:11;32592:6;32588:2;32584:15;32576:6;32572:28;32565:35;;32629:288;32636:4;32629:288;;;32661:5;;;;;;;;32803:8;32798:2;32791:5;32787:14;32782:30;32777:3;32769:44;32859:2;32850:11;;;;;;:::i;:::-;;;;;32893:1;32884:5;:10;32629:288;32880:21;32629:288;32938:6;32931:13;;;;;32247:716;;;:::o;63643:264::-;63736:4;63753:13;63769:23;63784:7;63769:14;:23::i;:::-;63753:39;;63822:5;63811:16;;:7;:16;;;:52;;;;63831:32;63848:5;63855:7;63831:16;:32::i;:::-;63811:52;:87;;;;63891:7;63867:31;;:20;63879:7;63867:11;:20::i;:::-;:31;;;63811:87;63803:96;;;63643:264;;;;:::o;67642:1263::-;67801:4;67774:31;;:23;67789:7;67774:14;:23::i;:::-;:31;;;67766:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;67880:1;67866:16;;:2;:16;;;67858:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;67936:42;67957:4;67963:2;67967:7;67976:1;67936:20;:42::i;:::-;68108:4;68081:31;;:23;68096:7;68081:14;:23::i;:::-;:31;;;68073:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;68226:15;:24;68242:7;68226:24;;;;;;;;;;;;68219:31;;;;;;;;;;;68721:1;68702:9;:15;68712:4;68702:15;;;;;;;;;;;;;;;;:20;;;;;;;;;;;68754:1;68737:9;:13;68747:2;68737:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;68796:2;68777:7;:16;68785:7;68777:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;68835:7;68831:2;68816:27;;68825:4;68816:27;;;;;;;;;;;;68856:41;68876:4;68882:2;68886:7;68895:1;68856:19;:41::i;:::-;67642:1263;;;:::o;18471:127::-;18578:1;18560:7;:14;;;:19;;;;;;;;;;;18471:127;:::o;64249:110::-;64325:26;64335:2;64339:7;64325:26;;;;;;;;;;;;:9;:26::i;:::-;64249:110;;:::o;62491:313::-;62647:28;62657:4;62663:2;62667:7;62647:9;:28::i;:::-;62694:47;62717:4;62723:2;62727:7;62736:4;62694:22;:47::i;:::-;62686:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;62491:313;;;;:::o;29113:922::-;29166:7;29186:14;29203:1;29186:18;;29253:6;29244:5;:15;29240:102;;29289:6;29280:15;;;;;;:::i;:::-;;;;;29324:2;29314:12;;;;29240:102;29369:6;29360:5;:15;29356:102;;29405:6;29396:15;;;;;;:::i;:::-;;;;;29440:2;29430:12;;;;29356:102;29485:6;29476:5;:15;29472:102;;29521:6;29512:15;;;;;;:::i;:::-;;;;;29556:2;29546:12;;;;29472:102;29601:5;29592;:14;29588:99;;29636:5;29627:14;;;;;;:::i;:::-;;;;;29670:1;29660:11;;;;29588:99;29714:5;29705;:14;29701:99;;29749:5;29740:14;;;;;;:::i;:::-;;;;;29783:1;29773:11;;;;29701:99;29827:5;29818;:14;29814:99;;29862:5;29853:14;;;;;;:::i;:::-;;;;;29896:1;29886:11;;;;29814:99;29940:5;29931;:14;29927:66;;29976:1;29966:11;;;;29927:66;30021:6;30014:13;;;29113:922;;;:::o;72029:410::-;72219:1;72207:9;:13;72203:229;;;72257:1;72241:18;;:4;:18;;;72237:87;;72299:9;72280;:15;72290:4;72280:15;;;;;;;;;;;;;;;;:28;;;;;;;:::i;:::-;;;;;;;;72237:87;72356:1;72342:16;;:2;:16;;;72338:83;;72396:9;72379;:13;72389:2;72379:13;;;;;;;;;;;;;;;;:26;;;;;;;:::i;:::-;;;;;;;;72338:83;72203:229;72029:410;;;;:::o;73161:158::-;;;;;:::o;64586:319::-;64715:18;64721:2;64725:7;64715:5;:18::i;:::-;64766:53;64797:1;64801:2;64805:7;64814:4;64766:22;:53::i;:::-;64744:153;;;;;;;;;;;;:::i;:::-;;;;;;;;;64586:319;;;:::o;70444:853::-;70598:4;70619:15;:2;:13;;;:15::i;:::-;70615:675;;;70671:2;70655:36;;;70692:12;:10;:12::i;:::-;70706:4;70712:7;70721:4;70655:71;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;70651:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;70913:1;70896:6;:13;:18;70892:328;;70939:60;;;;;;;;;;:::i;:::-;;;;;;;;70892:328;71170:6;71164:13;71155:6;71151:2;71147:15;71140:38;70651:584;70787:41;;;70777:51;;;:6;:51;;;;70770:58;;;;;70615:675;71274:4;71267:11;;70444:853;;;;;;;:::o;65241:942::-;65335:1;65321:16;;:2;:16;;;65313:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;65394:16;65402:7;65394;:16::i;:::-;65393:17;65385:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;65456:48;65485:1;65489:2;65493:7;65502:1;65456:20;:48::i;:::-;65603:16;65611:7;65603;:16::i;:::-;65602:17;65594:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;66018:1;66001:9;:13;66011:2;66001:13;;;;;;;;;;;;;;;;:18;;;;;;;;;;;66062:2;66043:7;:16;66051:7;66043:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;66107:7;66103:2;66082:33;;66099:1;66082:33;;;;;;;;;;;;66128:47;66156:1;66160:2;66164:7;66173:1;66128:19;:47::i;:::-;65241:942;;:::o;38967:326::-;39027:4;39284:1;39262:7;:19;;;:23;39255:30;;38967:326;;;:::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:99::-;1570:6;1604:5;1598:12;1588:22;;1518:99;;;:::o;1623:169::-;1707:11;1741:6;1736:3;1729:19;1781:4;1776:3;1772:14;1757:29;;1623:169;;;;:::o;1798:246::-;1879:1;1889:113;1903:6;1900:1;1897:13;1889:113;;;1988:1;1983:3;1979:11;1973:18;1969:1;1964:3;1960:11;1953:39;1925:2;1922:1;1918:10;1913:15;;1889:113;;;2036:1;2027:6;2022:3;2018:16;2011:27;1860:184;1798:246;;;:::o;2050:102::-;2091:6;2142:2;2138:7;2133:2;2126:5;2122:14;2118:28;2108:38;;2050:102;;;:::o;2158:377::-;2246:3;2274:39;2307:5;2274:39;:::i;:::-;2329:71;2393:6;2388:3;2329:71;:::i;:::-;2322:78;;2409:65;2467:6;2462:3;2455:4;2448:5;2444:16;2409:65;:::i;:::-;2499:29;2521:6;2499:29;:::i;:::-;2494:3;2490:39;2483:46;;2250:285;2158:377;;;;:::o;2541:313::-;2654:4;2692:2;2681:9;2677:18;2669:26;;2741:9;2735:4;2731:20;2727:1;2716:9;2712:17;2705:47;2769:78;2842:4;2833:6;2769:78;:::i;:::-;2761:86;;2541:313;;;;:::o;2860:77::-;2897:7;2926:5;2915:16;;2860:77;;;:::o;2943:122::-;3016:24;3034:5;3016:24;:::i;:::-;3009:5;3006:35;2996:63;;3055:1;3052;3045:12;2996:63;2943:122;:::o;3071:139::-;3117:5;3155:6;3142:20;3133:29;;3171:33;3198:5;3171:33;:::i;:::-;3071:139;;;;:::o;3216:329::-;3275:6;3324:2;3312:9;3303:7;3299:23;3295:32;3292:119;;;3330:79;;:::i;:::-;3292:119;3450:1;3475:53;3520:7;3511:6;3500:9;3496:22;3475:53;:::i;:::-;3465:63;;3421:117;3216:329;;;;:::o;3551:126::-;3588:7;3628:42;3621:5;3617:54;3606:65;;3551:126;;;:::o;3683:96::-;3720:7;3749:24;3767:5;3749:24;:::i;:::-;3738:35;;3683:96;;;:::o;3785:118::-;3872:24;3890:5;3872:24;:::i;:::-;3867:3;3860:37;3785:118;;:::o;3909:222::-;4002:4;4040:2;4029:9;4025:18;4017:26;;4053:71;4121:1;4110:9;4106:17;4097:6;4053:71;:::i;:::-;3909:222;;;;:::o;4137:122::-;4210:24;4228:5;4210:24;:::i;:::-;4203:5;4200:35;4190:63;;4249:1;4246;4239:12;4190:63;4137:122;:::o;4265:139::-;4311:5;4349:6;4336:20;4327:29;;4365:33;4392:5;4365:33;:::i;:::-;4265:139;;;;:::o;4410:474::-;4478:6;4486;4535:2;4523:9;4514:7;4510:23;4506:32;4503:119;;;4541:79;;:::i;:::-;4503:119;4661:1;4686:53;4731:7;4722:6;4711:9;4707:22;4686:53;:::i;:::-;4676:63;;4632:117;4788:2;4814:53;4859:7;4850:6;4839:9;4835:22;4814:53;:::i;:::-;4804:63;;4759:118;4410:474;;;;;:::o;4890:118::-;4977:24;4995:5;4977:24;:::i;:::-;4972:3;4965:37;4890:118;;:::o;5014:222::-;5107:4;5145:2;5134:9;5130:18;5122:26;;5158:71;5226:1;5215:9;5211:17;5202:6;5158:71;:::i;:::-;5014:222;;;;:::o;5242:117::-;5351:1;5348;5341:12;5365:117;5474:1;5471;5464:12;5488:180;5536:77;5533:1;5526:88;5633:4;5630:1;5623:15;5657:4;5654:1;5647:15;5674:281;5757:27;5779:4;5757:27;:::i;:::-;5749:6;5745:40;5887:6;5875:10;5872:22;5851:18;5839:10;5836:34;5833:62;5830:88;;;5898:18;;:::i;:::-;5830:88;5938:10;5934:2;5927:22;5717:238;5674:281;;:::o;5961:129::-;5995:6;6022:20;;:::i;:::-;6012:30;;6051:33;6079:4;6071:6;6051:33;:::i;:::-;5961:129;;;:::o;6096:308::-;6158:4;6248:18;6240:6;6237:30;6234:56;;;6270:18;;:::i;:::-;6234:56;6308:29;6330:6;6308:29;:::i;:::-;6300:37;;6392:4;6386;6382:15;6374:23;;6096:308;;;:::o;6410:146::-;6507:6;6502:3;6497;6484:30;6548:1;6539:6;6534:3;6530:16;6523:27;6410:146;;;:::o;6562:425::-;6640:5;6665:66;6681:49;6723:6;6681:49;:::i;:::-;6665:66;:::i;:::-;6656:75;;6754:6;6747:5;6740:21;6792:4;6785:5;6781:16;6830:3;6821:6;6816:3;6812:16;6809:25;6806:112;;;6837:79;;:::i;:::-;6806:112;6927:54;6974:6;6969:3;6964;6927:54;:::i;:::-;6646:341;6562:425;;;;;:::o;7007:340::-;7063:5;7112:3;7105:4;7097:6;7093:17;7089:27;7079:122;;7120:79;;:::i;:::-;7079:122;7237:6;7224:20;7262:79;7337:3;7329:6;7322:4;7314:6;7310:17;7262:79;:::i;:::-;7253:88;;7069:278;7007:340;;;;:::o;7353:509::-;7422:6;7471:2;7459:9;7450:7;7446:23;7442:32;7439:119;;;7477:79;;:::i;:::-;7439:119;7625:1;7614:9;7610:17;7597:31;7655:18;7647:6;7644:30;7641:117;;;7677:79;;:::i;:::-;7641:117;7782:63;7837:7;7828:6;7817:9;7813:22;7782:63;:::i;:::-;7772:73;;7568:287;7353:509;;;;:::o;7868:116::-;7938:21;7953:5;7938:21;:::i;:::-;7931:5;7928:32;7918:60;;7974:1;7971;7964:12;7918:60;7868:116;:::o;7990:133::-;8033:5;8071:6;8058:20;8049:29;;8087:30;8111:5;8087:30;:::i;:::-;7990:133;;;;:::o;8129:323::-;8185:6;8234:2;8222:9;8213:7;8209:23;8205:32;8202:119;;;8240:79;;:::i;:::-;8202:119;8360:1;8385:50;8427:7;8418:6;8407:9;8403:22;8385:50;:::i;:::-;8375:60;;8331:114;8129:323;;;;:::o;8458:619::-;8535:6;8543;8551;8600:2;8588:9;8579:7;8575:23;8571:32;8568:119;;;8606:79;;:::i;:::-;8568:119;8726:1;8751:53;8796:7;8787:6;8776:9;8772:22;8751:53;:::i;:::-;8741:63;;8697:117;8853:2;8879:53;8924:7;8915:6;8904:9;8900:22;8879:53;:::i;:::-;8869:63;;8824:118;8981:2;9007:53;9052:7;9043:6;9032:9;9028:22;9007:53;:::i;:::-;8997:63;;8952:118;8458:619;;;;;:::o;9083:329::-;9142:6;9191:2;9179:9;9170:7;9166:23;9162:32;9159:119;;;9197:79;;:::i;:::-;9159:119;9317:1;9342:53;9387:7;9378:6;9367:9;9363:22;9342:53;:::i;:::-;9332:63;;9288:117;9083:329;;;;:::o;9418:114::-;9485:6;9519:5;9513:12;9503:22;;9418:114;;;:::o;9538:184::-;9637:11;9671:6;9666:3;9659:19;9711:4;9706:3;9702:14;9687:29;;9538:184;;;;:::o;9728:132::-;9795:4;9818:3;9810:11;;9848:4;9843:3;9839:14;9831:22;;9728:132;;;:::o;9866:108::-;9943:24;9961:5;9943:24;:::i;:::-;9938:3;9931:37;9866:108;;:::o;9980:179::-;10049:10;10070:46;10112:3;10104:6;10070:46;:::i;:::-;10148:4;10143:3;10139:14;10125:28;;9980:179;;;;:::o;10165:113::-;10235:4;10267;10262:3;10258:14;10250:22;;10165:113;;;:::o;10314:732::-;10433:3;10462:54;10510:5;10462:54;:::i;:::-;10532:86;10611:6;10606:3;10532:86;:::i;:::-;10525:93;;10642:56;10692:5;10642:56;:::i;:::-;10721:7;10752:1;10737:284;10762:6;10759:1;10756:13;10737:284;;;10838:6;10832:13;10865:63;10924:3;10909:13;10865:63;:::i;:::-;10858:70;;10951:60;11004:6;10951:60;:::i;:::-;10941:70;;10797:224;10784:1;10781;10777:9;10772:14;;10737:284;;;10741:14;11037:3;11030:10;;10438:608;;;10314:732;;;;:::o;11052:373::-;11195:4;11233:2;11222:9;11218:18;11210:26;;11282:9;11276:4;11272:20;11268:1;11257:9;11253:17;11246:47;11310:108;11413:4;11404:6;11310:108;:::i;:::-;11302:116;;11052:373;;;;:::o;11431:468::-;11496:6;11504;11553:2;11541:9;11532:7;11528:23;11524:32;11521:119;;;11559:79;;:::i;:::-;11521:119;11679:1;11704:53;11749:7;11740:6;11729:9;11725:22;11704:53;:::i;:::-;11694:63;;11650:117;11806:2;11832:50;11874:7;11865:6;11854:9;11850:22;11832:50;:::i;:::-;11822:60;;11777:115;11431:468;;;;;:::o;11905:307::-;11966:4;12056:18;12048:6;12045:30;12042:56;;;12078:18;;:::i;:::-;12042:56;12116:29;12138:6;12116:29;:::i;:::-;12108:37;;12200:4;12194;12190:15;12182:23;;11905:307;;;:::o;12218:423::-;12295:5;12320:65;12336:48;12377:6;12336:48;:::i;:::-;12320:65;:::i;:::-;12311:74;;12408:6;12401:5;12394:21;12446:4;12439:5;12435:16;12484:3;12475:6;12470:3;12466:16;12463:25;12460:112;;;12491:79;;:::i;:::-;12460:112;12581:54;12628:6;12623:3;12618;12581:54;:::i;:::-;12301:340;12218:423;;;;;:::o;12660:338::-;12715:5;12764:3;12757:4;12749:6;12745:17;12741:27;12731:122;;12772:79;;:::i;:::-;12731:122;12889:6;12876:20;12914:78;12988:3;12980:6;12973:4;12965:6;12961:17;12914:78;:::i;:::-;12905:87;;12721:277;12660:338;;;;:::o;13004:943::-;13099:6;13107;13115;13123;13172:3;13160:9;13151:7;13147:23;13143:33;13140:120;;;13179:79;;:::i;:::-;13140:120;13299:1;13324:53;13369:7;13360:6;13349:9;13345:22;13324:53;:::i;:::-;13314:63;;13270:117;13426:2;13452:53;13497:7;13488:6;13477:9;13473:22;13452:53;:::i;:::-;13442:63;;13397:118;13554:2;13580:53;13625:7;13616:6;13605:9;13601:22;13580:53;:::i;:::-;13570:63;;13525:118;13710:2;13699:9;13695:18;13682:32;13741:18;13733:6;13730:30;13727:117;;;13763:79;;:::i;:::-;13727:117;13868:62;13922:7;13913:6;13902:9;13898:22;13868:62;:::i;:::-;13858:72;;13653:287;13004:943;;;;;;;:::o;13953:474::-;14021:6;14029;14078:2;14066:9;14057:7;14053:23;14049:32;14046:119;;;14084:79;;:::i;:::-;14046:119;14204:1;14229:53;14274:7;14265:6;14254:9;14250:22;14229:53;:::i;:::-;14219:63;;14175:117;14331:2;14357:53;14402:7;14393:6;14382:9;14378:22;14357:53;:::i;:::-;14347:63;;14302:118;13953:474;;;;;:::o;14433:::-;14501:6;14509;14558:2;14546:9;14537:7;14533:23;14529:32;14526:119;;;14564:79;;:::i;:::-;14526:119;14684:1;14709:53;14754:7;14745:6;14734:9;14730:22;14709:53;:::i;:::-;14699:63;;14655:117;14811:2;14837:53;14882:7;14873:6;14862:9;14858:22;14837:53;:::i;:::-;14827:63;;14782:118;14433:474;;;;;:::o;14913:180::-;14961:77;14958:1;14951:88;15058:4;15055:1;15048:15;15082:4;15079:1;15072:15;15099:320;15143:6;15180:1;15174:4;15170:12;15160:22;;15227:1;15221:4;15217:12;15248:18;15238:81;;15304:4;15296:6;15292:17;15282:27;;15238:81;15366:2;15358:6;15355:14;15335:18;15332:38;15329:84;;15385:18;;:::i;:::-;15329:84;15150:269;15099:320;;;:::o;15425:220::-;15565:34;15561:1;15553:6;15549:14;15542:58;15634:3;15629:2;15621:6;15617:15;15610:28;15425:220;:::o;15651:366::-;15793:3;15814:67;15878:2;15873:3;15814:67;:::i;:::-;15807:74;;15890:93;15979:3;15890:93;:::i;:::-;16008:2;16003:3;15999:12;15992:19;;15651:366;;;:::o;16023:419::-;16189:4;16227:2;16216:9;16212:18;16204:26;;16276:9;16270:4;16266:20;16262:1;16251:9;16247:17;16240:47;16304:131;16430:4;16304:131;:::i;:::-;16296:139;;16023:419;;;:::o;16448:248::-;16588:34;16584:1;16576:6;16572:14;16565:58;16657:31;16652:2;16644:6;16640:15;16633:56;16448:248;:::o;16702:366::-;16844:3;16865:67;16929:2;16924:3;16865:67;:::i;:::-;16858:74;;16941:93;17030:3;16941:93;:::i;:::-;17059:2;17054:3;17050:12;17043:19;;16702:366;;;:::o;17074:419::-;17240:4;17278:2;17267:9;17263:18;17255:26;;17327:9;17321:4;17317:20;17313:1;17302:9;17298:17;17291:47;17355:131;17481:4;17355:131;:::i;:::-;17347:139;;17074:419;;;:::o;17499:141::-;17548:4;17571:3;17563:11;;17594:3;17591:1;17584:14;17628:4;17625:1;17615:18;17607:26;;17499:141;;;:::o;17646:93::-;17683:6;17730:2;17725;17718:5;17714:14;17710:23;17700:33;;17646:93;;;:::o;17745:107::-;17789:8;17839:5;17833:4;17829:16;17808:37;;17745:107;;;;:::o;17858:393::-;17927:6;17977:1;17965:10;17961:18;18000:97;18030:66;18019:9;18000:97;:::i;:::-;18118:39;18148:8;18137:9;18118:39;:::i;:::-;18106:51;;18190:4;18186:9;18179:5;18175:21;18166:30;;18239:4;18229:8;18225:19;18218:5;18215:30;18205:40;;17934:317;;17858:393;;;;;:::o;18257:60::-;18285:3;18306:5;18299:12;;18257:60;;;:::o;18323:142::-;18373:9;18406:53;18424:34;18433:24;18451:5;18433:24;:::i;:::-;18424:34;:::i;:::-;18406:53;:::i;:::-;18393:66;;18323:142;;;:::o;18471:75::-;18514:3;18535:5;18528:12;;18471:75;;;:::o;18552:269::-;18662:39;18693:7;18662:39;:::i;:::-;18723:91;18772:41;18796:16;18772:41;:::i;:::-;18764:6;18757:4;18751:11;18723:91;:::i;:::-;18717:4;18710:105;18628:193;18552:269;;;:::o;18827:73::-;18872:3;18827:73;:::o;18906:189::-;18983:32;;:::i;:::-;19024:65;19082:6;19074;19068:4;19024:65;:::i;:::-;18959:136;18906:189;;:::o;19101:186::-;19161:120;19178:3;19171:5;19168:14;19161:120;;;19232:39;19269:1;19262:5;19232:39;:::i;:::-;19205:1;19198:5;19194:13;19185:22;;19161:120;;;19101:186;;:::o;19293:543::-;19394:2;19389:3;19386:11;19383:446;;;19428:38;19460:5;19428:38;:::i;:::-;19512:29;19530:10;19512:29;:::i;:::-;19502:8;19498:44;19695:2;19683:10;19680:18;19677:49;;;19716:8;19701:23;;19677:49;19739:80;19795:22;19813:3;19795:22;:::i;:::-;19785:8;19781:37;19768:11;19739:80;:::i;:::-;19398:431;;19383:446;19293:543;;;:::o;19842:117::-;19896:8;19946:5;19940:4;19936:16;19915:37;;19842:117;;;;:::o;19965:169::-;20009:6;20042:51;20090:1;20086:6;20078:5;20075:1;20071:13;20042:51;:::i;:::-;20038:56;20123:4;20117;20113:15;20103:25;;20016:118;19965:169;;;;:::o;20139:295::-;20215:4;20361:29;20386:3;20380:4;20361:29;:::i;:::-;20353:37;;20423:3;20420:1;20416:11;20410:4;20407:21;20399:29;;20139:295;;;;:::o;20439:1395::-;20556:37;20589:3;20556:37;:::i;:::-;20658:18;20650:6;20647:30;20644:56;;;20680:18;;:::i;:::-;20644:56;20724:38;20756:4;20750:11;20724:38;:::i;:::-;20809:67;20869:6;20861;20855:4;20809:67;:::i;:::-;20903:1;20927:4;20914:17;;20959:2;20951:6;20948:14;20976:1;20971:618;;;;21633:1;21650:6;21647:77;;;21699:9;21694:3;21690:19;21684:26;21675:35;;21647:77;21750:67;21810:6;21803:5;21750:67;:::i;:::-;21744:4;21737:81;21606:222;20941:887;;20971:618;21023:4;21019:9;21011:6;21007:22;21057:37;21089:4;21057:37;:::i;:::-;21116:1;21130:208;21144:7;21141:1;21138:14;21130:208;;;21223:9;21218:3;21214:19;21208:26;21200:6;21193:42;21274:1;21266:6;21262:14;21252:24;;21321:2;21310:9;21306:18;21293:31;;21167:4;21164:1;21160:12;21155:17;;21130:208;;;21366:6;21357:7;21354:19;21351:179;;;21424:9;21419:3;21415:19;21409:26;21467:48;21509:4;21501:6;21497:17;21486:9;21467:48;:::i;:::-;21459:6;21452:64;21374:156;21351:179;21576:1;21572;21564:6;21560:14;21556:22;21550:4;21543:36;20978:611;;;20941:887;;20531:1303;;;20439:1395;;:::o;21840:332::-;21961:4;21999:2;21988:9;21984:18;21976:26;;22012:71;22080:1;22069:9;22065:17;22056:6;22012:71;:::i;:::-;22093:72;22161:2;22150:9;22146:18;22137:6;22093:72;:::i;:::-;21840:332;;;;;:::o;22178:137::-;22232:5;22263:6;22257:13;22248:22;;22279:30;22303:5;22279:30;:::i;:::-;22178:137;;;;:::o;22321:345::-;22388:6;22437:2;22425:9;22416:7;22412:23;22408:32;22405:119;;;22443:79;;:::i;:::-;22405:119;22563:1;22588:61;22641:7;22632:6;22621:9;22617:22;22588:61;:::i;:::-;22578:71;;22534:125;22321:345;;;;:::o;22672:147::-;22773:11;22810:3;22795:18;;22672:147;;;;:::o;22825:114::-;;:::o;22945:398::-;23104:3;23125:83;23206:1;23201:3;23125:83;:::i;:::-;23118:90;;23217:93;23306:3;23217:93;:::i;:::-;23335:1;23330:3;23326:11;23319:18;;22945:398;;;:::o;23349:379::-;23533:3;23555:147;23698:3;23555:147;:::i;:::-;23548:154;;23719:3;23712:10;;23349:379;;;:::o;23734:180::-;23782:77;23779:1;23772:88;23879:4;23876:1;23869:15;23903:4;23900:1;23893:15;23920:180;23968:77;23965:1;23958:88;24065:4;24062:1;24055:15;24089:4;24086:1;24079:15;24106:233;24145:3;24168:24;24186:5;24168:24;:::i;:::-;24159:33;;24214:66;24207:5;24204:77;24201:103;;24284:18;;:::i;:::-;24201:103;24331:1;24324:5;24320:13;24313:20;;24106:233;;;:::o;24345:174::-;24485:26;24481:1;24473:6;24469:14;24462:50;24345:174;:::o;24525:366::-;24667:3;24688:67;24752:2;24747:3;24688:67;:::i;:::-;24681:74;;24764:93;24853:3;24764:93;:::i;:::-;24882:2;24877:3;24873:12;24866:19;;24525:366;;;:::o;24897:419::-;25063:4;25101:2;25090:9;25086:18;25078:26;;25150:9;25144:4;25140:20;25136:1;25125:9;25121:17;25114:47;25178:131;25304:4;25178:131;:::i;:::-;25170:139;;24897:419;;;:::o;25322:228::-;25462:34;25458:1;25450:6;25446:14;25439:58;25531:11;25526:2;25518:6;25514:15;25507:36;25322:228;:::o;25556:366::-;25698:3;25719:67;25783:2;25778:3;25719:67;:::i;:::-;25712:74;;25795:93;25884:3;25795:93;:::i;:::-;25913:2;25908:3;25904:12;25897:19;;25556:366;;;:::o;25928:419::-;26094:4;26132:2;26121:9;26117:18;26109:26;;26181:9;26175:4;26171:20;26167:1;26156:9;26152:17;26145:47;26209:131;26335:4;26209:131;:::i;:::-;26201:139;;25928:419;;;:::o;26353:170::-;26493:22;26489:1;26481:6;26477:14;26470:46;26353:170;:::o;26529:366::-;26671:3;26692:67;26756:2;26751:3;26692:67;:::i;:::-;26685:74;;26768:93;26857:3;26768:93;:::i;:::-;26886:2;26881:3;26877:12;26870:19;;26529:366;;;:::o;26901:419::-;27067:4;27105:2;27094:9;27090:18;27082:26;;27154:9;27148:4;27144:20;27140:1;27129:9;27125:17;27118:47;27182:131;27308:4;27182:131;:::i;:::-;27174:139;;26901:419;;;:::o;27326:191::-;27366:3;27385:20;27403:1;27385:20;:::i;:::-;27380:25;;27419:20;27437:1;27419:20;:::i;:::-;27414:25;;27462:1;27459;27455:9;27448:16;;27483:3;27480:1;27477:10;27474:36;;;27490:18;;:::i;:::-;27474:36;27326:191;;;;:::o;27523:170::-;27663:22;27659:1;27651:6;27647:14;27640:46;27523:170;:::o;27699:366::-;27841:3;27862:67;27926:2;27921:3;27862:67;:::i;:::-;27855:74;;27938:93;28027:3;27938:93;:::i;:::-;28056:2;28051:3;28047:12;28040:19;;27699:366;;;:::o;28071:419::-;28237:4;28275:2;28264:9;28260:18;28252:26;;28324:9;28318:4;28314:20;28310:1;28299:9;28295:17;28288:47;28352:131;28478:4;28352:131;:::i;:::-;28344:139;;28071:419;;;:::o;28496:173::-;28636:25;28632:1;28624:6;28620:14;28613:49;28496:173;:::o;28675:366::-;28817:3;28838:67;28902:2;28897:3;28838:67;:::i;:::-;28831:74;;28914:93;29003:3;28914:93;:::i;:::-;29032:2;29027:3;29023:12;29016:19;;28675:366;;;:::o;29047:419::-;29213:4;29251:2;29240:9;29236:18;29228:26;;29300:9;29294:4;29290:20;29286:1;29275:9;29271:17;29264:47;29328:131;29454:4;29328:131;:::i;:::-;29320:139;;29047:419;;;:::o;29472:410::-;29512:7;29535:20;29553:1;29535:20;:::i;:::-;29530:25;;29569:20;29587:1;29569:20;:::i;:::-;29564:25;;29624:1;29621;29617:9;29646:30;29664:11;29646:30;:::i;:::-;29635:41;;29825:1;29816:7;29812:15;29809:1;29806:22;29786:1;29779:9;29759:83;29736:139;;29855:18;;:::i;:::-;29736:139;29520:362;29472:410;;;;:::o;29888:169::-;30028:21;30024:1;30016:6;30012:14;30005:45;29888:169;:::o;30063:366::-;30205:3;30226:67;30290:2;30285:3;30226:67;:::i;:::-;30219:74;;30302:93;30391:3;30302:93;:::i;:::-;30420:2;30415:3;30411:12;30404:19;;30063:366;;;:::o;30435:419::-;30601:4;30639:2;30628:9;30624:18;30616:26;;30688:9;30682:4;30678:20;30674:1;30663:9;30659:17;30652:47;30716:131;30842:4;30716:131;:::i;:::-;30708:139;;30435:419;;;:::o;30860:234::-;31000:34;30996:1;30988:6;30984:14;30977:58;31069:17;31064:2;31056:6;31052:15;31045:42;30860:234;:::o;31100:366::-;31242:3;31263:67;31327:2;31322:3;31263:67;:::i;:::-;31256:74;;31339:93;31428:3;31339:93;:::i;:::-;31457:2;31452:3;31448:12;31441:19;;31100:366;;;:::o;31472:419::-;31638:4;31676:2;31665:9;31661:18;31653:26;;31725:9;31719:4;31715:20;31711:1;31700:9;31696:17;31689:47;31753:131;31879:4;31753:131;:::i;:::-;31745:139;;31472:419;;;:::o;31897:148::-;31999:11;32036:3;32021:18;;31897:148;;;;:::o;32051:390::-;32157:3;32185:39;32218:5;32185:39;:::i;:::-;32240:89;32322:6;32317:3;32240:89;:::i;:::-;32233:96;;32338:65;32396:6;32391:3;32384:4;32377:5;32373:16;32338:65;:::i;:::-;32428:6;32423:3;32419:16;32412:23;;32161:280;32051:390;;;;:::o;32471:874::-;32574:3;32611:5;32605:12;32640:36;32666:9;32640:36;:::i;:::-;32692:89;32774:6;32769:3;32692:89;:::i;:::-;32685:96;;32812:1;32801:9;32797:17;32828:1;32823:166;;;;33003:1;32998:341;;;;32790:549;;32823:166;32907:4;32903:9;32892;32888:25;32883:3;32876:38;32969:6;32962:14;32955:22;32947:6;32943:35;32938:3;32934:45;32927:52;;32823:166;;32998:341;33065:38;33097:5;33065:38;:::i;:::-;33125:1;33139:154;33153:6;33150:1;33147:13;33139:154;;;33227:7;33221:14;33217:1;33212:3;33208:11;33201:35;33277:1;33268:7;33264:15;33253:26;;33175:4;33172:1;33168:12;33163:17;;33139:154;;;33322:6;33317:3;33313:16;33306:23;;33005:334;;32790:549;;32578:767;;32471:874;;;;:::o;33351:589::-;33576:3;33598:95;33689:3;33680:6;33598:95;:::i;:::-;33591:102;;33710:95;33801:3;33792:6;33710:95;:::i;:::-;33703:102;;33822:92;33910:3;33901:6;33822:92;:::i;:::-;33815:99;;33931:3;33924:10;;33351:589;;;;;;:::o;33946:225::-;34086:34;34082:1;34074:6;34070:14;34063:58;34155:8;34150:2;34142:6;34138:15;34131:33;33946:225;:::o;34177:366::-;34319:3;34340:67;34404:2;34399:3;34340:67;:::i;:::-;34333:74;;34416:93;34505:3;34416:93;:::i;:::-;34534:2;34529:3;34525:12;34518:19;;34177:366;;;:::o;34549:419::-;34715:4;34753:2;34742:9;34738:18;34730:26;;34802:9;34796:4;34792:20;34788:1;34777:9;34773:17;34766:47;34830:131;34956:4;34830:131;:::i;:::-;34822:139;;34549:419;;;:::o;34974:182::-;35114:34;35110:1;35102:6;35098:14;35091:58;34974:182;:::o;35162:366::-;35304:3;35325:67;35389:2;35384:3;35325:67;:::i;:::-;35318:74;;35401:93;35490:3;35401:93;:::i;:::-;35519:2;35514:3;35510:12;35503:19;;35162:366;;;:::o;35534:419::-;35700:4;35738:2;35727:9;35723:18;35715:26;;35787:9;35781:4;35777:20;35773:1;35762:9;35758:17;35751:47;35815:131;35941:4;35815:131;:::i;:::-;35807:139;;35534:419;;;:::o;35959:232::-;36099:34;36095:1;36087:6;36083:14;36076:58;36168:15;36163:2;36155:6;36151:15;36144:40;35959:232;:::o;36197:366::-;36339:3;36360:67;36424:2;36419:3;36360:67;:::i;:::-;36353:74;;36436:93;36525:3;36436:93;:::i;:::-;36554:2;36549:3;36545:12;36538:19;;36197:366;;;:::o;36569:419::-;36735:4;36773:2;36762:9;36758:18;36750:26;;36822:9;36816:4;36812:20;36808:1;36797:9;36793:17;36786:47;36850:131;36976:4;36850:131;:::i;:::-;36842:139;;36569:419;;;:::o;36994:175::-;37134:27;37130:1;37122:6;37118:14;37111:51;36994:175;:::o;37175:366::-;37317:3;37338:67;37402:2;37397:3;37338:67;:::i;:::-;37331:74;;37414:93;37503:3;37414:93;:::i;:::-;37532:2;37527:3;37523:12;37516:19;;37175:366;;;:::o;37547:419::-;37713:4;37751:2;37740:9;37736:18;37728:26;;37800:9;37794:4;37790:20;37786:1;37775:9;37771:17;37764:47;37828:131;37954:4;37828:131;:::i;:::-;37820:139;;37547:419;;;:::o;37972:180::-;38020:77;38017:1;38010:88;38117:4;38114:1;38107:15;38141:4;38138:1;38131:15;38158:224;38298:34;38294:1;38286:6;38282:14;38275:58;38367:7;38362:2;38354:6;38350:15;38343:32;38158:224;:::o;38388:366::-;38530:3;38551:67;38615:2;38610:3;38551:67;:::i;:::-;38544:74;;38627:93;38716:3;38627:93;:::i;:::-;38745:2;38740:3;38736:12;38729:19;;38388:366;;;:::o;38760:419::-;38926:4;38964:2;38953:9;38949:18;38941:26;;39013:9;39007:4;39003:20;38999:1;38988:9;38984:17;38977:47;39041:131;39167:4;39041:131;:::i;:::-;39033:139;;38760:419;;;:::o;39185:223::-;39325:34;39321:1;39313:6;39309:14;39302:58;39394:6;39389:2;39381:6;39377:15;39370:31;39185:223;:::o;39414:366::-;39556:3;39577:67;39641:2;39636:3;39577:67;:::i;:::-;39570:74;;39653:93;39742:3;39653:93;:::i;:::-;39771:2;39766:3;39762:12;39755:19;;39414:366;;;:::o;39786:419::-;39952:4;39990:2;39979:9;39975:18;39967:26;;40039:9;40033:4;40029:20;40025:1;40014:9;40010:17;40003:47;40067:131;40193:4;40067:131;:::i;:::-;40059:139;;39786:419;;;:::o;40211:237::-;40351:34;40347:1;40339:6;40335:14;40328:58;40420:20;40415:2;40407:6;40403:15;40396:45;40211:237;:::o;40454:366::-;40596:3;40617:67;40681:2;40676:3;40617:67;:::i;:::-;40610:74;;40693:93;40782:3;40693:93;:::i;:::-;40811:2;40806:3;40802:12;40795:19;;40454:366;;;:::o;40826:419::-;40992:4;41030:2;41019:9;41015:18;41007:26;;41079:9;41073:4;41069:20;41065:1;41054:9;41050:17;41043:47;41107:131;41233:4;41107:131;:::i;:::-;41099:139;;40826:419;;;:::o;41251:194::-;41291:4;41311:20;41329:1;41311:20;:::i;:::-;41306:25;;41345:20;41363:1;41345:20;:::i;:::-;41340:25;;41389:1;41386;41382:9;41374:17;;41413:1;41407:4;41404:11;41401:37;;;41418:18;;:::i;:::-;41401:37;41251:194;;;;:::o;41451:98::-;41502:6;41536:5;41530:12;41520:22;;41451:98;;;:::o;41555:168::-;41638:11;41672:6;41667:3;41660:19;41712:4;41707:3;41703:14;41688:29;;41555:168;;;;:::o;41729:373::-;41815:3;41843:38;41875:5;41843:38;:::i;:::-;41897:70;41960:6;41955:3;41897:70;:::i;:::-;41890:77;;41976:65;42034:6;42029:3;42022:4;42015:5;42011:16;41976:65;:::i;:::-;42066:29;42088:6;42066:29;:::i;:::-;42061:3;42057:39;42050:46;;41819:283;41729:373;;;;:::o;42108:640::-;42303:4;42341:3;42330:9;42326:19;42318:27;;42355:71;42423:1;42412:9;42408:17;42399:6;42355:71;:::i;:::-;42436:72;42504:2;42493:9;42489:18;42480:6;42436:72;:::i;:::-;42518;42586:2;42575:9;42571:18;42562:6;42518:72;:::i;:::-;42637:9;42631:4;42627:20;42622:2;42611:9;42607:18;42600:48;42665:76;42736:4;42727:6;42665:76;:::i;:::-;42657:84;;42108:640;;;;;;;:::o;42754:141::-;42810:5;42841:6;42835:13;42826:22;;42857:32;42883:5;42857:32;:::i;:::-;42754:141;;;;:::o;42901:349::-;42970:6;43019:2;43007:9;42998:7;42994:23;42990:32;42987:119;;;43025:79;;:::i;:::-;42987:119;43145:1;43170:63;43225:7;43216:6;43205:9;43201:22;43170:63;:::i;:::-;43160:73;;43116:127;42901:349;;;;:::o;43256:182::-;43396:34;43392:1;43384:6;43380:14;43373:58;43256:182;:::o;43444:366::-;43586:3;43607:67;43671:2;43666:3;43607:67;:::i;:::-;43600:74;;43683:93;43772:3;43683:93;:::i;:::-;43801:2;43796:3;43792:12;43785:19;;43444:366;;;:::o;43816:419::-;43982:4;44020:2;44009:9;44005:18;43997:26;;44069:9;44063:4;44059:20;44055:1;44044:9;44040:17;44033:47;44097:131;44223:4;44097:131;:::i;:::-;44089:139;;43816:419;;;:::o;44241:178::-;44381:30;44377:1;44369:6;44365:14;44358:54;44241:178;:::o;44425:366::-;44567:3;44588:67;44652:2;44647:3;44588:67;:::i;:::-;44581:74;;44664:93;44753:3;44664:93;:::i;:::-;44782:2;44777:3;44773:12;44766:19;;44425:366;;;:::o;44797:419::-;44963:4;45001:2;44990:9;44986:18;44978:26;;45050:9;45044:4;45040:20;45036:1;45025:9;45021:17;45014:47;45078:131;45204:4;45078:131;:::i;:::-;45070:139;;44797:419;;;:::o

Swarm Source

ipfs://5f4178fd6fc4e248c7e092bbf2c60e525be5860531b8d2342a4a158287e4e08f
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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