ETH Price: $3,090.79 (+0.66%)
Gas: 7 Gwei

Token

Big is Coming ($BIC)
 

Overview

Max Total Supply

1,000,000,000,000,000 $BIC

Holders

38

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-

Other Info

Token Contract (WITH 18 Decimals)

Balance
1,266,125,023,707.148619313679189772 $BIC

Value
$0.00
0xf7b641b0f2de07cb085651e971ef9f5db09663a4
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:
BigisComing

Compiler Version
v0.8.24+commit.e11b9ed9

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2024-02-12
*/

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


// OpenZeppelin Contracts (last updated v5.0.0) (utils/Nonces.sol)
pragma solidity ^0.8.20;

/**
 * @dev Provides tracking nonces for addresses. Nonces will only increment.
 */
abstract contract Nonces {
    /**
     * @dev The nonce used for an `account` is not the expected current nonce.
     */
    error InvalidAccountNonce(address account, uint256 currentNonce);

    mapping(address account => uint256) private _nonces;

    /**
     * @dev Returns the next unused nonce for an address.
     */
    function nonces(address owner) public view virtual returns (uint256) {
        return _nonces[owner];
    }

    /**
     * @dev Consumes a nonce.
     *
     * Returns the current value and increments nonce.
     */
    function _useNonce(address owner) internal virtual returns (uint256) {
        // For each account, the nonce has an initial value of 0, can only be incremented by one, and cannot be
        // decremented or reset. This guarantees that the nonce never overflows.
        unchecked {
            // It is important to do x++ and not ++x here.
            return _nonces[owner]++;
        }
    }

    /**
     * @dev Same as {_useNonce} but checking that `nonce` is the next valid for `owner`.
     */
    function _useCheckedNonce(address owner, uint256 nonce) internal virtual {
        uint256 current = _useNonce(owner);
        if (nonce != current) {
            revert InvalidAccountNonce(owner, current);
        }
    }
}

// File: @openzeppelin/contracts/interfaces/IERC5267.sol


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

pragma solidity ^0.8.20;

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

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

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


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

pragma solidity ^0.8.20;

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

    struct BooleanSlot {
        bool value;
    }

    struct Bytes32Slot {
        bytes32 value;
    }

    struct Uint256Slot {
        uint256 value;
    }

    struct StringSlot {
        string value;
    }

    struct BytesSlot {
        bytes value;
    }

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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.20;


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

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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.20;

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

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

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

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

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


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

pragma solidity ^0.8.20;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.20;



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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.20;


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

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

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

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

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


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

pragma solidity ^0.8.20;




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

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

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

    bytes32 private immutable _hashedName;
    bytes32 private immutable _hashedVersion;

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

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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.20;

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS
    }

    /**
     * @dev The signature derives the `address(0)`.
     */
    error ECDSAInvalidSignature();

    /**
     * @dev The signature has an invalid length.
     */
    error ECDSAInvalidSignatureLength(uint256 length);

    /**
     * @dev The signature has an S value that is in the upper half order.
     */
    error ECDSAInvalidSignatureS(bytes32 s);

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with `signature` or an error. This will not
     * return address(0) without also returning an error description. Errors are documented using an enum (error type)
     * and a bytes32 providing additional information about the error.
     *
     * If no error is returned, then the address can be used for verification purposes.
     *
     * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError, bytes32) {
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            /// @solidity memory-safe-assembly
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength, bytes32(signature.length));
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM precompile allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {MessageHashUtils-toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, signature);
        _throwError(error, errorArg);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     */
    function tryRecover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address, RecoverError, bytes32) {
        unchecked {
            bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
            // We do not check for an overflow here since the shift operation results in 0 or 1.
            uint8 v = uint8((uint256(vs) >> 255) + 27);
            return tryRecover(hash, v, r, s);
        }
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     */
    function recover(bytes32 hash, bytes32 r, bytes32 vs) internal pure returns (address) {
        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, r, vs);
        _throwError(error, errorArg);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError, bytes32) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS, s);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature, bytes32(0));
        }

        return (signer, RecoverError.NoError, bytes32(0));
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(bytes32 hash, uint8 v, bytes32 r, bytes32 s) internal pure returns (address) {
        (address recovered, RecoverError error, bytes32 errorArg) = tryRecover(hash, v, r, s);
        _throwError(error, errorArg);
        return recovered;
    }

    /**
     * @dev Optionally reverts with the corresponding custom error according to the `error` argument provided.
     */
    function _throwError(RecoverError error, bytes32 errorArg) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert ECDSAInvalidSignature();
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert ECDSAInvalidSignatureLength(uint256(errorArg));
        } else if (error == RecoverError.InvalidSignatureS) {
            revert ECDSAInvalidSignatureS(errorArg);
        }
    }
}

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


// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Permit.sol)

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on {IERC20-approve}, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 *
 * ==== Security Considerations
 *
 * There are two important considerations concerning the use of `permit`. The first is that a valid permit signature
 * expresses an allowance, and it should not be assumed to convey additional meaning. In particular, it should not be
 * considered as an intention to spend the allowance in any specific way. The second is that because permits have
 * built-in replay protection and can be submitted by anyone, they can be frontrun. A protocol that uses permits should
 * take this into consideration and allow a `permit` call to fail. Combining these two aspects, a pattern that may be
 * generally recommended is:
 *
 * ```solidity
 * function doThingWithPermit(..., uint256 value, uint256 deadline, uint8 v, bytes32 r, bytes32 s) public {
 *     try token.permit(msg.sender, address(this), value, deadline, v, r, s) {} catch {}
 *     doThing(..., value);
 * }
 *
 * function doThing(..., uint256 value) public {
 *     token.safeTransferFrom(msg.sender, address(this), value);
 *     ...
 * }
 * ```
 *
 * Observe that: 1) `msg.sender` is used as the owner, leaving no ambiguity as to the signer intent, and 2) the use of
 * `try/catch` allows the permit to fail and makes the code tolerant to frontrunning. (See also
 * {SafeERC20-safeTransferFrom}).
 *
 * Additionally, note that smart contract wallets (such as Argent or Safe) are not able to produce permit signatures, so
 * contracts should have entry points that don't rely on permit.
 */
interface IERC20Permit {
    /**
     * @dev Sets `value` as the allowance of `spender` over ``owner``'s tokens,
     * given ``owner``'s signed approval.
     *
     * IMPORTANT: The same issues {IERC20-approve} has related to transaction
     * ordering also apply here.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `spender` cannot be the zero address.
     * - `deadline` must be a timestamp in the future.
     * - `v`, `r` and `s` must be a valid `secp256k1` signature from `owner`
     * over the EIP712-formatted function arguments.
     * - the signature must use ``owner``'s current nonce (see {nonces}).
     *
     * For more information on the signature format, see the
     * https://eips.ethereum.org/EIPS/eip-2612#specification[relevant EIP
     * section].
     *
     * CAUTION: See Security Considerations above.
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) external;

    /**
     * @dev Returns the current nonce for `owner`. This value must be
     * included whenever a signature is generated for {permit}.
     *
     * Every successful call to {permit} increases ``owner``'s nonce by one. This
     * prevents a signature from being used multiple times.
     */
    function nonces(address owner) external view returns (uint256);

    /**
     * @dev Returns the domain separator used in the encoding of the signature for {permit}, as defined by {EIP712}.
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view returns (bytes32);
}

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


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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.20;

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

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

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

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


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

pragma solidity ^0.8.20;


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

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

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

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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.20;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

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

    /**
     * @dev Returns the value of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

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


// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/IERC20Metadata.sol)

pragma solidity ^0.8.20;


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

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

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

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


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

pragma solidity ^0.8.20;





/**
 * @dev Implementation of the {IERC20} interface.
 *
 * This implementation is agnostic to the way tokens are created. This means
 * that a supply mechanism has to be added in a derived contract using {_mint}.
 *
 * TIP: For a detailed writeup see our guide
 * https://forum.openzeppelin.com/t/how-to-implement-erc20-supply-mechanisms/226[How
 * to implement supply mechanisms].
 *
 * The default value of {decimals} is 18. To change this, you should override
 * this function so it returns a different value.
 *
 * We have followed general OpenZeppelin Contracts guidelines: functions revert
 * instead returning `false` on failure. This behavior is nonetheless
 * conventional and does not conflict with the expectations of ERC20
 * applications.
 *
 * Additionally, an {Approval} event is emitted on calls to {transferFrom}.
 * This allows applications to reconstruct the allowance for all accounts just
 * by listening to said events. Other implementations of the EIP may not emit
 * these events, as it isn't required by the specification.
 */
abstract contract ERC20 is Context, IERC20, IERC20Metadata, IERC20Errors {
    mapping(address account => uint256) private _balances;

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

    uint256 private _totalSupply;

    string private _name;
    string private _symbol;

    /**
     * @dev Sets the values for {name} and {symbol}.
     *
     * All two of these values are immutable: they can only be set once during
     * construction.
     */
    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
    }

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

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

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

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

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

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

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

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

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

    /**
     * @dev Moves a `value` amount of tokens from `from` to `to`.
     *
     * This internal function is equivalent to {transfer}, and can be used to
     * e.g. implement automatic token fees, slashing mechanisms, etc.
     *
     * Emits a {Transfer} event.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead.
     */
    function _transfer(address from, address to, uint256 value) internal {
        if (from == address(0)) {
            revert ERC20InvalidSender(address(0));
        }
        if (to == address(0)) {
            revert ERC20InvalidReceiver(address(0));
        }
        _update(from, to, value);
    }

    /**
     * @dev Transfers a `value` amount of tokens from `from` to `to`, or alternatively mints (or burns) if `from`
     * (or `to`) is the zero address. All customizations to transfers, mints, and burns should be done by overriding
     * this function.
     *
     * Emits a {Transfer} event.
     */
    function _update(address from, address to, uint256 value) internal virtual {
        if (from == address(0)) {
            // Overflow check required: The rest of the code assumes that totalSupply never overflows
            _totalSupply += value;
        } else {
            uint256 fromBalance = _balances[from];
            if (fromBalance < value) {
                revert ERC20InsufficientBalance(from, fromBalance, value);
            }
            unchecked {
                // Overflow not possible: value <= fromBalance <= totalSupply.
                _balances[from] = fromBalance - value;
            }
        }

        if (to == address(0)) {
            unchecked {
                // Overflow not possible: value <= totalSupply or value <= fromBalance <= totalSupply.
                _totalSupply -= value;
            }
        } else {
            unchecked {
                // Overflow not possible: balance + value is at most totalSupply, which we know fits into a uint256.
                _balances[to] += value;
            }
        }

        emit Transfer(from, to, value);
    }

    /**
     * @dev Creates a `value` amount of tokens and assigns them to `account`, by transferring it from address(0).
     * Relies on the `_update` mechanism
     *
     * Emits a {Transfer} event with `from` set to the zero address.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead.
     */
    function _mint(address account, uint256 value) internal {
        if (account == address(0)) {
            revert ERC20InvalidReceiver(address(0));
        }
        _update(address(0), account, value);
    }

    /**
     * @dev Destroys a `value` amount of tokens from `account`, lowering the total supply.
     * Relies on the `_update` mechanism.
     *
     * Emits a {Transfer} event with `to` set to the zero address.
     *
     * NOTE: This function is not virtual, {_update} should be overridden instead
     */
    function _burn(address account, uint256 value) internal {
        if (account == address(0)) {
            revert ERC20InvalidSender(address(0));
        }
        _update(account, address(0), value);
    }

    /**
     * @dev Sets `value` as the allowance of `spender` over the `owner` s tokens.
     *
     * This internal function is equivalent to `approve`, and can be used to
     * e.g. set automatic allowances for certain subsystems, etc.
     *
     * Emits an {Approval} event.
     *
     * Requirements:
     *
     * - `owner` cannot be the zero address.
     * - `spender` cannot be the zero address.
     *
     * Overrides to this logic should be done to the variant with an additional `bool emitEvent` argument.
     */
    function _approve(address owner, address spender, uint256 value) internal {
        _approve(owner, spender, value, true);
    }

    /**
     * @dev Variant of {_approve} with an optional flag to enable or disable the {Approval} event.
     *
     * By default (when calling {_approve}) the flag is set to true. On the other hand, approval changes made by
     * `_spendAllowance` during the `transferFrom` operation set the flag to false. This saves gas by not emitting any
     * `Approval` event during `transferFrom` operations.
     *
     * Anyone who wishes to continue emitting `Approval` events on the`transferFrom` operation can force the flag to
     * true using the following override:
     * ```
     * function _approve(address owner, address spender, uint256 value, bool) internal virtual override {
     *     super._approve(owner, spender, value, true);
     * }
     * ```
     *
     * Requirements are the same as {_approve}.
     */
    function _approve(address owner, address spender, uint256 value, bool emitEvent) internal virtual {
        if (owner == address(0)) {
            revert ERC20InvalidApprover(address(0));
        }
        if (spender == address(0)) {
            revert ERC20InvalidSpender(address(0));
        }
        _allowances[owner][spender] = value;
        if (emitEvent) {
            emit Approval(owner, spender, value);
        }
    }

    /**
     * @dev Updates `owner` s allowance for `spender` based on spent `value`.
     *
     * Does not update the allowance value in case of infinite allowance.
     * Revert if not enough allowance is available.
     *
     * Does not emit an {Approval} event.
     */
    function _spendAllowance(address owner, address spender, uint256 value) internal virtual {
        uint256 currentAllowance = allowance(owner, spender);
        if (currentAllowance != type(uint256).max) {
            if (currentAllowance < value) {
                revert ERC20InsufficientAllowance(spender, currentAllowance, value);
            }
            unchecked {
                _approve(owner, spender, currentAllowance - value, false);
            }
        }
    }
}

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


// OpenZeppelin Contracts (last updated v5.0.0) (token/ERC20/extensions/ERC20Permit.sol)

pragma solidity ^0.8.20;






/**
 * @dev Implementation of the ERC20 Permit extension allowing approvals to be made via signatures, as defined in
 * https://eips.ethereum.org/EIPS/eip-2612[EIP-2612].
 *
 * Adds the {permit} method, which can be used to change an account's ERC20 allowance (see {IERC20-allowance}) by
 * presenting a message signed by the account. By not relying on `{IERC20-approve}`, the token holder account doesn't
 * need to send a transaction, and thus is not required to hold Ether at all.
 */
abstract contract ERC20Permit is ERC20, IERC20Permit, EIP712, Nonces {
    bytes32 private constant PERMIT_TYPEHASH =
        keccak256("Permit(address owner,address spender,uint256 value,uint256 nonce,uint256 deadline)");

    /**
     * @dev Permit deadline has expired.
     */
    error ERC2612ExpiredSignature(uint256 deadline);

    /**
     * @dev Mismatched signature.
     */
    error ERC2612InvalidSigner(address signer, address owner);

    /**
     * @dev Initializes the {EIP712} domain separator using the `name` parameter, and setting `version` to `"1"`.
     *
     * It's a good idea to use the same `name` that is defined as the ERC20 token name.
     */
    constructor(string memory name) EIP712(name, "1") {}

    /**
     * @inheritdoc IERC20Permit
     */
    function permit(
        address owner,
        address spender,
        uint256 value,
        uint256 deadline,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) public virtual {
        if (block.timestamp > deadline) {
            revert ERC2612ExpiredSignature(deadline);
        }

        bytes32 structHash = keccak256(abi.encode(PERMIT_TYPEHASH, owner, spender, value, _useNonce(owner), deadline));

        bytes32 hash = _hashTypedDataV4(structHash);

        address signer = ECDSA.recover(hash, v, r, s);
        if (signer != owner) {
            revert ERC2612InvalidSigner(signer, owner);
        }

        _approve(owner, spender, value);
    }

    /**
     * @inheritdoc IERC20Permit
     */
    function nonces(address owner) public view virtual override(IERC20Permit, Nonces) returns (uint256) {
        return super.nonces(owner);
    }

    /**
     * @inheritdoc IERC20Permit
     */
    // solhint-disable-next-line func-name-mixedcase
    function DOMAIN_SEPARATOR() external view virtual returns (bytes32) {
        return _domainSeparatorV4();
    }
}

// File: DOTRUMP.sol


pragma solidity ^0.8.9;




contract BigisComing is ERC20, ERC20Permit, Ownable {
    mapping(address => bool) private _blacklist;
    mapping(address => LockInfo) private _lockedLpPools;
    mapping(address => bool) private _whitelist;
    bool private _whitelistEnabled = false;
            struct LockInfo {
            address poolAddress;
            uint256 lockEndTime;
    
    }

    constructor()
        ERC20("Big is Coming", "$BIC")
        ERC20Permit("$BIC")
        Ownable(msg.sender) 
    {
        _mint(msg.sender, 1000000000000000 * 10 ** decimals());
    }
    function setWhitelistEnabled(bool enabled) public onlyOwner {
        _whitelistEnabled = enabled;
    }

    function addToWhitelist(address account) public onlyOwner {
        require(account != address(0), "Cannot add zero address to whitelist");
        _whitelist[account] = true;
    }

    function removeFromWhitelist(address account) public onlyOwner {
        require(account != address(0), "Cannot remove zero address from whitelist");
        _whitelist[account] = false;
    }

    function isWhitelisted(address account) public view returns (bool) {
        return _whitelist[account];
    }
   
    function addToBlacklist(address account) public onlyOwner {
        _blacklist[account] = true;
    }

    function removeFromBlacklist(address account) public onlyOwner {
        _blacklist[account] = false;
    }

    function isBlacklisted(address account) public view returns (bool) {
        return _blacklist[account];
    }

    
    function addLockLpPool(address poolAddress, uint256 lockEndTime) public onlyOwner {
        _lockedLpPools[poolAddress] = LockInfo(poolAddress, lockEndTime);
    }

    function isLpPoolLocked(address poolAddress) public view returns (bool) {
        return _lockedLpPools[poolAddress].lockEndTime > block.timestamp;
    }


    function transfer(address recipient, uint256 amount) public override returns (bool) {
        require(!isBlacklisted(_msgSender()), "ERC20: transfer from blacklisted address");
        require(!isBlacklisted(recipient), "ERC20: transfer to blacklisted address");
        require(!isLpPoolLocked(recipient), "ERC20: transfer to locked LP pool");
        require(!_whitelistEnabled || (isWhitelisted(msg.sender) && isWhitelisted(recipient)), "ERC20: sender and/or recipient is not whitelisted");
        require(!isLpPoolLocked(recipient), "ERC20: transfer to locked LP pool");
        return super.transfer(recipient, amount);
    }

    function transferFrom(address sender, address recipient, uint256 amount) public override returns (bool) {
        require(!isBlacklisted(sender), "ERC20: transfer from blacklisted address");
        require(!isBlacklisted(recipient), "ERC20: transfer to blacklisted address");
        require(!isLpPoolLocked(recipient), "ERC20: transfer to locked LP pool");
        require(!_whitelistEnabled || (isWhitelisted(sender) && isWhitelisted(recipient) && isWhitelisted(msg.sender)), "ERC20: sender, recipient, and/or authorized caller is not whitelisted");
        require(!isLpPoolLocked(recipient), "ERC20: transfer to locked LP pool");
        return super.transferFrom(sender, recipient, amount);
    }

    function approve(address spender, uint256 amount) public override returns (bool) {
        require(!isBlacklisted(_msgSender()), "ERC20: approve from blacklisted address");
        require(!isBlacklisted(spender), "ERC20: approve to blacklisted address");

        return super.approve(spender, amount);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ECDSAInvalidSignature","type":"error"},{"inputs":[{"internalType":"uint256","name":"length","type":"uint256"}],"name":"ECDSAInvalidSignatureLength","type":"error"},{"inputs":[{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"ECDSAInvalidSignatureS","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"allowance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientAllowance","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"uint256","name":"balance","type":"uint256"},{"internalType":"uint256","name":"needed","type":"uint256"}],"name":"ERC20InsufficientBalance","type":"error"},{"inputs":[{"internalType":"address","name":"approver","type":"address"}],"name":"ERC20InvalidApprover","type":"error"},{"inputs":[{"internalType":"address","name":"receiver","type":"address"}],"name":"ERC20InvalidReceiver","type":"error"},{"inputs":[{"internalType":"address","name":"sender","type":"address"}],"name":"ERC20InvalidSender","type":"error"},{"inputs":[{"internalType":"address","name":"spender","type":"address"}],"name":"ERC20InvalidSpender","type":"error"},{"inputs":[{"internalType":"uint256","name":"deadline","type":"uint256"}],"name":"ERC2612ExpiredSignature","type":"error"},{"inputs":[{"internalType":"address","name":"signer","type":"address"},{"internalType":"address","name":"owner","type":"address"}],"name":"ERC2612InvalidSigner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"currentNonce","type":"uint256"}],"name":"InvalidAccountNonce","type":"error"},{"inputs":[],"name":"InvalidShortString","type":"error"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"OwnableInvalidOwner","type":"error"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"OwnableUnauthorizedAccount","type":"error"},{"inputs":[{"internalType":"string","name":"str","type":"string"}],"name":"StringTooLong","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[],"name":"EIP712DomainChanged","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":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DOMAIN_SEPARATOR","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"poolAddress","type":"address"},{"internalType":"uint256","name":"lockEndTime","type":"uint256"}],"name":"addLockLpPool","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addToBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"addToWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"approve","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"eip712Domain","outputs":[{"internalType":"bytes1","name":"fields","type":"bytes1"},{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"version","type":"string"},{"internalType":"uint256","name":"chainId","type":"uint256"},{"internalType":"address","name":"verifyingContract","type":"address"},{"internalType":"bytes32","name":"salt","type":"bytes32"},{"internalType":"uint256[]","name":"extensions","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isBlacklisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"poolAddress","type":"address"}],"name":"isLpPoolLocked","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"isWhitelisted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"nonces","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"value","type":"uint256"},{"internalType":"uint256","name":"deadline","type":"uint256"},{"internalType":"uint8","name":"v","type":"uint8"},{"internalType":"bytes32","name":"r","type":"bytes32"},{"internalType":"bytes32","name":"s","type":"bytes32"}],"name":"permit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeFromBlacklist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"removeFromWhitelist","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"enabled","type":"bool"}],"name":"setWhitelistEnabled","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"sender","type":"address"},{"internalType":"address","name":"recipient","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transferFrom","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6101606040525f600c5f6101000a81548160ff0219169083151502179055503480156200002a575f80fd5b50336040518060400160405280600481526020017f2442494300000000000000000000000000000000000000000000000000000000815250806040518060400160405280600181526020017f31000000000000000000000000000000000000000000000000000000000000008152506040518060400160405280600d81526020017f42696720697320436f6d696e67000000000000000000000000000000000000008152506040518060400160405280600481526020017f24424943000000000000000000000000000000000000000000000000000000008152508160039081620001169190620009ab565b508060049081620001289190620009ab565b50505062000141600583620002aa60201b90919060201c565b61012081815250506200015f600682620002aa60201b90919060201c565b6101408181525050818051906020012060e08181525050808051906020012061010081815250504660a081815250506200019e620002ff60201b60201c565b608081815250503073ffffffffffffffffffffffffffffffffffffffff1660c08173ffffffffffffffffffffffffffffffffffffffff16815250505050505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036200024f575f6040517f1e4fbdf700000000000000000000000000000000000000000000000000000000815260040162000246919062000ad2565b60405180910390fd5b62000260816200035b60201b60201c565b50620002a433620002766200041e60201b60201c565b600a62000284919062000c76565b66038d7ea4c6800062000298919062000cc6565b6200042660201b60201c565b62000f70565b5f602083511015620002cf57620002c783620004b060201b60201c565b9050620002f9565b82620002e1836200051a60201b60201c565b5f019081620002f19190620009ab565b5060ff5f1b90505b92915050565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f60e0516101005146306040516020016200034095949392919062000d3b565b60405160208183030381529060405280519060200120905090565b5f60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160085f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f6012905090565b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160362000499575f6040517fec442f0500000000000000000000000000000000000000000000000000000000815260040162000490919062000ad2565b60405180910390fd5b620004ac5f83836200052360201b60201c565b5050565b5f80829050601f81511115620004ff57826040517f305a27a9000000000000000000000000000000000000000000000000000000008152600401620004f6919062000e20565b60405180910390fd5b8051816200050d9062000e71565b5f1c175f1b915050919050565b5f819050919050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff160362000577578060025f8282546200056a919062000ee0565b9250508190555062000648565b5f805f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205490508181101562000603578381836040517fe450d38c000000000000000000000000000000000000000000000000000000008152600401620005fa9392919062000f1a565b60405180910390fd5b8181035f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff160362000691578060025f8282540392505081905550620006db565b805f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef836040516200073a919062000f55565b60405180910390a3505050565b5f81519050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f6002820490506001821680620007c357607f821691505b602082108103620007d957620007d86200077e565b5b50919050565b5f819050815f5260205f209050919050565b5f6020601f8301049050919050565b5f82821b905092915050565b5f600883026200083d7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8262000800565b62000849868362000800565b95508019841693508086168417925050509392505050565b5f819050919050565b5f819050919050565b5f620008936200088d620008878462000861565b6200086a565b62000861565b9050919050565b5f819050919050565b620008ae8362000873565b620008c6620008bd826200089a565b8484546200080c565b825550505050565b5f90565b620008dc620008ce565b620008e9818484620008a3565b505050565b5b818110156200091057620009045f82620008d2565b600181019050620008ef565b5050565b601f8211156200095f576200092981620007df565b6200093484620007f1565b8101602085101562000944578190505b6200095c6200095385620007f1565b830182620008ee565b50505b505050565b5f82821c905092915050565b5f620009815f198460080262000964565b1980831691505092915050565b5f6200099b838362000970565b9150826002028217905092915050565b620009b68262000747565b67ffffffffffffffff811115620009d257620009d162000751565b5b620009de8254620007ab565b620009eb82828562000914565b5f60209050601f83116001811462000a21575f841562000a0c578287015190505b62000a1885826200098e565b86555062000a87565b601f19841662000a3186620007df565b5f5b8281101562000a5a5784890151825560018201915060208501945060208101905062000a33565b8683101562000a7a578489015162000a76601f89168262000970565b8355505b6001600288020188555050505b505050505050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f62000aba8262000a8f565b9050919050565b62000acc8162000aae565b82525050565b5f60208201905062000ae75f83018462000ac1565b92915050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f8160011c9050919050565b5f808291508390505b600185111562000b775780860481111562000b4f5762000b4e62000aed565b5b600185161562000b5f5780820291505b808102905062000b6f8562000b1a565b945062000b2f565b94509492505050565b5f8262000b91576001905062000c63565b8162000ba0575f905062000c63565b816001811462000bb9576002811462000bc45762000bfa565b600191505062000c63565b60ff84111562000bd95762000bd862000aed565b5b8360020a91508482111562000bf35762000bf262000aed565b5b5062000c63565b5060208310610133831016604e8410600b841016171562000c345782820a90508381111562000c2e5762000c2d62000aed565b5b62000c63565b62000c43848484600162000b26565b9250905081840481111562000c5d5762000c5c62000aed565b5b81810290505b9392505050565b5f60ff82169050919050565b5f62000c828262000861565b915062000c8f8362000c6a565b925062000cbe7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff848462000b80565b905092915050565b5f62000cd28262000861565b915062000cdf8362000861565b925082820262000cef8162000861565b9150828204841483151762000d095762000d0862000aed565b5b5092915050565b5f819050919050565b62000d248162000d10565b82525050565b62000d358162000861565b82525050565b5f60a08201905062000d505f83018862000d19565b62000d5f602083018762000d19565b62000d6e604083018662000d19565b62000d7d606083018562000d2a565b62000d8c608083018462000ac1565b9695505050505050565b5f82825260208201905092915050565b5f5b8381101562000dc557808201518184015260208101905062000da8565b5f8484015250505050565b5f601f19601f8301169050919050565b5f62000dec8262000747565b62000df8818562000d96565b935062000e0a81856020860162000da6565b62000e158162000dd0565b840191505092915050565b5f6020820190508181035f83015262000e3a818462000de0565b905092915050565b5f81519050919050565b5f819050602082019050919050565b5f62000e68825162000d10565b80915050919050565b5f62000e7d8262000e42565b8262000e898462000e4c565b905062000e968162000e5b565b9250602082101562000ed95762000ed47fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8360200360080262000800565b831692505b5050919050565b5f62000eec8262000861565b915062000ef98362000861565b925082820190508082111562000f145762000f1362000aed565b5b92915050565b5f60608201905062000f2f5f83018662000ac1565b62000f3e602083018562000d2a565b62000f4d604083018462000d2a565b949350505050565b5f60208201905062000f6a5f83018462000d2a565b92915050565b60805160a05160c05160e051610100516101205161014051612d5662000fc25f395f6114ce01525f61149301525f61179501525f61177401525f6112ce01525f61132401525f61134d0152612d565ff3fe608060405234801561000f575f80fd5b5060043610610171575f3560e01c80637ecebe00116100dc578063a9059cbb11610095578063dd62ed3e1161006f578063dd62ed3e1461044f578063e43252d71461047f578063f2fde38b1461049b578063fe575a87146104b757610171565b8063a9059cbb146103e7578063a994fe2d14610417578063d505accf1461043357610171565b80637ecebe001461030b57806384b0196e1461033b57806386840dec1461035f5780638ab1d6811461038f5780638da5cb5b146103ab57806395d89b41146103c957610171565b80633644e5151161012e5780633644e5151461024b5780633af32abf1461026957806344337ea114610299578063537df3b6146102b557806370a08231146102d1578063715018a61461030157610171565b8063052d9e7e1461017557806306fdde0314610191578063095ea7b3146101af57806318160ddd146101df57806323b872dd146101fd578063313ce5671461022d575b5f80fd5b61018f600480360381019061018a9190611ffc565b6104e7565b005b61019961050b565b6040516101a691906120b1565b60405180910390f35b6101c960048036038101906101c4919061215e565b61059b565b6040516101d691906121ab565b60405180910390f35b6101e7610647565b6040516101f491906121d3565b60405180910390f35b610217600480360381019061021291906121ec565b610650565b60405161022491906121ab565b60405180910390f35b61023561080a565b6040516102429190612257565b60405180910390f35b610253610812565b6040516102609190612288565b60405180910390f35b610283600480360381019061027e91906122a1565b610820565b60405161029091906121ab565b60405180910390f35b6102b360048036038101906102ae91906122a1565b610872565b005b6102cf60048036038101906102ca91906122a1565b6108d2565b005b6102eb60048036038101906102e691906122a1565b610931565b6040516102f891906121d3565b60405180910390f35b610309610976565b005b610325600480360381019061032091906122a1565b610989565b60405161033291906121d3565b60405180910390f35b61034361099a565b60405161035697969594939291906123cc565b60405180910390f35b610379600480360381019061037491906122a1565b610a3f565b60405161038691906121ab565b60405180910390f35b6103a960048036038101906103a491906122a1565b610a8a565b005b6103b3610b57565b6040516103c0919061244e565b60405180910390f35b6103d1610b7f565b6040516103de91906120b1565b60405180910390f35b61040160048036038101906103fc919061215e565b610c0f565b60405161040e91906121ab565b60405180910390f35b610431600480360381019061042c919061215e565b610dbd565b005b61044d600480360381019061044891906124bb565b610e82565b005b61046960048036038101906104649190612558565b610fc7565b60405161047691906121d3565b60405180910390f35b610499600480360381019061049491906122a1565b611049565b005b6104b560048036038101906104b091906122a1565b611117565b005b6104d160048036038101906104cc91906122a1565b61119b565b6040516104de91906121ab565b60405180910390f35b6104ef6111ed565b80600c5f6101000a81548160ff02191690831515021790555050565b60606003805461051a906125c3565b80601f0160208091040260200160405190810160405280929190818152602001828054610546906125c3565b80156105915780601f1061056857610100808354040283529160200191610591565b820191905f5260205f20905b81548152906001019060200180831161057457829003601f168201915b5050505050905090565b5f6105ac6105a7611274565b61119b565b156105ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e390612663565b60405180910390fd5b6105f58361119b565b15610635576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161062c906126f1565b60405180910390fd5b61063f838361127b565b905092915050565b5f600254905090565b5f61065a8461119b565b1561069a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106919061277f565b60405180910390fd5b6106a38361119b565b156106e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106da9061280d565b60405180910390fd5b6106ec83610a3f565b1561072c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107239061289b565b60405180910390fd5b600c5f9054906101000a900460ff16158061076e575061074b84610820565b801561075c575061075b83610820565b5b801561076d575061076c33610820565b5b5b6107ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107a49061294f565b60405180910390fd5b6107b683610a3f565b156107f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107ed9061289b565b60405180910390fd5b61080184848461129d565b90509392505050565b5f6012905090565b5f61081b6112cb565b905090565b5f600b5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff169050919050565b61087a6111ed565b600160095f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555050565b6108da6111ed565b5f60095f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555050565b5f805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b61097e6111ed565b6109875f611381565b565b5f61099382611444565b9050919050565b5f6060805f805f60606109ab61148a565b6109b36114c5565b46305f801b5f67ffffffffffffffff8111156109d2576109d161296d565b5b604051908082528060200260200182016040528015610a005781602001602082028036833780820191505090505b507f0f00000000000000000000000000000000000000000000000000000000000000959493929190965096509650965096509650965090919293949596565b5f42600a5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010154119050919050565b610a926111ed565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610b00576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af790612a0a565b60405180910390fd5b5f600b5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555050565b5f60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060048054610b8e906125c3565b80601f0160208091040260200160405190810160405280929190818152602001828054610bba906125c3565b8015610c055780601f10610bdc57610100808354040283529160200191610c05565b820191905f5260205f20905b815481529060010190602001808311610be857829003601f168201915b5050505050905090565b5f610c20610c1b611274565b61119b565b15610c60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c579061277f565b60405180910390fd5b610c698361119b565b15610ca9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca09061280d565b60405180910390fd5b610cb283610a3f565b15610cf2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce99061289b565b60405180910390fd5b600c5f9054906101000a900460ff161580610d235750610d1133610820565b8015610d225750610d2183610820565b5b5b610d62576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d5990612a98565b60405180910390fd5b610d6b83610a3f565b15610dab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610da29061289b565b60405180910390fd5b610db58383611500565b905092915050565b610dc56111ed565b60405180604001604052808373ffffffffffffffffffffffffffffffffffffffff16815260200182815250600a5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101559050505050565b83421115610ec757836040517f62791302000000000000000000000000000000000000000000000000000000008152600401610ebe91906121d3565b60405180910390fd5b5f7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9888888610ef58c611522565b89604051602001610f0b96959493929190612ab6565b6040516020818303038152906040528051906020012090505f610f2d82611575565b90505f610f3c8287878761158e565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610fb057808a6040517f4b800e46000000000000000000000000000000000000000000000000000000008152600401610fa7929190612b15565b60405180910390fd5b610fbb8a8a8a6115bc565b50505050505050505050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b6110516111ed565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036110bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b690612bac565b60405180910390fd5b6001600b5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555050565b61111f6111ed565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361118f575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401611186919061244e565b60405180910390fd5b61119881611381565b50565b5f60095f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff169050919050565b6111f5611274565b73ffffffffffffffffffffffffffffffffffffffff16611213610b57565b73ffffffffffffffffffffffffffffffffffffffff161461127257611236611274565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401611269919061244e565b60405180910390fd5b565b5f33905090565b5f80611285611274565b90506112928185856115bc565b600191505092915050565b5f806112a7611274565b90506112b48582856115ce565b6112bf858585611660565b60019150509392505050565b5f7f000000000000000000000000000000000000000000000000000000000000000073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1614801561134657507f000000000000000000000000000000000000000000000000000000000000000046145b15611373577f0000000000000000000000000000000000000000000000000000000000000000905061137e565b61137b611750565b90505b90565b5f60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160085f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f60075f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b60606114c060057f00000000000000000000000000000000000000000000000000000000000000006117e590919063ffffffff16565b905090565b60606114fb60067f00000000000000000000000000000000000000000000000000000000000000006117e590919063ffffffff16565b905090565b5f8061150a611274565b9050611517818585611660565b600191505092915050565b5f60075f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f815480929190600101919050559050919050565b5f6115876115816112cb565b83611892565b9050919050565b5f805f8061159e888888886118d2565b9250925092506115ae82826119b9565b829350505050949350505050565b6115c98383836001611b1b565b505050565b5f6115d98484610fc7565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461165a578181101561164b578281836040517ffb8f41b200000000000000000000000000000000000000000000000000000000815260040161164293929190612bca565b60405180910390fd5b61165984848484035f611b1b565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036116d0575f6040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081526004016116c7919061244e565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611740575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401611737919061244e565b60405180910390fd5b61174b838383611cea565b505050565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000046306040516020016117ca959493929190612bff565b60405160208183030381529060405280519060200120905090565b606060ff5f1b8314611801576117fa83611f03565b905061188c565b81805461180d906125c3565b80601f0160208091040260200160405190810160405280929190818152602001828054611839906125c3565b80156118845780601f1061185b57610100808354040283529160200191611884565b820191905f5260205f20905b81548152906001019060200180831161186757829003601f168201915b505050505090505b92915050565b5f6040517f190100000000000000000000000000000000000000000000000000000000000081528360028201528260228201526042812091505092915050565b5f805f7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0845f1c111561190e575f6003859250925092506119af565b5f6001888888886040515f81526020016040526040516119319493929190612c50565b6020604051602081039080840390855afa158015611951573d5f803e3d5ffd5b5050506020604051035190505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036119a2575f60015f801b935093509350506119af565b805f805f1b935093509350505b9450945094915050565b5f60038111156119cc576119cb612c93565b5b8260038111156119df576119de612c93565b5b0315611b1757600160038111156119f9576119f8612c93565b5b826003811115611a0c57611a0b612c93565b5b03611a43576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026003811115611a5757611a56612c93565b5b826003811115611a6a57611a69612c93565b5b03611aae57805f1c6040517ffce698f7000000000000000000000000000000000000000000000000000000008152600401611aa591906121d3565b60405180910390fd5b600380811115611ac157611ac0612c93565b5b826003811115611ad457611ad3612c93565b5b03611b1657806040517fd78bce0c000000000000000000000000000000000000000000000000000000008152600401611b0d9190612288565b60405180910390fd5b5b5050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611b8b575f6040517fe602df05000000000000000000000000000000000000000000000000000000008152600401611b82919061244e565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611bfb575f6040517f94280d62000000000000000000000000000000000000000000000000000000008152600401611bf2919061244e565b60405180910390fd5b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508015611ce4578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051611cdb91906121d3565b60405180910390a35b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d3a578060025f828254611d2e9190612ced565b92505081905550611e08565b5f805f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015611dc3578381836040517fe450d38c000000000000000000000000000000000000000000000000000000008152600401611dba93929190612bca565b60405180910390fd5b8181035f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611e4f578060025f8282540392505081905550611e99565b805f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611ef691906121d3565b60405180910390a3505050565b60605f611f0f83611f75565b90505f602067ffffffffffffffff811115611f2d57611f2c61296d565b5b6040519080825280601f01601f191660200182016040528015611f5f5781602001600182028036833780820191505090505b5090508181528360208201528092505050919050565b5f8060ff835f1c169050601f811115611fba576040517fb3512b0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80915050919050565b5f80fd5b5f8115159050919050565b611fdb81611fc7565b8114611fe5575f80fd5b50565b5f81359050611ff681611fd2565b92915050565b5f6020828403121561201157612010611fc3565b5b5f61201e84828501611fe8565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561205e578082015181840152602081019050612043565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61208382612027565b61208d8185612031565b935061209d818560208601612041565b6120a681612069565b840191505092915050565b5f6020820190508181035f8301526120c98184612079565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6120fa826120d1565b9050919050565b61210a816120f0565b8114612114575f80fd5b50565b5f8135905061212581612101565b92915050565b5f819050919050565b61213d8161212b565b8114612147575f80fd5b50565b5f8135905061215881612134565b92915050565b5f806040838503121561217457612173611fc3565b5b5f61218185828601612117565b92505060206121928582860161214a565b9150509250929050565b6121a581611fc7565b82525050565b5f6020820190506121be5f83018461219c565b92915050565b6121cd8161212b565b82525050565b5f6020820190506121e65f8301846121c4565b92915050565b5f805f6060848603121561220357612202611fc3565b5b5f61221086828701612117565b935050602061222186828701612117565b92505060406122328682870161214a565b9150509250925092565b5f60ff82169050919050565b6122518161223c565b82525050565b5f60208201905061226a5f830184612248565b92915050565b5f819050919050565b61228281612270565b82525050565b5f60208201905061229b5f830184612279565b92915050565b5f602082840312156122b6576122b5611fc3565b5b5f6122c384828501612117565b91505092915050565b5f7fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b612300816122cc565b82525050565b61230f816120f0565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6123478161212b565b82525050565b5f612358838361233e565b60208301905092915050565b5f602082019050919050565b5f61237a82612315565b612384818561231f565b935061238f8361232f565b805f5b838110156123bf5781516123a6888261234d565b97506123b183612364565b925050600181019050612392565b5085935050505092915050565b5f60e0820190506123df5f83018a6122f7565b81810360208301526123f18189612079565b905081810360408301526124058188612079565b905061241460608301876121c4565b6124216080830186612306565b61242e60a0830185612279565b81810360c08301526124408184612370565b905098975050505050505050565b5f6020820190506124615f830184612306565b92915050565b6124708161223c565b811461247a575f80fd5b50565b5f8135905061248b81612467565b92915050565b61249a81612270565b81146124a4575f80fd5b50565b5f813590506124b581612491565b92915050565b5f805f805f805f60e0888a0312156124d6576124d5611fc3565b5b5f6124e38a828b01612117565b97505060206124f48a828b01612117565b96505060406125058a828b0161214a565b95505060606125168a828b0161214a565b94505060806125278a828b0161247d565b93505060a06125388a828b016124a7565b92505060c06125498a828b016124a7565b91505092959891949750929550565b5f806040838503121561256e5761256d611fc3565b5b5f61257b85828601612117565b925050602061258c85828601612117565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806125da57607f821691505b6020821081036125ed576125ec612596565b5b50919050565b7f45524332303a20617070726f76652066726f6d20626c61636b6c6973746564205f8201527f6164647265737300000000000000000000000000000000000000000000000000602082015250565b5f61264d602783612031565b9150612658826125f3565b604082019050919050565b5f6020820190508181035f83015261267a81612641565b9050919050565b7f45524332303a20617070726f766520746f20626c61636b6c69737465642061645f8201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b5f6126db602583612031565b91506126e682612681565b604082019050919050565b5f6020820190508181035f830152612708816126cf565b9050919050565b7f45524332303a207472616e736665722066726f6d20626c61636b6c69737465645f8201527f2061646472657373000000000000000000000000000000000000000000000000602082015250565b5f612769602883612031565b91506127748261270f565b604082019050919050565b5f6020820190508181035f8301526127968161275d565b9050919050565b7f45524332303a207472616e7366657220746f20626c61636b6c697374656420615f8201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b5f6127f7602683612031565b91506128028261279d565b604082019050919050565b5f6020820190508181035f830152612824816127eb565b9050919050565b7f45524332303a207472616e7366657220746f206c6f636b6564204c5020706f6f5f8201527f6c00000000000000000000000000000000000000000000000000000000000000602082015250565b5f612885602183612031565b91506128908261282b565b604082019050919050565b5f6020820190508181035f8301526128b281612879565b9050919050565b7f45524332303a2073656e6465722c20726563697069656e742c20616e642f6f725f8201527f20617574686f72697a65642063616c6c6572206973206e6f742077686974656c60208201527f6973746564000000000000000000000000000000000000000000000000000000604082015250565b5f612939604583612031565b9150612944826128b9565b606082019050919050565b5f6020820190508181035f8301526129668161292d565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f43616e6e6f742072656d6f7665207a65726f20616464726573732066726f6d205f8201527f77686974656c6973740000000000000000000000000000000000000000000000602082015250565b5f6129f4602983612031565b91506129ff8261299a565b604082019050919050565b5f6020820190508181035f830152612a21816129e8565b9050919050565b7f45524332303a2073656e64657220616e642f6f7220726563697069656e7420695f8201527f73206e6f742077686974656c6973746564000000000000000000000000000000602082015250565b5f612a82603183612031565b9150612a8d82612a28565b604082019050919050565b5f6020820190508181035f830152612aaf81612a76565b9050919050565b5f60c082019050612ac95f830189612279565b612ad66020830188612306565b612ae36040830187612306565b612af060608301866121c4565b612afd60808301856121c4565b612b0a60a08301846121c4565b979650505050505050565b5f604082019050612b285f830185612306565b612b356020830184612306565b9392505050565b7f43616e6e6f7420616464207a65726f206164647265737320746f2077686974655f8201527f6c69737400000000000000000000000000000000000000000000000000000000602082015250565b5f612b96602483612031565b9150612ba182612b3c565b604082019050919050565b5f6020820190508181035f830152612bc381612b8a565b9050919050565b5f606082019050612bdd5f830186612306565b612bea60208301856121c4565b612bf760408301846121c4565b949350505050565b5f60a082019050612c125f830188612279565b612c1f6020830187612279565b612c2c6040830186612279565b612c3960608301856121c4565b612c466080830184612306565b9695505050505050565b5f608082019050612c635f830187612279565b612c706020830186612248565b612c7d6040830185612279565b612c8a6060830184612279565b95945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612cf78261212b565b9150612d028361212b565b9250828201905080821115612d1a57612d19612cc0565b5b9291505056fea2646970667358221220c98f202613ce3861c4e1621f7628e03334235184bd24635c68aaae31c27752b864736f6c63430008180033

Deployed Bytecode

0x608060405234801561000f575f80fd5b5060043610610171575f3560e01c80637ecebe00116100dc578063a9059cbb11610095578063dd62ed3e1161006f578063dd62ed3e1461044f578063e43252d71461047f578063f2fde38b1461049b578063fe575a87146104b757610171565b8063a9059cbb146103e7578063a994fe2d14610417578063d505accf1461043357610171565b80637ecebe001461030b57806384b0196e1461033b57806386840dec1461035f5780638ab1d6811461038f5780638da5cb5b146103ab57806395d89b41146103c957610171565b80633644e5151161012e5780633644e5151461024b5780633af32abf1461026957806344337ea114610299578063537df3b6146102b557806370a08231146102d1578063715018a61461030157610171565b8063052d9e7e1461017557806306fdde0314610191578063095ea7b3146101af57806318160ddd146101df57806323b872dd146101fd578063313ce5671461022d575b5f80fd5b61018f600480360381019061018a9190611ffc565b6104e7565b005b61019961050b565b6040516101a691906120b1565b60405180910390f35b6101c960048036038101906101c4919061215e565b61059b565b6040516101d691906121ab565b60405180910390f35b6101e7610647565b6040516101f491906121d3565b60405180910390f35b610217600480360381019061021291906121ec565b610650565b60405161022491906121ab565b60405180910390f35b61023561080a565b6040516102429190612257565b60405180910390f35b610253610812565b6040516102609190612288565b60405180910390f35b610283600480360381019061027e91906122a1565b610820565b60405161029091906121ab565b60405180910390f35b6102b360048036038101906102ae91906122a1565b610872565b005b6102cf60048036038101906102ca91906122a1565b6108d2565b005b6102eb60048036038101906102e691906122a1565b610931565b6040516102f891906121d3565b60405180910390f35b610309610976565b005b610325600480360381019061032091906122a1565b610989565b60405161033291906121d3565b60405180910390f35b61034361099a565b60405161035697969594939291906123cc565b60405180910390f35b610379600480360381019061037491906122a1565b610a3f565b60405161038691906121ab565b60405180910390f35b6103a960048036038101906103a491906122a1565b610a8a565b005b6103b3610b57565b6040516103c0919061244e565b60405180910390f35b6103d1610b7f565b6040516103de91906120b1565b60405180910390f35b61040160048036038101906103fc919061215e565b610c0f565b60405161040e91906121ab565b60405180910390f35b610431600480360381019061042c919061215e565b610dbd565b005b61044d600480360381019061044891906124bb565b610e82565b005b61046960048036038101906104649190612558565b610fc7565b60405161047691906121d3565b60405180910390f35b610499600480360381019061049491906122a1565b611049565b005b6104b560048036038101906104b091906122a1565b611117565b005b6104d160048036038101906104cc91906122a1565b61119b565b6040516104de91906121ab565b60405180910390f35b6104ef6111ed565b80600c5f6101000a81548160ff02191690831515021790555050565b60606003805461051a906125c3565b80601f0160208091040260200160405190810160405280929190818152602001828054610546906125c3565b80156105915780601f1061056857610100808354040283529160200191610591565b820191905f5260205f20905b81548152906001019060200180831161057457829003601f168201915b5050505050905090565b5f6105ac6105a7611274565b61119b565b156105ec576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016105e390612663565b60405180910390fd5b6105f58361119b565b15610635576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161062c906126f1565b60405180910390fd5b61063f838361127b565b905092915050565b5f600254905090565b5f61065a8461119b565b1561069a576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106919061277f565b60405180910390fd5b6106a38361119b565b156106e3576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016106da9061280d565b60405180910390fd5b6106ec83610a3f565b1561072c576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107239061289b565b60405180910390fd5b600c5f9054906101000a900460ff16158061076e575061074b84610820565b801561075c575061075b83610820565b5b801561076d575061076c33610820565b5b5b6107ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107a49061294f565b60405180910390fd5b6107b683610a3f565b156107f6576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016107ed9061289b565b60405180910390fd5b61080184848461129d565b90509392505050565b5f6012905090565b5f61081b6112cb565b905090565b5f600b5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff169050919050565b61087a6111ed565b600160095f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555050565b6108da6111ed565b5f60095f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555050565b5f805f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b61097e6111ed565b6109875f611381565b565b5f61099382611444565b9050919050565b5f6060805f805f60606109ab61148a565b6109b36114c5565b46305f801b5f67ffffffffffffffff8111156109d2576109d161296d565b5b604051908082528060200260200182016040528015610a005781602001602082028036833780820191505090505b507f0f00000000000000000000000000000000000000000000000000000000000000959493929190965096509650965096509650965090919293949596565b5f42600a5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2060010154119050919050565b610a926111ed565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603610b00576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af790612a0a565b60405180910390fd5b5f600b5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555050565b5f60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b606060048054610b8e906125c3565b80601f0160208091040260200160405190810160405280929190818152602001828054610bba906125c3565b8015610c055780601f10610bdc57610100808354040283529160200191610c05565b820191905f5260205f20905b815481529060010190602001808311610be857829003601f168201915b5050505050905090565b5f610c20610c1b611274565b61119b565b15610c60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c579061277f565b60405180910390fd5b610c698361119b565b15610ca9576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ca09061280d565b60405180910390fd5b610cb283610a3f565b15610cf2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ce99061289b565b60405180910390fd5b600c5f9054906101000a900460ff161580610d235750610d1133610820565b8015610d225750610d2183610820565b5b5b610d62576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d5990612a98565b60405180910390fd5b610d6b83610a3f565b15610dab576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610da29061289b565b60405180910390fd5b610db58383611500565b905092915050565b610dc56111ed565b60405180604001604052808373ffffffffffffffffffffffffffffffffffffffff16815260200182815250600a5f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f820151815f015f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550602082015181600101559050505050565b83421115610ec757836040517f62791302000000000000000000000000000000000000000000000000000000008152600401610ebe91906121d3565b60405180910390fd5b5f7f6e71edae12b1b97f4d1f60370fef10105fa2faae0126114a169c64845d6126c9888888610ef58c611522565b89604051602001610f0b96959493929190612ab6565b6040516020818303038152906040528051906020012090505f610f2d82611575565b90505f610f3c8287878761158e565b90508973ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610fb057808a6040517f4b800e46000000000000000000000000000000000000000000000000000000008152600401610fa7929190612b15565b60405180910390fd5b610fbb8a8a8a6115bc565b50505050505050505050565b5f60015f8473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905092915050565b6110516111ed565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036110bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b690612bac565b60405180910390fd5b6001600b5f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f6101000a81548160ff02191690831515021790555050565b61111f6111ed565b5f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff160361118f575f6040517f1e4fbdf7000000000000000000000000000000000000000000000000000000008152600401611186919061244e565b60405180910390fd5b61119881611381565b50565b5f60095f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f9054906101000a900460ff169050919050565b6111f5611274565b73ffffffffffffffffffffffffffffffffffffffff16611213610b57565b73ffffffffffffffffffffffffffffffffffffffff161461127257611236611274565b6040517f118cdaa7000000000000000000000000000000000000000000000000000000008152600401611269919061244e565b60405180910390fd5b565b5f33905090565b5f80611285611274565b90506112928185856115bc565b600191505092915050565b5f806112a7611274565b90506112b48582856115ce565b6112bf858585611660565b60019150509392505050565b5f7f000000000000000000000000b1421ba225e75448ed0246663d5c48e3d400d01073ffffffffffffffffffffffffffffffffffffffff163073ffffffffffffffffffffffffffffffffffffffff1614801561134657507f000000000000000000000000000000000000000000000000000000000000000146145b15611373577f5298d8e8431ee3fa7f7f5178768ad08800c66070d1e3bd5f63139b09eccfb0b3905061137e565b61137b611750565b90505b90565b5f60085f9054906101000a900473ffffffffffffffffffffffffffffffffffffffff1690508160085f6101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b5f60075f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20549050919050565b60606114c060057f24424943000000000000000000000000000000000000000000000000000000046117e590919063ffffffff16565b905090565b60606114fb60067f31000000000000000000000000000000000000000000000000000000000000016117e590919063ffffffff16565b905090565b5f8061150a611274565b9050611517818585611660565b600191505092915050565b5f60075f8373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f815480929190600101919050559050919050565b5f6115876115816112cb565b83611892565b9050919050565b5f805f8061159e888888886118d2565b9250925092506115ae82826119b9565b829350505050949350505050565b6115c98383836001611b1b565b505050565b5f6115d98484610fc7565b90507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff811461165a578181101561164b578281836040517ffb8f41b200000000000000000000000000000000000000000000000000000000815260040161164293929190612bca565b60405180910390fd5b61165984848484035f611b1b565b5b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16036116d0575f6040517f96c6fd1e0000000000000000000000000000000000000000000000000000000081526004016116c7919061244e565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611740575f6040517fec442f05000000000000000000000000000000000000000000000000000000008152600401611737919061244e565b60405180910390fd5b61174b838383611cea565b505050565b5f7f8b73c3c69bb8fe3d512ecc4cf759cc79239f7b179b0ffacaa9a75d522b39400f7f3c11548e3170bc1a528ea6f4b9c031a17c0a15e5dc043da30310b525986adaa87fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc646306040516020016117ca959493929190612bff565b60405160208183030381529060405280519060200120905090565b606060ff5f1b8314611801576117fa83611f03565b905061188c565b81805461180d906125c3565b80601f0160208091040260200160405190810160405280929190818152602001828054611839906125c3565b80156118845780601f1061185b57610100808354040283529160200191611884565b820191905f5260205f20905b81548152906001019060200180831161186757829003601f168201915b505050505090505b92915050565b5f6040517f190100000000000000000000000000000000000000000000000000000000000081528360028201528260228201526042812091505092915050565b5f805f7f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a0845f1c111561190e575f6003859250925092506119af565b5f6001888888886040515f81526020016040526040516119319493929190612c50565b6020604051602081039080840390855afa158015611951573d5f803e3d5ffd5b5050506020604051035190505f73ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16036119a2575f60015f801b935093509350506119af565b805f805f1b935093509350505b9450945094915050565b5f60038111156119cc576119cb612c93565b5b8260038111156119df576119de612c93565b5b0315611b1757600160038111156119f9576119f8612c93565b5b826003811115611a0c57611a0b612c93565b5b03611a43576040517ff645eedf00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60026003811115611a5757611a56612c93565b5b826003811115611a6a57611a69612c93565b5b03611aae57805f1c6040517ffce698f7000000000000000000000000000000000000000000000000000000008152600401611aa591906121d3565b60405180910390fd5b600380811115611ac157611ac0612c93565b5b826003811115611ad457611ad3612c93565b5b03611b1657806040517fd78bce0c000000000000000000000000000000000000000000000000000000008152600401611b0d9190612288565b60405180910390fd5b5b5050565b5f73ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1603611b8b575f6040517fe602df05000000000000000000000000000000000000000000000000000000008152600401611b82919061244e565b60405180910390fd5b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611bfb575f6040517f94280d62000000000000000000000000000000000000000000000000000000008152600401611bf2919061244e565b60405180910390fd5b8160015f8673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f20819055508015611ce4578273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92584604051611cdb91906121d3565b60405180910390a35b50505050565b5f73ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1603611d3a578060025f828254611d2e9190612ced565b92505081905550611e08565b5f805f8573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2054905081811015611dc3578381836040517fe450d38c000000000000000000000000000000000000000000000000000000008152600401611dba93929190612bca565b60405180910390fd5b8181035f808673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f2081905550505b5f73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603611e4f578060025f8282540392505081905550611e99565b805f808473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020015f205f82825401925050819055505b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef83604051611ef691906121d3565b60405180910390a3505050565b60605f611f0f83611f75565b90505f602067ffffffffffffffff811115611f2d57611f2c61296d565b5b6040519080825280601f01601f191660200182016040528015611f5f5781602001600182028036833780820191505090505b5090508181528360208201528092505050919050565b5f8060ff835f1c169050601f811115611fba576040517fb3512b0c00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80915050919050565b5f80fd5b5f8115159050919050565b611fdb81611fc7565b8114611fe5575f80fd5b50565b5f81359050611ff681611fd2565b92915050565b5f6020828403121561201157612010611fc3565b5b5f61201e84828501611fe8565b91505092915050565b5f81519050919050565b5f82825260208201905092915050565b5f5b8381101561205e578082015181840152602081019050612043565b5f8484015250505050565b5f601f19601f8301169050919050565b5f61208382612027565b61208d8185612031565b935061209d818560208601612041565b6120a681612069565b840191505092915050565b5f6020820190508181035f8301526120c98184612079565b905092915050565b5f73ffffffffffffffffffffffffffffffffffffffff82169050919050565b5f6120fa826120d1565b9050919050565b61210a816120f0565b8114612114575f80fd5b50565b5f8135905061212581612101565b92915050565b5f819050919050565b61213d8161212b565b8114612147575f80fd5b50565b5f8135905061215881612134565b92915050565b5f806040838503121561217457612173611fc3565b5b5f61218185828601612117565b92505060206121928582860161214a565b9150509250929050565b6121a581611fc7565b82525050565b5f6020820190506121be5f83018461219c565b92915050565b6121cd8161212b565b82525050565b5f6020820190506121e65f8301846121c4565b92915050565b5f805f6060848603121561220357612202611fc3565b5b5f61221086828701612117565b935050602061222186828701612117565b92505060406122328682870161214a565b9150509250925092565b5f60ff82169050919050565b6122518161223c565b82525050565b5f60208201905061226a5f830184612248565b92915050565b5f819050919050565b61228281612270565b82525050565b5f60208201905061229b5f830184612279565b92915050565b5f602082840312156122b6576122b5611fc3565b5b5f6122c384828501612117565b91505092915050565b5f7fff0000000000000000000000000000000000000000000000000000000000000082169050919050565b612300816122cc565b82525050565b61230f816120f0565b82525050565b5f81519050919050565b5f82825260208201905092915050565b5f819050602082019050919050565b6123478161212b565b82525050565b5f612358838361233e565b60208301905092915050565b5f602082019050919050565b5f61237a82612315565b612384818561231f565b935061238f8361232f565b805f5b838110156123bf5781516123a6888261234d565b97506123b183612364565b925050600181019050612392565b5085935050505092915050565b5f60e0820190506123df5f83018a6122f7565b81810360208301526123f18189612079565b905081810360408301526124058188612079565b905061241460608301876121c4565b6124216080830186612306565b61242e60a0830185612279565b81810360c08301526124408184612370565b905098975050505050505050565b5f6020820190506124615f830184612306565b92915050565b6124708161223c565b811461247a575f80fd5b50565b5f8135905061248b81612467565b92915050565b61249a81612270565b81146124a4575f80fd5b50565b5f813590506124b581612491565b92915050565b5f805f805f805f60e0888a0312156124d6576124d5611fc3565b5b5f6124e38a828b01612117565b97505060206124f48a828b01612117565b96505060406125058a828b0161214a565b95505060606125168a828b0161214a565b94505060806125278a828b0161247d565b93505060a06125388a828b016124a7565b92505060c06125498a828b016124a7565b91505092959891949750929550565b5f806040838503121561256e5761256d611fc3565b5b5f61257b85828601612117565b925050602061258c85828601612117565b9150509250929050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602260045260245ffd5b5f60028204905060018216806125da57607f821691505b6020821081036125ed576125ec612596565b5b50919050565b7f45524332303a20617070726f76652066726f6d20626c61636b6c6973746564205f8201527f6164647265737300000000000000000000000000000000000000000000000000602082015250565b5f61264d602783612031565b9150612658826125f3565b604082019050919050565b5f6020820190508181035f83015261267a81612641565b9050919050565b7f45524332303a20617070726f766520746f20626c61636b6c69737465642061645f8201527f6472657373000000000000000000000000000000000000000000000000000000602082015250565b5f6126db602583612031565b91506126e682612681565b604082019050919050565b5f6020820190508181035f830152612708816126cf565b9050919050565b7f45524332303a207472616e736665722066726f6d20626c61636b6c69737465645f8201527f2061646472657373000000000000000000000000000000000000000000000000602082015250565b5f612769602883612031565b91506127748261270f565b604082019050919050565b5f6020820190508181035f8301526127968161275d565b9050919050565b7f45524332303a207472616e7366657220746f20626c61636b6c697374656420615f8201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b5f6127f7602683612031565b91506128028261279d565b604082019050919050565b5f6020820190508181035f830152612824816127eb565b9050919050565b7f45524332303a207472616e7366657220746f206c6f636b6564204c5020706f6f5f8201527f6c00000000000000000000000000000000000000000000000000000000000000602082015250565b5f612885602183612031565b91506128908261282b565b604082019050919050565b5f6020820190508181035f8301526128b281612879565b9050919050565b7f45524332303a2073656e6465722c20726563697069656e742c20616e642f6f725f8201527f20617574686f72697a65642063616c6c6572206973206e6f742077686974656c60208201527f6973746564000000000000000000000000000000000000000000000000000000604082015250565b5f612939604583612031565b9150612944826128b9565b606082019050919050565b5f6020820190508181035f8301526129668161292d565b9050919050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52604160045260245ffd5b7f43616e6e6f742072656d6f7665207a65726f20616464726573732066726f6d205f8201527f77686974656c6973740000000000000000000000000000000000000000000000602082015250565b5f6129f4602983612031565b91506129ff8261299a565b604082019050919050565b5f6020820190508181035f830152612a21816129e8565b9050919050565b7f45524332303a2073656e64657220616e642f6f7220726563697069656e7420695f8201527f73206e6f742077686974656c6973746564000000000000000000000000000000602082015250565b5f612a82603183612031565b9150612a8d82612a28565b604082019050919050565b5f6020820190508181035f830152612aaf81612a76565b9050919050565b5f60c082019050612ac95f830189612279565b612ad66020830188612306565b612ae36040830187612306565b612af060608301866121c4565b612afd60808301856121c4565b612b0a60a08301846121c4565b979650505050505050565b5f604082019050612b285f830185612306565b612b356020830184612306565b9392505050565b7f43616e6e6f7420616464207a65726f206164647265737320746f2077686974655f8201527f6c69737400000000000000000000000000000000000000000000000000000000602082015250565b5f612b96602483612031565b9150612ba182612b3c565b604082019050919050565b5f6020820190508181035f830152612bc381612b8a565b9050919050565b5f606082019050612bdd5f830186612306565b612bea60208301856121c4565b612bf760408301846121c4565b949350505050565b5f60a082019050612c125f830188612279565b612c1f6020830187612279565b612c2c6040830186612279565b612c3960608301856121c4565b612c466080830184612306565b9695505050505050565b5f608082019050612c635f830187612279565b612c706020830186612248565b612c7d6040830185612279565b612c8a6060830184612279565b95945050505050565b7f4e487b71000000000000000000000000000000000000000000000000000000005f52602160045260245ffd5b7f4e487b71000000000000000000000000000000000000000000000000000000005f52601160045260245ffd5b5f612cf78261212b565b9150612d028361212b565b9250828201905080821115612d1a57612d19612cc0565b5b9291505056fea2646970667358221220c98f202613ce3861c4e1621f7628e03334235184bd24635c68aaae31c27752b864736f6c63430008180033

Deployed Bytecode Sourcemap

81771:3577:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;82344:106;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;69738:91;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;85031:314;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70840:99;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;84314:709;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70691:84;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;81591:114;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;82853:112;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;82976:103;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83087:109;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;71002:118;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;63351:103;;;:::i;:::-;;81333:145;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;39863:580;;;:::i;:::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;83503:155;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;82650:195;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;62676:87;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69948:95;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83668:638;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;83330:165;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;80579:695;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;71570:142;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;82458:184;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;63609:220;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;83204:112;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;82344:106;62562:13;:11;:13::i;:::-;82435:7:::1;82415:17;;:27;;;;;;;;;;;;;;;;;;82344:106:::0;:::o;69738:91::-;69783:13;69816:5;69809:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69738:91;:::o;85031:314::-;85106:4;85132:27;85146:12;:10;:12::i;:::-;85132:13;:27::i;:::-;85131:28;85123:80;;;;;;;;;;;;:::i;:::-;;;;;;;;;85223:22;85237:7;85223:13;:22::i;:::-;85222:23;85214:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;85307:30;85321:7;85330:6;85307:13;:30::i;:::-;85300:37;;85031:314;;;;:::o;70840:99::-;70892:7;70919:12;;70912:19;;70840:99;:::o;84314:709::-;84412:4;84438:21;84452:6;84438:13;:21::i;:::-;84437:22;84429:75;;;;;;;;;;;;:::i;:::-;;;;;;;;;84524:24;84538:9;84524:13;:24::i;:::-;84523:25;84515:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;84611:25;84626:9;84611:14;:25::i;:::-;84610:26;84602:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;84694:17;;;;;;;;;;;84693:18;:102;;;;84716:21;84730:6;84716:13;:21::i;:::-;:49;;;;;84741:24;84755:9;84741:13;:24::i;:::-;84716:49;:78;;;;;84769:25;84783:10;84769:13;:25::i;:::-;84716:78;84693:102;84685:184;;;;;;;;;;;;:::i;:::-;;;;;;;;;84889:25;84904:9;84889:14;:25::i;:::-;84888:26;84880:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;84970:45;84989:6;84997:9;85008:6;84970:18;:45::i;:::-;84963:52;;84314:709;;;;;:::o;70691:84::-;70740:5;70765:2;70758:9;;70691:84;:::o;81591:114::-;81650:7;81677:20;:18;:20::i;:::-;81670:27;;81591:114;:::o;82853:112::-;82914:4;82938:10;:19;82949:7;82938:19;;;;;;;;;;;;;;;;;;;;;;;;;82931:26;;82853:112;;;:::o;82976:103::-;62562:13;:11;:13::i;:::-;83067:4:::1;83045:10;:19;83056:7;83045:19;;;;;;;;;;;;;;;;:26;;;;;;;;;;;;;;;;;;82976:103:::0;:::o;83087:109::-;62562:13;:11;:13::i;:::-;83183:5:::1;83161:10;:19;83172:7;83161:19;;;;;;;;;;;;;;;;:27;;;;;;;;;;;;;;;;;;83087:109:::0;:::o;71002:118::-;71067:7;71094:9;:18;71104:7;71094:18;;;;;;;;;;;;;;;;71087:25;;71002:118;;;:::o;63351:103::-;62562:13;:11;:13::i;:::-;63416:30:::1;63443:1;63416:18;:30::i;:::-;63351:103::o:0;81333:145::-;81424:7;81451:19;81464:5;81451:12;:19::i;:::-;81444:26;;81333:145;;;:::o;39863:580::-;39966:13;39994:18;40027:21;40063:15;40093:25;40133:12;40160:27;40268:13;:11;:13::i;:::-;40296:16;:14;:16::i;:::-;40327:13;40363:4;40391:1;40383:10;;40422:1;40408:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40215:220;;;;;;;;;;;;;;;;;;;;;39863:580;;;;;;;:::o;83503:155::-;83569:4;83635:15;83593:14;:27;83608:11;83593:27;;;;;;;;;;;;;;;:39;;;:57;83586:64;;83503:155;;;:::o;82650:195::-;62562:13;:11;:13::i;:::-;82751:1:::1;82732:21;;:7;:21;;::::0;82724:75:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;82832:5;82810:10;:19;82821:7;82810:19;;;;;;;;;;;;;;;;:27;;;;;;;;;;;;;;;;;;82650:195:::0;:::o;62676:87::-;62722:7;62749:6;;;;;;;;;;;62742:13;;62676:87;:::o;69948:95::-;69995:13;70028:7;70021:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;69948:95;:::o;83668:638::-;83746:4;83772:27;83786:12;:10;:12::i;:::-;83772:13;:27::i;:::-;83771:28;83763:81;;;;;;;;;;;;:::i;:::-;;;;;;;;;83864:24;83878:9;83864:13;:24::i;:::-;83863:25;83855:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;83951:25;83966:9;83951:14;:25::i;:::-;83950:26;83942:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;84034:17;;;;;;;;;;;84033:18;:77;;;;84056:25;84070:10;84056:13;:25::i;:::-;:53;;;;;84085:24;84099:9;84085:13;:24::i;:::-;84056:53;84033:77;84025:139;;;;;;;;;;;;:::i;:::-;;;;;;;;;84184:25;84199:9;84184:14;:25::i;:::-;84183:26;84175:72;;;;;;;;;;;;:::i;:::-;;;;;;;;;84265:33;84280:9;84291:6;84265:14;:33::i;:::-;84258:40;;83668:638;;;;:::o;83330:165::-;62562:13;:11;:13::i;:::-;83453:34:::1;;;;;;;;83462:11;83453:34;;;;;;83475:11;83453:34;;::::0;83423:14:::1;:27;83438:11;83423:27;;;;;;;;;;;;;;;:64;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;83330:165:::0;;:::o;80579:695::-;80809:8;80791:15;:26;80787:99;;;80865:8;80841:33;;;;;;;;;;;:::i;:::-;;;;;;;;80787:99;80898:18;79899:95;80957:5;80964:7;80973:5;80980:16;80990:5;80980:9;:16::i;:::-;80998:8;80929:78;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;80919:89;;;;;;80898:110;;81021:12;81036:28;81053:10;81036:16;:28::i;:::-;81021:43;;81077:14;81094:28;81108:4;81114:1;81117;81120;81094:13;:28::i;:::-;81077:45;;81147:5;81137:15;;:6;:15;;;81133:90;;81197:6;81205:5;81176:35;;;;;;;;;;;;:::i;:::-;;;;;;;;81133:90;81235:31;81244:5;81251:7;81260:5;81235:8;:31::i;:::-;80776:498;;;80579:695;;;;;;;:::o;71570:142::-;71650:7;71677:11;:18;71689:5;71677:18;;;;;;;;;;;;;;;:27;71696:7;71677:27;;;;;;;;;;;;;;;;71670:34;;71570:142;;;;:::o;82458:184::-;62562:13;:11;:13::i;:::-;82554:1:::1;82535:21;;:7;:21;;::::0;82527:70:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;82630:4;82608:10;:19;82619:7;82608:19;;;;;;;;;;;;;;;;:26;;;;;;;;;;;;;;;;;;82458:184:::0;:::o;63609:220::-;62562:13;:11;:13::i;:::-;63714:1:::1;63694:22;;:8;:22;;::::0;63690:93:::1;;63768:1;63740:31;;;;;;;;;;;:::i;:::-;;;;;;;;63690:93;63793:28;63812:8;63793:18;:28::i;:::-;63609:220:::0;:::o;83204:112::-;83265:4;83289:10;:19;83300:7;83289:19;;;;;;;;;;;;;;;;;;;;;;;;;83282:26;;83204:112;;;:::o;62841:166::-;62912:12;:10;:12::i;:::-;62901:23;;:7;:5;:7::i;:::-;:23;;;62897:103;;62975:12;:10;:12::i;:::-;62948:40;;;;;;;;;;;:::i;:::-;;;;;;;;62897:103;62841:166::o;60685:98::-;60738:7;60765:10;60758:17;;60685:98;:::o;72031:190::-;72104:4;72121:13;72137:12;:10;:12::i;:::-;72121:28;;72160:31;72169:5;72176:7;72185:5;72160:8;:31::i;:::-;72209:4;72202:11;;;72031:190;;;;:::o;72799:249::-;72886:4;72903:15;72921:12;:10;:12::i;:::-;72903:30;;72944:37;72960:4;72966:7;72975:5;72944:15;:37::i;:::-;72992:26;73002:4;73008:2;73012:5;72992:9;:26::i;:::-;73036:4;73029:11;;;72799:249;;;;;:::o;38530:268::-;38583:7;38624:11;38607:28;;38615:4;38607:28;;;:63;;;;;38656:14;38639:13;:31;38607:63;38603:188;;;38694:22;38687:29;;;;38603:188;38756:23;:21;:23::i;:::-;38749:30;;38530:268;;:::o;63989:191::-;64063:16;64082:6;;;;;;;;;;;64063:25;;64108:8;64099:6;;:17;;;;;;;;;;;;;;;;;;64163:8;64132:40;;64153:8;64132:40;;;;;;;;;;;;64052:128;63989:191;:::o;578:109::-;638:7;665;:14;673:5;665:14;;;;;;;;;;;;;;;;658:21;;578:109;;;:::o;40772:128::-;40818:13;40851:41;40878:13;40851:5;:26;;:41;;;;:::i;:::-;40844:48;;40772:128;:::o;41235:137::-;41284:13;41317:47;41347:16;41317:8;:29;;:47;;;;:::i;:::-;41310:54;;41235:137;:::o;71325:182::-;71394:4;71411:13;71427:12;:10;:12::i;:::-;71411:28;;71450:27;71460:5;71467:2;71471:5;71450:9;:27::i;:::-;71495:4;71488:11;;;71325:182;;;;:::o;808:402::-;868:7;1175;:14;1183:5;1175:14;;;;;;;;;;;;;;;;:16;;;;;;;;;;;;1168:23;;808:402;;;:::o;39629:178::-;39706:7;39733:66;39766:20;:18;:20::i;:::-;39788:10;39733:32;:66::i;:::-;39726:73;;39629:178;;;:::o;48369:264::-;48454:7;48475:17;48494:18;48514:16;48534:25;48545:4;48551:1;48554;48557;48534:10;:25::i;:::-;48474:85;;;;;;48570:28;48582:5;48589:8;48570:11;:28::i;:::-;48616:9;48609:16;;;;;48369:264;;;;;;:::o;76858:130::-;76943:37;76952:5;76959:7;76968:5;76975:4;76943:8;:37::i;:::-;76858:130;;;:::o;78574:487::-;78674:24;78701:25;78711:5;78718:7;78701:9;:25::i;:::-;78674:52;;78761:17;78741:16;:37;78737:317;;78818:5;78799:16;:24;78795:132;;;78878:7;78887:16;78905:5;78851:60;;;;;;;;;;;;;:::i;:::-;;;;;;;;78795:132;78970:57;78979:5;78986:7;79014:5;78995:16;:24;79021:5;78970:8;:57::i;:::-;78737:317;78663:398;78574:487;;;:::o;73433:308::-;73533:1;73517:18;;:4;:18;;;73513:88;;73586:1;73559:30;;;;;;;;;;;:::i;:::-;;;;;;;;73513:88;73629:1;73615:16;;:2;:16;;;73611:88;;73684:1;73655:32;;;;;;;;;;;:::i;:::-;;;;;;;;73611:88;73709:24;73717:4;73723:2;73727:5;73709:7;:24::i;:::-;73433:308;;;:::o;38806:181::-;38861:7;36722:95;38920:11;38933:14;38949:13;38972:4;38898:80;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;38888:91;;;;;;38881:98;;38806:181;:::o;9918:273::-;10012:13;7864:66;10071:17;;10061:5;10042:46;10038:146;;10112:15;10121:5;10112:8;:15::i;:::-;10105:22;;;;10038:146;10167:5;10160:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;9918:273;;;;;:::o;34329:410::-;34422:14;34534:4;34528:11;34565:10;34560:3;34553:23;34613:15;34606:4;34601:3;34597:14;34590:39;34666:10;34659:4;34654:3;34650:14;34643:34;34716:4;34711:3;34701:20;34691:30;;34502:230;34329:410;;;;:::o;46674:1556::-;46805:7;46814:12;46828:7;47748:66;47743:1;47735:10;;:79;47731:166;;;47847:1;47851:30;47883:1;47831:54;;;;;;;;47731:166;47994:14;48011:24;48021:4;48027:1;48030;48033;48011:24;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47994:41;;48068:1;48050:20;;:6;:20;;;48046:115;;48103:1;48107:29;48146:1;48138:10;;48087:62;;;;;;;;;48046:115;48181:6;48189:20;48219:1;48211:10;;48173:49;;;;;;;46674:1556;;;;;;;;;:::o;48771:542::-;48867:20;48858:29;;;;;;;;:::i;:::-;;:5;:29;;;;;;;;:::i;:::-;;;48854:452;48904:7;48854:452;48965:29;48956:38;;;;;;;;:::i;:::-;;:5;:38;;;;;;;;:::i;:::-;;;48952:354;;49018:23;;;;;;;;;;;;;;48952:354;49072:35;49063:44;;;;;;;;:::i;:::-;;:5;:44;;;;;;;;:::i;:::-;;;49059:247;;49167:8;49159:17;;49131:46;;;;;;;;;;;:::i;:::-;;;;;;;;49059:247;49208:30;49199:39;;;;;;;;:::i;:::-;;:5;:39;;;;;;;;:::i;:::-;;;49195:111;;49285:8;49262:32;;;;;;;;;;;:::i;:::-;;;;;;;;49195:111;48771:542;;;:::o;77839:443::-;77969:1;77952:19;;:5;:19;;;77948:91;;78024:1;77995:32;;;;;;;;;;;:::i;:::-;;;;;;;;77948:91;78072:1;78053:21;;:7;:21;;;78049:92;;78126:1;78098:31;;;;;;;;;;;:::i;:::-;;;;;;;;78049:92;78181:5;78151:11;:18;78163:5;78151:18;;;;;;;;;;;;;;;:27;78170:7;78151:27;;;;;;;;;;;;;;;:35;;;;78201:9;78197:78;;;78248:7;78232:31;;78241:5;78232:31;;;78257:5;78232:31;;;;;;:::i;:::-;;;;;;;;78197:78;77839:443;;;;:::o;74065:1135::-;74171:1;74155:18;;:4;:18;;;74151:552;;74309:5;74293:12;;:21;;;;;;;:::i;:::-;;;;;;;;74151:552;;;74347:19;74369:9;:15;74379:4;74369:15;;;;;;;;;;;;;;;;74347:37;;74417:5;74403:11;:19;74399:117;;;74475:4;74481:11;74494:5;74450:50;;;;;;;;;;;;;:::i;:::-;;;;;;;;74399:117;74671:5;74657:11;:19;74639:9;:15;74649:4;74639:15;;;;;;;;;;;;;;;:37;;;;74332:371;74151:552;74733:1;74719:16;;:2;:16;;;74715:435;;74901:5;74885:12;;:21;;;;;;;;;;;74715:435;;;75118:5;75101:9;:13;75111:2;75101:13;;;;;;;;;;;;;;;;:22;;;;;;;;;;;74715:435;75182:2;75167:25;;75176:4;75167:25;;;75186:5;75167:25;;;;;;:::i;:::-;;;;;;;;74065:1135;;;:::o;8573:415::-;8632:13;8658:11;8672:16;8683:4;8672:10;:16::i;:::-;8658:30;;8778:17;8809:2;8798:14;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;8778:34;;8903:3;8898;8891:16;8944:4;8937;8932:3;8928:14;8921:28;8977:3;8970:10;;;;8573:415;;;:::o;9065:251::-;9126:7;9146:14;9199:4;9190;9163:33;;:40;9146:57;;9227:2;9218:6;:11;9214:71;;;9253:20;;;;;;;;;;;;;;9214:71;9302:6;9295:13;;;9065:251;;;:::o;88:117:1:-;197:1;194;187:12;334:90;368:7;411:5;404:13;397:21;386:32;;334:90;;;:::o;430:116::-;500:21;515:5;500:21;:::i;:::-;493:5;490:32;480:60;;536:1;533;526:12;480:60;430:116;:::o;552:133::-;595:5;633:6;620:20;611:29;;649:30;673:5;649:30;:::i;:::-;552:133;;;;:::o;691:323::-;747:6;796:2;784:9;775:7;771:23;767:32;764:119;;;802:79;;:::i;:::-;764:119;922:1;947:50;989:7;980:6;969:9;965:22;947:50;:::i;:::-;937:60;;893:114;691:323;;;;:::o;1020:99::-;1072:6;1106:5;1100:12;1090:22;;1020:99;;;:::o;1125:169::-;1209:11;1243:6;1238:3;1231:19;1283:4;1278:3;1274:14;1259:29;;1125:169;;;;:::o;1300:246::-;1381:1;1391:113;1405:6;1402:1;1399:13;1391:113;;;1490:1;1485:3;1481:11;1475:18;1471:1;1466:3;1462:11;1455:39;1427:2;1424:1;1420:10;1415:15;;1391:113;;;1538:1;1529:6;1524:3;1520:16;1513:27;1362:184;1300:246;;;:::o;1552:102::-;1593:6;1644:2;1640:7;1635:2;1628:5;1624:14;1620:28;1610:38;;1552:102;;;:::o;1660:377::-;1748:3;1776:39;1809:5;1776:39;:::i;:::-;1831:71;1895:6;1890:3;1831:71;:::i;:::-;1824:78;;1911:65;1969:6;1964:3;1957:4;1950:5;1946:16;1911:65;:::i;:::-;2001:29;2023:6;2001:29;:::i;:::-;1996:3;1992:39;1985:46;;1752:285;1660:377;;;;:::o;2043:313::-;2156:4;2194:2;2183:9;2179:18;2171:26;;2243:9;2237:4;2233:20;2229:1;2218:9;2214:17;2207:47;2271:78;2344:4;2335:6;2271:78;:::i;:::-;2263:86;;2043:313;;;;:::o;2362:126::-;2399:7;2439:42;2432:5;2428:54;2417:65;;2362:126;;;:::o;2494:96::-;2531:7;2560:24;2578:5;2560:24;:::i;:::-;2549:35;;2494:96;;;:::o;2596:122::-;2669:24;2687:5;2669:24;:::i;:::-;2662:5;2659:35;2649:63;;2708:1;2705;2698:12;2649:63;2596:122;:::o;2724:139::-;2770:5;2808:6;2795:20;2786:29;;2824:33;2851:5;2824:33;:::i;:::-;2724:139;;;;:::o;2869:77::-;2906:7;2935:5;2924:16;;2869:77;;;:::o;2952:122::-;3025:24;3043:5;3025:24;:::i;:::-;3018:5;3015:35;3005:63;;3064:1;3061;3054:12;3005:63;2952:122;:::o;3080:139::-;3126:5;3164:6;3151:20;3142:29;;3180:33;3207:5;3180:33;:::i;:::-;3080:139;;;;:::o;3225:474::-;3293:6;3301;3350:2;3338:9;3329:7;3325:23;3321:32;3318:119;;;3356:79;;:::i;:::-;3318:119;3476:1;3501:53;3546:7;3537:6;3526:9;3522:22;3501:53;:::i;:::-;3491:63;;3447:117;3603:2;3629:53;3674:7;3665:6;3654:9;3650:22;3629:53;:::i;:::-;3619:63;;3574:118;3225:474;;;;;:::o;3705:109::-;3786:21;3801:5;3786:21;:::i;:::-;3781:3;3774:34;3705:109;;:::o;3820:210::-;3907:4;3945:2;3934:9;3930:18;3922:26;;3958:65;4020:1;4009:9;4005:17;3996:6;3958:65;:::i;:::-;3820:210;;;;:::o;4036:118::-;4123:24;4141:5;4123:24;:::i;:::-;4118:3;4111:37;4036:118;;:::o;4160:222::-;4253:4;4291:2;4280:9;4276:18;4268:26;;4304:71;4372:1;4361:9;4357:17;4348:6;4304:71;:::i;:::-;4160:222;;;;:::o;4388:619::-;4465:6;4473;4481;4530:2;4518:9;4509:7;4505:23;4501:32;4498:119;;;4536:79;;:::i;:::-;4498:119;4656:1;4681:53;4726:7;4717:6;4706:9;4702:22;4681:53;:::i;:::-;4671:63;;4627:117;4783:2;4809:53;4854:7;4845:6;4834:9;4830:22;4809:53;:::i;:::-;4799:63;;4754:118;4911:2;4937:53;4982:7;4973:6;4962:9;4958:22;4937:53;:::i;:::-;4927:63;;4882:118;4388:619;;;;;:::o;5013:86::-;5048:7;5088:4;5081:5;5077:16;5066:27;;5013:86;;;:::o;5105:112::-;5188:22;5204:5;5188:22;:::i;:::-;5183:3;5176:35;5105:112;;:::o;5223:214::-;5312:4;5350:2;5339:9;5335:18;5327:26;;5363:67;5427:1;5416:9;5412:17;5403:6;5363:67;:::i;:::-;5223:214;;;;:::o;5443:77::-;5480:7;5509:5;5498:16;;5443:77;;;:::o;5526:118::-;5613:24;5631:5;5613:24;:::i;:::-;5608:3;5601:37;5526:118;;:::o;5650:222::-;5743:4;5781:2;5770:9;5766:18;5758:26;;5794:71;5862:1;5851:9;5847:17;5838:6;5794:71;:::i;:::-;5650:222;;;;:::o;5878:329::-;5937:6;5986:2;5974:9;5965:7;5961:23;5957:32;5954:119;;;5992:79;;:::i;:::-;5954:119;6112:1;6137:53;6182:7;6173:6;6162:9;6158:22;6137:53;:::i;:::-;6127:63;;6083:117;5878:329;;;;:::o;6213:149::-;6249:7;6289:66;6282:5;6278:78;6267:89;;6213:149;;;:::o;6368:115::-;6453:23;6470:5;6453:23;:::i;:::-;6448:3;6441:36;6368:115;;:::o;6489:118::-;6576:24;6594:5;6576:24;:::i;:::-;6571:3;6564:37;6489:118;;:::o;6613:114::-;6680:6;6714:5;6708:12;6698:22;;6613:114;;;:::o;6733:184::-;6832:11;6866:6;6861:3;6854:19;6906:4;6901:3;6897:14;6882:29;;6733:184;;;;:::o;6923:132::-;6990:4;7013:3;7005:11;;7043:4;7038:3;7034:14;7026:22;;6923:132;;;:::o;7061:108::-;7138:24;7156:5;7138:24;:::i;:::-;7133:3;7126:37;7061:108;;:::o;7175:179::-;7244:10;7265:46;7307:3;7299:6;7265:46;:::i;:::-;7343:4;7338:3;7334:14;7320:28;;7175:179;;;;:::o;7360:113::-;7430:4;7462;7457:3;7453:14;7445:22;;7360:113;;;:::o;7509:732::-;7628:3;7657:54;7705:5;7657:54;:::i;:::-;7727:86;7806:6;7801:3;7727:86;:::i;:::-;7720:93;;7837:56;7887:5;7837:56;:::i;:::-;7916:7;7947:1;7932:284;7957:6;7954:1;7951:13;7932:284;;;8033:6;8027:13;8060:63;8119:3;8104:13;8060:63;:::i;:::-;8053:70;;8146:60;8199:6;8146:60;:::i;:::-;8136:70;;7992:224;7979:1;7976;7972:9;7967:14;;7932:284;;;7936:14;8232:3;8225:10;;7633:608;;;7509:732;;;;:::o;8247:1215::-;8596:4;8634:3;8623:9;8619:19;8611:27;;8648:69;8714:1;8703:9;8699:17;8690:6;8648:69;:::i;:::-;8764:9;8758:4;8754:20;8749:2;8738:9;8734:18;8727:48;8792:78;8865:4;8856:6;8792:78;:::i;:::-;8784:86;;8917:9;8911:4;8907:20;8902:2;8891:9;8887:18;8880:48;8945:78;9018:4;9009:6;8945:78;:::i;:::-;8937:86;;9033:72;9101:2;9090:9;9086:18;9077:6;9033:72;:::i;:::-;9115:73;9183:3;9172:9;9168:19;9159:6;9115:73;:::i;:::-;9198;9266:3;9255:9;9251:19;9242:6;9198:73;:::i;:::-;9319:9;9313:4;9309:20;9303:3;9292:9;9288:19;9281:49;9347:108;9450:4;9441:6;9347:108;:::i;:::-;9339:116;;8247:1215;;;;;;;;;;:::o;9468:222::-;9561:4;9599:2;9588:9;9584:18;9576:26;;9612:71;9680:1;9669:9;9665:17;9656:6;9612:71;:::i;:::-;9468:222;;;;:::o;9696:118::-;9767:22;9783:5;9767:22;:::i;:::-;9760:5;9757:33;9747:61;;9804:1;9801;9794:12;9747:61;9696:118;:::o;9820:135::-;9864:5;9902:6;9889:20;9880:29;;9918:31;9943:5;9918:31;:::i;:::-;9820:135;;;;:::o;9961:122::-;10034:24;10052:5;10034:24;:::i;:::-;10027:5;10024:35;10014:63;;10073:1;10070;10063:12;10014:63;9961:122;:::o;10089:139::-;10135:5;10173:6;10160:20;10151:29;;10189:33;10216:5;10189:33;:::i;:::-;10089:139;;;;:::o;10234:1199::-;10345:6;10353;10361;10369;10377;10385;10393;10442:3;10430:9;10421:7;10417:23;10413:33;10410:120;;;10449:79;;:::i;:::-;10410:120;10569:1;10594:53;10639:7;10630:6;10619:9;10615:22;10594:53;:::i;:::-;10584:63;;10540:117;10696:2;10722:53;10767:7;10758:6;10747:9;10743:22;10722:53;:::i;:::-;10712:63;;10667:118;10824:2;10850:53;10895:7;10886:6;10875:9;10871:22;10850:53;:::i;:::-;10840:63;;10795:118;10952:2;10978:53;11023:7;11014:6;11003:9;10999:22;10978:53;:::i;:::-;10968:63;;10923:118;11080:3;11107:51;11150:7;11141:6;11130:9;11126:22;11107:51;:::i;:::-;11097:61;;11051:117;11207:3;11234:53;11279:7;11270:6;11259:9;11255:22;11234:53;:::i;:::-;11224:63;;11178:119;11336:3;11363:53;11408:7;11399:6;11388:9;11384:22;11363:53;:::i;:::-;11353:63;;11307:119;10234:1199;;;;;;;;;;:::o;11439:474::-;11507:6;11515;11564:2;11552:9;11543:7;11539:23;11535:32;11532:119;;;11570:79;;:::i;:::-;11532:119;11690:1;11715:53;11760:7;11751:6;11740:9;11736:22;11715:53;:::i;:::-;11705:63;;11661:117;11817:2;11843:53;11888:7;11879:6;11868:9;11864:22;11843:53;:::i;:::-;11833:63;;11788:118;11439:474;;;;;:::o;11919:180::-;11967:77;11964:1;11957:88;12064:4;12061:1;12054:15;12088:4;12085:1;12078:15;12105:320;12149:6;12186:1;12180:4;12176:12;12166:22;;12233:1;12227:4;12223:12;12254:18;12244:81;;12310:4;12302:6;12298:17;12288:27;;12244:81;12372:2;12364:6;12361:14;12341:18;12338:38;12335:84;;12391:18;;:::i;:::-;12335:84;12156:269;12105:320;;;:::o;12431:226::-;12571:34;12567:1;12559:6;12555:14;12548:58;12640:9;12635:2;12627:6;12623:15;12616:34;12431:226;:::o;12663:366::-;12805:3;12826:67;12890:2;12885:3;12826:67;:::i;:::-;12819:74;;12902:93;12991:3;12902:93;:::i;:::-;13020:2;13015:3;13011:12;13004:19;;12663:366;;;:::o;13035:419::-;13201:4;13239:2;13228:9;13224:18;13216:26;;13288:9;13282:4;13278:20;13274:1;13263:9;13259:17;13252:47;13316:131;13442:4;13316:131;:::i;:::-;13308:139;;13035:419;;;:::o;13460:224::-;13600:34;13596:1;13588:6;13584:14;13577:58;13669:7;13664:2;13656:6;13652:15;13645:32;13460:224;:::o;13690:366::-;13832:3;13853:67;13917:2;13912:3;13853:67;:::i;:::-;13846:74;;13929:93;14018:3;13929:93;:::i;:::-;14047:2;14042:3;14038:12;14031:19;;13690:366;;;:::o;14062:419::-;14228:4;14266:2;14255:9;14251:18;14243:26;;14315:9;14309:4;14305:20;14301:1;14290:9;14286:17;14279:47;14343:131;14469:4;14343:131;:::i;:::-;14335:139;;14062:419;;;:::o;14487:227::-;14627:34;14623:1;14615:6;14611:14;14604:58;14696:10;14691:2;14683:6;14679:15;14672:35;14487:227;:::o;14720:366::-;14862:3;14883:67;14947:2;14942:3;14883:67;:::i;:::-;14876:74;;14959:93;15048:3;14959:93;:::i;:::-;15077:2;15072:3;15068:12;15061:19;;14720:366;;;:::o;15092:419::-;15258:4;15296:2;15285:9;15281:18;15273:26;;15345:9;15339:4;15335:20;15331:1;15320:9;15316:17;15309:47;15373:131;15499:4;15373:131;:::i;:::-;15365:139;;15092:419;;;:::o;15517:225::-;15657:34;15653:1;15645:6;15641:14;15634:58;15726:8;15721:2;15713:6;15709:15;15702:33;15517:225;:::o;15748:366::-;15890:3;15911:67;15975:2;15970:3;15911:67;:::i;:::-;15904:74;;15987:93;16076:3;15987:93;:::i;:::-;16105:2;16100:3;16096:12;16089:19;;15748:366;;;:::o;16120:419::-;16286:4;16324:2;16313:9;16309:18;16301:26;;16373:9;16367:4;16363:20;16359:1;16348:9;16344:17;16337:47;16401:131;16527:4;16401:131;:::i;:::-;16393:139;;16120:419;;;:::o;16545:220::-;16685:34;16681:1;16673:6;16669:14;16662:58;16754:3;16749:2;16741:6;16737:15;16730:28;16545:220;:::o;16771:366::-;16913:3;16934:67;16998:2;16993:3;16934:67;:::i;:::-;16927:74;;17010:93;17099:3;17010:93;:::i;:::-;17128:2;17123:3;17119:12;17112:19;;16771:366;;;:::o;17143:419::-;17309:4;17347:2;17336:9;17332:18;17324:26;;17396:9;17390:4;17386:20;17382:1;17371:9;17367:17;17360:47;17424:131;17550:4;17424:131;:::i;:::-;17416:139;;17143:419;;;:::o;17568:293::-;17708:34;17704:1;17696:6;17692:14;17685:58;17777:34;17772:2;17764:6;17760:15;17753:59;17846:7;17841:2;17833:6;17829:15;17822:32;17568:293;:::o;17867:366::-;18009:3;18030:67;18094:2;18089:3;18030:67;:::i;:::-;18023:74;;18106:93;18195:3;18106:93;:::i;:::-;18224:2;18219:3;18215:12;18208:19;;17867:366;;;:::o;18239:419::-;18405:4;18443:2;18432:9;18428:18;18420:26;;18492:9;18486:4;18482:20;18478:1;18467:9;18463:17;18456:47;18520:131;18646:4;18520:131;:::i;:::-;18512:139;;18239:419;;;:::o;18664:180::-;18712:77;18709:1;18702:88;18809:4;18806:1;18799:15;18833:4;18830:1;18823:15;18850:228;18990:34;18986:1;18978:6;18974:14;18967:58;19059:11;19054:2;19046:6;19042:15;19035:36;18850:228;:::o;19084:366::-;19226:3;19247:67;19311:2;19306:3;19247:67;:::i;:::-;19240:74;;19323:93;19412:3;19323:93;:::i;:::-;19441:2;19436:3;19432:12;19425:19;;19084:366;;;:::o;19456:419::-;19622:4;19660:2;19649:9;19645:18;19637:26;;19709:9;19703:4;19699:20;19695:1;19684:9;19680:17;19673:47;19737:131;19863:4;19737:131;:::i;:::-;19729:139;;19456:419;;;:::o;19881:236::-;20021:34;20017:1;20009:6;20005:14;19998:58;20090:19;20085:2;20077:6;20073:15;20066:44;19881:236;:::o;20123:366::-;20265:3;20286:67;20350:2;20345:3;20286:67;:::i;:::-;20279:74;;20362:93;20451:3;20362:93;:::i;:::-;20480:2;20475:3;20471:12;20464:19;;20123:366;;;:::o;20495:419::-;20661:4;20699:2;20688:9;20684:18;20676:26;;20748:9;20742:4;20738:20;20734:1;20723:9;20719:17;20712:47;20776:131;20902:4;20776:131;:::i;:::-;20768:139;;20495:419;;;:::o;20920:775::-;21153:4;21191:3;21180:9;21176:19;21168:27;;21205:71;21273:1;21262:9;21258:17;21249:6;21205:71;:::i;:::-;21286:72;21354:2;21343:9;21339:18;21330:6;21286:72;:::i;:::-;21368;21436:2;21425:9;21421:18;21412:6;21368:72;:::i;:::-;21450;21518:2;21507:9;21503:18;21494:6;21450:72;:::i;:::-;21532:73;21600:3;21589:9;21585:19;21576:6;21532:73;:::i;:::-;21615;21683:3;21672:9;21668:19;21659:6;21615:73;:::i;:::-;20920:775;;;;;;;;;:::o;21701:332::-;21822:4;21860:2;21849:9;21845:18;21837:26;;21873:71;21941:1;21930:9;21926:17;21917:6;21873:71;:::i;:::-;21954:72;22022:2;22011:9;22007:18;21998:6;21954:72;:::i;:::-;21701:332;;;;;:::o;22039:223::-;22179:34;22175:1;22167:6;22163:14;22156:58;22248:6;22243:2;22235:6;22231:15;22224:31;22039:223;:::o;22268:366::-;22410:3;22431:67;22495:2;22490:3;22431:67;:::i;:::-;22424:74;;22507:93;22596:3;22507:93;:::i;:::-;22625:2;22620:3;22616:12;22609:19;;22268:366;;;:::o;22640:419::-;22806:4;22844:2;22833:9;22829:18;22821:26;;22893:9;22887:4;22883:20;22879:1;22868:9;22864:17;22857:47;22921:131;23047:4;22921:131;:::i;:::-;22913:139;;22640:419;;;:::o;23065:442::-;23214:4;23252:2;23241:9;23237:18;23229:26;;23265:71;23333:1;23322:9;23318:17;23309:6;23265:71;:::i;:::-;23346:72;23414:2;23403:9;23399:18;23390:6;23346:72;:::i;:::-;23428;23496:2;23485:9;23481:18;23472:6;23428:72;:::i;:::-;23065:442;;;;;;:::o;23513:664::-;23718:4;23756:3;23745:9;23741:19;23733:27;;23770:71;23838:1;23827:9;23823:17;23814:6;23770:71;:::i;:::-;23851:72;23919:2;23908:9;23904:18;23895:6;23851:72;:::i;:::-;23933;24001:2;23990:9;23986:18;23977:6;23933:72;:::i;:::-;24015;24083:2;24072:9;24068:18;24059:6;24015:72;:::i;:::-;24097:73;24165:3;24154:9;24150:19;24141:6;24097:73;:::i;:::-;23513:664;;;;;;;;:::o;24183:545::-;24356:4;24394:3;24383:9;24379:19;24371:27;;24408:71;24476:1;24465:9;24461:17;24452:6;24408:71;:::i;:::-;24489:68;24553:2;24542:9;24538:18;24529:6;24489:68;:::i;:::-;24567:72;24635:2;24624:9;24620:18;24611:6;24567:72;:::i;:::-;24649;24717:2;24706:9;24702:18;24693:6;24649:72;:::i;:::-;24183:545;;;;;;;:::o;24734:180::-;24782:77;24779:1;24772:88;24879:4;24876:1;24869:15;24903:4;24900:1;24893:15;24920:180;24968:77;24965:1;24958:88;25065:4;25062:1;25055:15;25089:4;25086:1;25079:15;25106:191;25146:3;25165:20;25183:1;25165:20;:::i;:::-;25160:25;;25199:20;25217:1;25199:20;:::i;:::-;25194:25;;25242:1;25239;25235:9;25228:16;;25263:3;25260:1;25257:10;25254:36;;;25270:18;;:::i;:::-;25254:36;25106:191;;;;:::o

Swarm Source

ipfs://c98f202613ce3861c4e1621f7628e03334235184bd24635c68aaae31c27752b8
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.