ETH Price: $3,433.22 (+4.02%)

Token

ChillOrbs (CHILLORBS)
 

Overview

Max Total Supply

8,912 CHILLORBS

Holders

5,632

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
0xwl.eth
Balance
1 CHILLORBS
0x0c7ae85c963dbc7f1bba6e339aaf794bfc12014f
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:
ChillOrbs

Compiler Version
v0.8.18+commit.87f61d96

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2023-06-18
*/

// File: utils.sol


pragma solidity ^0.8.4;



library Utils {
    function substring(string memory str, uint startIndex, uint endIndex) internal pure returns (string memory) {
        bytes memory strBytes = bytes(str);
        bytes memory result = new bytes(endIndex-startIndex);
        for(uint i = startIndex; i < endIndex; i++) {
            result[i-startIndex] = strBytes[i];
        }
        return string(result);
    }

    function replaceInString(string memory sourceText, string memory search, string memory replacement) internal pure returns (string memory) {
        bytes memory sourceBytes = bytes(sourceText);
        bytes memory searchBytes = bytes(search);

        if (searchBytes.length > sourceBytes.length) {
            return sourceText;
        }

        // Searching for the given string
        bool found = false;
        uint256 position = 0;
        for (uint256 i = 0; i <= sourceBytes.length - searchBytes.length; i++) {
            bool flag = true;
            for (uint256 j = 0; j < searchBytes.length; j++)
                if (sourceBytes [i + j] != searchBytes [j]) {
                    flag = false;
                    break;
                }
            if (flag) {
                found = true;
                position = i;
                break;
            }
        }

        // Replace to the given replacement string
        if (found) {
            string memory firstHalf = substring(sourceText, 0, position);
            string memory secondHalf = substring(sourceText, position + searchBytes.length, sourceBytes.length);

            return string.concat(firstHalf, replacement, secondHalf);
        }
        
        return sourceText;
    }

    function uintToString(uint v) internal pure returns (string memory) {
        if (v == 0) return "0";
        uint maxlength = 100;
        bytes memory reversed = new bytes(maxlength);
        uint i = 0;
        while (v != 0) {
            uint remainder = v % 10;
            v = v / 10;
            reversed[i++] = bytes1(uint8(48 + remainder));
        }
        bytes memory s = new bytes(i); // i + 1 is inefficient
        for (uint j = 0; j < i; j++) {
            s[j] = reversed[i - j - 1]; // to avoid the off-by-one error
        }
        string memory str = string(s);  // memory isn't implicitly convertible to storage
        return str;
    }
}
// File: @openzeppelin/contracts/utils/Base64.sol


// OpenZeppelin Contracts (last updated v4.7.0) (utils/Base64.sol)

pragma solidity ^0.8.0;

/**
 * @dev Provides a set of functions to operate with Base64 strings.
 *
 * _Available since v4.5._
 */
library Base64 {
    /**
     * @dev Base64 Encoding/Decoding Table
     */
    string internal constant _TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    /**
     * @dev Converts a `bytes` to its Bytes64 `string` representation.
     */
    function encode(bytes memory data) internal pure returns (string memory) {
        /**
         * Inspired by Brecht Devos (Brechtpd) implementation - MIT licence
         * https://github.com/Brechtpd/base64/blob/e78d9fd951e7b0977ddca77d92dc85183770daf4/base64.sol
         */
        if (data.length == 0) return "";

        // Loads the table into memory
        string memory table = _TABLE;

        // Encoding takes 3 bytes chunks of binary data from `bytes` data parameter
        // and split into 4 numbers of 6 bits.
        // The final Base64 length should be `bytes` data length multiplied by 4/3 rounded up
        // - `data.length + 2`  -> Round up
        // - `/ 3`              -> Number of 3-bytes chunks
        // - `4 *`              -> 4 characters for each chunk
        string memory result = new string(4 * ((data.length + 2) / 3));

        /// @solidity memory-safe-assembly
        assembly {
            // Prepare the lookup table (skip the first "length" byte)
            let tablePtr := add(table, 1)

            // Prepare result pointer, jump over length
            let resultPtr := add(result, 32)

            // Run over the input, 3 bytes at a time
            for {
                let dataPtr := data
                let endPtr := add(data, mload(data))
            } lt(dataPtr, endPtr) {

            } {
                // Advance 3 bytes
                dataPtr := add(dataPtr, 3)
                let input := mload(dataPtr)

                // To write each character, shift the 3 bytes (18 bits) chunk
                // 4 times in blocks of 6 bits for each character (18, 12, 6, 0)
                // and apply logical AND with 0x3F which is the number of
                // the previous character in the ASCII table prior to the Base64 Table
                // The result is then added to the table to get the character to write,
                // and finally write it in the result pointer but with a left shift
                // of 256 (1 byte) - 8 (1 ASCII char) = 248 bits

                mstore8(resultPtr, mload(add(tablePtr, and(shr(18, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(shr(12, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(shr(6, input), 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance

                mstore8(resultPtr, mload(add(tablePtr, and(input, 0x3F))))
                resultPtr := add(resultPtr, 1) // Advance
            }

            // When data `bytes` is not exactly 3 bytes long
            // it is padded with `=` characters at the end
            switch mod(mload(data), 3)
            case 1 {
                mstore8(sub(resultPtr, 1), 0x3d)
                mstore8(sub(resultPtr, 2), 0x3d)
            }
            case 2 {
                mstore8(sub(resultPtr, 1), 0x3d)
            }
        }

        return result;
    }
}

// File: operator-filter-registry/src/lib/Constants.sol


pragma solidity ^0.8.13;

address constant CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS = 0x000000000000AAeB6D7670E522A718067333cd4E;
address constant CANONICAL_CORI_SUBSCRIPTION = 0x3cc6CddA760b79bAfa08dF41ECFA224f810dCeB6;

// File: operator-filter-registry/src/IOperatorFilterRegistry.sol


pragma solidity ^0.8.13;

interface IOperatorFilterRegistry {
    /**
     * @notice Returns true if operator is not filtered for a given token, either by address or codeHash. Also returns
     *         true if supplied registrant address is not registered.
     */
    function isOperatorAllowed(address registrant, address operator) external view returns (bool);

    /**
     * @notice Registers an address with the registry. May be called by address itself or by EIP-173 owner.
     */
    function register(address registrant) external;

    /**
     * @notice Registers an address with the registry and "subscribes" to another address's filtered operators and codeHashes.
     */
    function registerAndSubscribe(address registrant, address subscription) external;

    /**
     * @notice Registers an address with the registry and copies the filtered operators and codeHashes from another
     *         address without subscribing.
     */
    function registerAndCopyEntries(address registrant, address registrantToCopy) external;

    /**
     * @notice Unregisters an address with the registry and removes its subscription. May be called by address itself or by EIP-173 owner.
     *         Note that this does not remove any filtered addresses or codeHashes.
     *         Also note that any subscriptions to this registrant will still be active and follow the existing filtered addresses and codehashes.
     */
    function unregister(address addr) external;

    /**
     * @notice Update an operator address for a registered address - when filtered is true, the operator is filtered.
     */
    function updateOperator(address registrant, address operator, bool filtered) external;

    /**
     * @notice Update multiple operators for a registered address - when filtered is true, the operators will be filtered. Reverts on duplicates.
     */
    function updateOperators(address registrant, address[] calldata operators, bool filtered) external;

    /**
     * @notice Update a codeHash for a registered address - when filtered is true, the codeHash is filtered.
     */
    function updateCodeHash(address registrant, bytes32 codehash, bool filtered) external;

    /**
     * @notice Update multiple codeHashes for a registered address - when filtered is true, the codeHashes will be filtered. Reverts on duplicates.
     */
    function updateCodeHashes(address registrant, bytes32[] calldata codeHashes, bool filtered) external;

    /**
     * @notice Subscribe an address to another registrant's filtered operators and codeHashes. Will remove previous
     *         subscription if present.
     *         Note that accounts with subscriptions may go on to subscribe to other accounts - in this case,
     *         subscriptions will not be forwarded. Instead the former subscription's existing entries will still be
     *         used.
     */
    function subscribe(address registrant, address registrantToSubscribe) external;

    /**
     * @notice Unsubscribe an address from its current subscribed registrant, and optionally copy its filtered operators and codeHashes.
     */
    function unsubscribe(address registrant, bool copyExistingEntries) external;

    /**
     * @notice Get the subscription address of a given registrant, if any.
     */
    function subscriptionOf(address addr) external returns (address registrant);

    /**
     * @notice Get the set of addresses subscribed to a given registrant.
     *         Note that order is not guaranteed as updates are made.
     */
    function subscribers(address registrant) external returns (address[] memory);

    /**
     * @notice Get the subscriber at a given index in the set of addresses subscribed to a given registrant.
     *         Note that order is not guaranteed as updates are made.
     */
    function subscriberAt(address registrant, uint256 index) external returns (address);

    /**
     * @notice Copy filtered operators and codeHashes from a different registrantToCopy to addr.
     */
    function copyEntriesOf(address registrant, address registrantToCopy) external;

    /**
     * @notice Returns true if operator is filtered by a given address or its subscription.
     */
    function isOperatorFiltered(address registrant, address operator) external returns (bool);

    /**
     * @notice Returns true if the hash of an address's code is filtered by a given address or its subscription.
     */
    function isCodeHashOfFiltered(address registrant, address operatorWithCode) external returns (bool);

    /**
     * @notice Returns true if a codeHash is filtered by a given address or its subscription.
     */
    function isCodeHashFiltered(address registrant, bytes32 codeHash) external returns (bool);

    /**
     * @notice Returns a list of filtered operators for a given address or its subscription.
     */
    function filteredOperators(address addr) external returns (address[] memory);

    /**
     * @notice Returns the set of filtered codeHashes for a given address or its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashes(address addr) external returns (bytes32[] memory);

    /**
     * @notice Returns the filtered operator at the given index of the set of filtered operators for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredOperatorAt(address registrant, uint256 index) external returns (address);

    /**
     * @notice Returns the filtered codeHash at the given index of the list of filtered codeHashes for a given address or
     *         its subscription.
     *         Note that order is not guaranteed as updates are made.
     */
    function filteredCodeHashAt(address registrant, uint256 index) external returns (bytes32);

    /**
     * @notice Returns true if an address has registered
     */
    function isRegistered(address addr) external returns (bool);

    /**
     * @dev Convenience method to compute the code hash of an arbitrary contract
     */
    function codeHashOf(address addr) external returns (bytes32);
}

// File: operator-filter-registry/src/OperatorFilterer.sol


pragma solidity ^0.8.13;


/**
 * @title  OperatorFilterer
 * @notice Abstract contract whose constructor automatically registers and optionally subscribes to or copies another
 *         registrant's entries in the OperatorFilterRegistry.
 * @dev    This smart contract is meant to be inherited by token contracts so they can use the following:
 *         - `onlyAllowedOperator` modifier for `transferFrom` and `safeTransferFrom` methods.
 *         - `onlyAllowedOperatorApproval` modifier for `approve` and `setApprovalForAll` methods.
 *         Please note that if your token contract does not provide an owner with EIP-173, it must provide
 *         administration methods on the contract itself to interact with the registry otherwise the subscription
 *         will be locked to the options set during construction.
 */

abstract contract OperatorFilterer {
    /// @dev Emitted when an operator is not allowed.
    error OperatorNotAllowed(address operator);

    IOperatorFilterRegistry public constant OPERATOR_FILTER_REGISTRY =
        IOperatorFilterRegistry(CANONICAL_OPERATOR_FILTER_REGISTRY_ADDRESS);

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

    /**
     * @dev A helper function to check if an operator is allowed.
     */
    modifier onlyAllowedOperator(address from) virtual {
        // Allow spending tokens from addresses with balance
        // Note that this still allows listings and marketplaces with escrow to transfer tokens if transferred
        // from an EOA.
        if (from != msg.sender) {
            _checkFilterOperator(msg.sender);
        }
        _;
    }

    /**
     * @dev A helper function to check if an operator approval is allowed.
     */
    modifier onlyAllowedOperatorApproval(address operator) virtual {
        _checkFilterOperator(operator);
        _;
    }

    /**
     * @dev A helper function to check if an operator is allowed.
     */
    function _checkFilterOperator(address operator) internal view virtual {
        // Check registry code length to facilitate testing in environments without a deployed registry.
        if (address(OPERATOR_FILTER_REGISTRY).code.length > 0) {
            // under normal circumstances, this function will revert rather than return false, but inheriting contracts
            // may specify their own OperatorFilterRegistry implementations, which may behave differently
            if (!OPERATOR_FILTER_REGISTRY.isOperatorAllowed(address(this), operator)) {
                revert OperatorNotAllowed(operator);
            }
        }
    }
}

// File: operator-filter-registry/src/DefaultOperatorFilterer.sol


pragma solidity ^0.8.13;


/**
 * @title  DefaultOperatorFilterer
 * @notice Inherits from OperatorFilterer and automatically subscribes to the default OpenSea subscription.
 * @dev    Please note that if your token contract does not provide an owner with EIP-173, it must provide
 *         administration methods on the contract itself to interact with the registry otherwise the subscription
 *         will be locked to the options set during construction.
 */

abstract contract DefaultOperatorFilterer is OperatorFilterer {
    /// @dev The constructor that is called when the contract is being deployed.
    constructor() OperatorFilterer(CANONICAL_CORI_SUBSCRIPTION, true) {}
}

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


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

pragma solidity ^0.8.0;

/**
 * @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 v4.9.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

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

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

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

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

    /**
     * @dev Returns the ceiling of the division of two numbers.
     *
     * This differs from standard division with `/` in that it rounds up instead
     * of rounding down.
     */
    function ceilDiv(uint256 a, uint256 b) internal pure returns (uint256) {
        // (a + b - 1) / b can overflow on addition, so we distribute.
        return a == 0 ? 0 : (a - 1) / b + 1;
    }

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

            // Handle non-overflow cases, 256 by 256 division.
            if (prod1 == 0) {
                // 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.
            require(denominator > prod1, "Math: mulDiv overflow");

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

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

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

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

            // Does not overflow because the denominator cannot be zero at this stage in the function.
            uint256 twos = denominator & (~denominator + 1);
            assembly {
                // Divide denominator by twos.
                denominator := div(denominator, twos)

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.0;



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

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

    /**
     * @dev Converts a `int256` to its ASCII `string` decimal representation.
     */
    function toString(int256 value) internal pure returns (string memory) {
        return string(abi.encodePacked(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) {
        bytes memory buffer = new bytes(2 * length + 2);
        buffer[0] = "0";
        buffer[1] = "x";
        for (uint256 i = 2 * length + 1; i > 1; --i) {
            buffer[i] = _SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }

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

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

// File: @openzeppelin/contracts/security/ReentrancyGuard.sol


// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

/**
 * @dev Contract module that helps prevent reentrant calls to a function.
 *
 * Inheriting from `ReentrancyGuard` will make the {nonReentrant} modifier
 * available, which can be applied to functions to make sure there are no nested
 * (reentrant) calls to them.
 *
 * Note that because there is a single `nonReentrant` guard, functions marked as
 * `nonReentrant` may not call one another. This can be worked around by making
 * those functions `private`, and then adding `external` `nonReentrant` entry
 * points to them.
 *
 * TIP: If you would like to learn more about reentrancy and alternative ways
 * to protect against it, check out our blog post
 * https://blog.openzeppelin.com/reentrancy-after-istanbul/[Reentrancy After Istanbul].
 */
abstract contract ReentrancyGuard {
    // Booleans are more expensive than uint256 or any type that takes up a full
    // word because each write operation emits an extra SLOAD to first read the
    // slot's contents, replace the bits taken up by the boolean, and then write
    // back. This is the compiler's defense against contract upgrades and
    // pointer aliasing, and it cannot be disabled.

    // The values being non-zero value makes deployment a bit more expensive,
    // but in exchange the refund on every call to nonReentrant will be lower in
    // amount. Since refunds are capped to a percentage of the total
    // transaction's gas, it is best to keep them low in cases like this one, to
    // increase the likelihood of the full refund coming into effect.
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and making it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        _nonReentrantBefore();
        _;
        _nonReentrantAfter();
    }

    function _nonReentrantBefore() private {
        // On the first call to nonReentrant, _status will be _NOT_ENTERED
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

        // Any calls to nonReentrant after this point will fail
        _status = _ENTERED;
    }

    function _nonReentrantAfter() private {
        // By storing the original value once again, a refund is triggered (see
        // https://eips.ethereum.org/EIPS/eip-2200)
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Returns true if the reentrancy guard is currently set to "entered", which indicates there is a
     * `nonReentrant` function in the call stack.
     */
    function _reentrancyGuardEntered() internal view returns (bool) {
        return _status == _ENTERED;
    }
}

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


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

pragma solidity ^0.8.0;

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

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

// File: @openzeppelin/contracts/security/Pausable.sol


// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)

pragma solidity ^0.8.0;


/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        _requireNotPaused();
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        _requirePaused();
        _;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Throws if the contract is paused.
     */
    function _requireNotPaused() internal view virtual {
        require(!paused(), "Pausable: paused");
    }

    /**
     * @dev Throws if the contract is not paused.
     */
    function _requirePaused() internal view virtual {
        require(paused(), "Pausable: not paused");
    }

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

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

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


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

pragma solidity ^0.8.0;


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

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

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

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

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

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

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions. 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 {
        require(newOwner != address(0), "Ownable: new owner is the zero address");
        _transferOwnership(newOwner);
    }

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

// File: erc721a/contracts/IERC721A.sol


// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;

/**
 * @dev Interface of ERC721A.
 */
interface IERC721A {
    /**
     * The caller must own the token or be an approved operator.
     */
    error ApprovalCallerNotOwnerNorApproved();

    /**
     * The token does not exist.
     */
    error ApprovalQueryForNonexistentToken();

    /**
     * Cannot query the balance for the zero address.
     */
    error BalanceQueryForZeroAddress();

    /**
     * Cannot mint to the zero address.
     */
    error MintToZeroAddress();

    /**
     * The quantity of tokens minted must be more than zero.
     */
    error MintZeroQuantity();

    /**
     * The token does not exist.
     */
    error OwnerQueryForNonexistentToken();

    /**
     * The caller must own the token or be an approved operator.
     */
    error TransferCallerNotOwnerNorApproved();

    /**
     * The token must be owned by `from`.
     */
    error TransferFromIncorrectOwner();

    /**
     * Cannot safely transfer to a contract that does not implement the
     * ERC721Receiver interface.
     */
    error TransferToNonERC721ReceiverImplementer();

    /**
     * Cannot transfer to the zero address.
     */
    error TransferToZeroAddress();

    /**
     * The token does not exist.
     */
    error URIQueryForNonexistentToken();

    /**
     * The `quantity` minted with ERC2309 exceeds the safety limit.
     */
    error MintERC2309QuantityExceedsLimit();

    /**
     * The `extraData` cannot be set on an unintialized ownership slot.
     */
    error OwnershipNotInitializedForExtraData();

    // =============================================================
    //                            STRUCTS
    // =============================================================

    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Stores the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
        // Arbitrary data similar to `startTimestamp` that can be set via {_extraData}.
        uint24 extraData;
    }

    // =============================================================
    //                         TOKEN COUNTERS
    // =============================================================

    /**
     * @dev Returns the total number of tokens in existence.
     * Burned tokens will reduce the count.
     * To get the total number of tokens minted, please see {_totalMinted}.
     */
    function totalSupply() external view returns (uint256);

    // =============================================================
    //                            IERC165
    // =============================================================

    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30000 gas.
     */
    function supportsInterface(bytes4 interfaceId) external view returns (bool);

    // =============================================================
    //                            IERC721
    // =============================================================

    /**
     * @dev Emitted when `tokenId` token is transferred from `from` to `to`.
     */
    event Transfer(address indexed from, address indexed to, uint256 indexed tokenId);

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

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

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

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

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

    /**
     * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external payable;

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {safeTransferFrom}
     * whenever possible.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token
     * by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) external payable;

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

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

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

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

    // =============================================================
    //                        IERC721Metadata
    // =============================================================

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

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

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

    // =============================================================
    //                           IERC2309
    // =============================================================

    /**
     * @dev Emitted when tokens in `fromTokenId` to `toTokenId`
     * (inclusive) is transferred from `from` to `to`, as defined in the
     * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309) standard.
     *
     * See {_mintERC2309} for more details.
     */
    event ConsecutiveTransfer(uint256 indexed fromTokenId, uint256 toTokenId, address indexed from, address indexed to);
}

// File: erc721a/contracts/ERC721A.sol


// ERC721A Contracts v4.2.3
// Creator: Chiru Labs

pragma solidity ^0.8.4;


/**
 * @dev Interface of ERC721 token receiver.
 */
interface ERC721A__IERC721Receiver {
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

/**
 * @title ERC721A
 *
 * @dev Implementation of the [ERC721](https://eips.ethereum.org/EIPS/eip-721)
 * Non-Fungible Token Standard, including the Metadata extension.
 * Optimized for lower gas during batch mints.
 *
 * Token IDs are minted in sequential order (e.g. 0, 1, 2, 3, ...)
 * starting from `_startTokenId()`.
 *
 * Assumptions:
 *
 * - An owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 * - The maximum token ID cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is IERC721A {
    // Bypass for a `--via-ir` bug (https://github.com/chiru-labs/ERC721A/pull/364).
    struct TokenApprovalRef {
        address value;
    }

    // =============================================================
    //                           CONSTANTS
    // =============================================================

    // Mask of an entry in packed address data.
    uint256 private constant _BITMASK_ADDRESS_DATA_ENTRY = (1 << 64) - 1;

    // The bit position of `numberMinted` in packed address data.
    uint256 private constant _BITPOS_NUMBER_MINTED = 64;

    // The bit position of `numberBurned` in packed address data.
    uint256 private constant _BITPOS_NUMBER_BURNED = 128;

    // The bit position of `aux` in packed address data.
    uint256 private constant _BITPOS_AUX = 192;

    // Mask of all 256 bits in packed address data except the 64 bits for `aux`.
    uint256 private constant _BITMASK_AUX_COMPLEMENT = (1 << 192) - 1;

    // The bit position of `startTimestamp` in packed ownership.
    uint256 private constant _BITPOS_START_TIMESTAMP = 160;

    // The bit mask of the `burned` bit in packed ownership.
    uint256 private constant _BITMASK_BURNED = 1 << 224;

    // The bit position of the `nextInitialized` bit in packed ownership.
    uint256 private constant _BITPOS_NEXT_INITIALIZED = 225;

    // The bit mask of the `nextInitialized` bit in packed ownership.
    uint256 private constant _BITMASK_NEXT_INITIALIZED = 1 << 225;

    // The bit position of `extraData` in packed ownership.
    uint256 private constant _BITPOS_EXTRA_DATA = 232;

    // Mask of all 256 bits in a packed ownership except the 24 bits for `extraData`.
    uint256 private constant _BITMASK_EXTRA_DATA_COMPLEMENT = (1 << 232) - 1;

    // The mask of the lower 160 bits for addresses.
    uint256 private constant _BITMASK_ADDRESS = (1 << 160) - 1;

    // The maximum `quantity` that can be minted with {_mintERC2309}.
    // This limit is to prevent overflows on the address data entries.
    // For a limit of 5000, a total of 3.689e15 calls to {_mintERC2309}
    // is required to cause an overflow, which is unrealistic.
    uint256 private constant _MAX_MINT_ERC2309_QUANTITY_LIMIT = 5000;

    // The `Transfer` event signature is given by:
    // `keccak256(bytes("Transfer(address,address,uint256)"))`.
    bytes32 private constant _TRANSFER_EVENT_SIGNATURE =
        0xddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef;

    // =============================================================
    //                            STORAGE
    // =============================================================

    // The next token ID to be minted.
    uint256 private _currentIndex;

    // The number of tokens burned.
    uint256 private _burnCounter;

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Mapping from token ID to ownership details
    // An empty struct value does not necessarily mean the token is unowned.
    // See {_packedOwnershipOf} implementation for details.
    //
    // Bits Layout:
    // - [0..159]   `addr`
    // - [160..223] `startTimestamp`
    // - [224]      `burned`
    // - [225]      `nextInitialized`
    // - [232..255] `extraData`
    mapping(uint256 => uint256) private _packedOwnerships;

    // Mapping owner address to address data.
    //
    // Bits Layout:
    // - [0..63]    `balance`
    // - [64..127]  `numberMinted`
    // - [128..191] `numberBurned`
    // - [192..255] `aux`
    mapping(address => uint256) private _packedAddressData;

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

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

    // =============================================================
    //                          CONSTRUCTOR
    // =============================================================

    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
        _currentIndex = _startTokenId();
    }

    // =============================================================
    //                   TOKEN COUNTING OPERATIONS
    // =============================================================

    /**
     * @dev Returns the starting token ID.
     * To change the starting token ID, please override this function.
     */
    function _startTokenId() internal view virtual returns (uint256) {
        return 0;
    }

    /**
     * @dev Returns the next token ID to be minted.
     */
    function _nextTokenId() internal view virtual returns (uint256) {
        return _currentIndex;
    }

    /**
     * @dev Returns the total number of tokens in existence.
     * Burned tokens will reduce the count.
     * To get the total number of tokens minted, please see {_totalMinted}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        // Counter underflow is impossible as _burnCounter cannot be incremented
        // more than `_currentIndex - _startTokenId()` times.
        unchecked {
            return _currentIndex - _burnCounter - _startTokenId();
        }
    }

    /**
     * @dev Returns the total amount of tokens minted in the contract.
     */
    function _totalMinted() internal view virtual returns (uint256) {
        // Counter underflow is impossible as `_currentIndex` does not decrement,
        // and it is initialized to `_startTokenId()`.
        unchecked {
            return _currentIndex - _startTokenId();
        }
    }

    /**
     * @dev Returns the total number of tokens burned.
     */
    function _totalBurned() internal view virtual returns (uint256) {
        return _burnCounter;
    }

    // =============================================================
    //                    ADDRESS DATA OPERATIONS
    // =============================================================

    /**
     * @dev Returns the number of tokens in `owner`'s account.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        if (owner == address(0)) revert BalanceQueryForZeroAddress();
        return _packedAddressData[owner] & _BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the number of tokens minted by `owner`.
     */
    function _numberMinted(address owner) internal view returns (uint256) {
        return (_packedAddressData[owner] >> _BITPOS_NUMBER_MINTED) & _BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the number of tokens burned by or on behalf of `owner`.
     */
    function _numberBurned(address owner) internal view returns (uint256) {
        return (_packedAddressData[owner] >> _BITPOS_NUMBER_BURNED) & _BITMASK_ADDRESS_DATA_ENTRY;
    }

    /**
     * Returns the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
     */
    function _getAux(address owner) internal view returns (uint64) {
        return uint64(_packedAddressData[owner] >> _BITPOS_AUX);
    }

    /**
     * Sets the auxiliary data for `owner`. (e.g. number of whitelist mint slots used).
     * If there are multiple variables, please pack them into a uint64.
     */
    function _setAux(address owner, uint64 aux) internal virtual {
        uint256 packed = _packedAddressData[owner];
        uint256 auxCasted;
        // Cast `aux` with assembly to avoid redundant masking.
        assembly {
            auxCasted := aux
        }
        packed = (packed & _BITMASK_AUX_COMPLEMENT) | (auxCasted << _BITPOS_AUX);
        _packedAddressData[owner] = packed;
    }

    // =============================================================
    //                            IERC165
    // =============================================================

    /**
     * @dev Returns true if this contract implements the interface defined by
     * `interfaceId`. See the corresponding
     * [EIP section](https://eips.ethereum.org/EIPS/eip-165#how-interfaces-are-identified)
     * to learn more about how these ids are created.
     *
     * This function call must use less than 30000 gas.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        // The interface IDs are constants representing the first 4 bytes
        // of the XOR of all function selectors in the interface.
        // See: [ERC165](https://eips.ethereum.org/EIPS/eip-165)
        // (e.g. `bytes4(i.functionA.selector ^ i.functionB.selector ^ ...)`)
        return
            interfaceId == 0x01ffc9a7 || // ERC165 interface ID for ERC165.
            interfaceId == 0x80ac58cd || // ERC165 interface ID for ERC721.
            interfaceId == 0x5b5e139f; // ERC165 interface ID for ERC721Metadata.
    }

    // =============================================================
    //                        IERC721Metadata
    // =============================================================

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

    /**
     * @dev Returns the token collection symbol.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev Returns the Uniform Resource Identifier (URI) for `tokenId` token.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

        string memory baseURI = _baseURI();
        return bytes(baseURI).length != 0 ? string(abi.encodePacked(baseURI, _toString(tokenId))) : '';
    }

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

    // =============================================================
    //                     OWNERSHIPS OPERATIONS
    // =============================================================

    /**
     * @dev Returns the owner of the `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        return address(uint160(_packedOwnershipOf(tokenId)));
    }

    /**
     * @dev Gas spent here starts off proportional to the maximum mint batch size.
     * It gradually moves to O(1) as tokens get transferred around over time.
     */
    function _ownershipOf(uint256 tokenId) internal view virtual returns (TokenOwnership memory) {
        return _unpackedOwnership(_packedOwnershipOf(tokenId));
    }

    /**
     * @dev Returns the unpacked `TokenOwnership` struct at `index`.
     */
    function _ownershipAt(uint256 index) internal view virtual returns (TokenOwnership memory) {
        return _unpackedOwnership(_packedOwnerships[index]);
    }

    /**
     * @dev Initializes the ownership slot minted at `index` for efficiency purposes.
     */
    function _initializeOwnershipAt(uint256 index) internal virtual {
        if (_packedOwnerships[index] == 0) {
            _packedOwnerships[index] = _packedOwnershipOf(index);
        }
    }

    /**
     * Returns the packed ownership data of `tokenId`.
     */
    function _packedOwnershipOf(uint256 tokenId) private view returns (uint256) {
        uint256 curr = tokenId;

        unchecked {
            if (_startTokenId() <= curr)
                if (curr < _currentIndex) {
                    uint256 packed = _packedOwnerships[curr];
                    // If not burned.
                    if (packed & _BITMASK_BURNED == 0) {
                        // Invariant:
                        // There will always be an initialized ownership slot
                        // (i.e. `ownership.addr != address(0) && ownership.burned == false`)
                        // before an unintialized ownership slot
                        // (i.e. `ownership.addr == address(0) && ownership.burned == false`)
                        // Hence, `curr` will not underflow.
                        //
                        // We can directly compare the packed value.
                        // If the address is zero, packed will be zero.
                        while (packed == 0) {
                            packed = _packedOwnerships[--curr];
                        }
                        return packed;
                    }
                }
        }
        revert OwnerQueryForNonexistentToken();
    }

    /**
     * @dev Returns the unpacked `TokenOwnership` struct from `packed`.
     */
    function _unpackedOwnership(uint256 packed) private pure returns (TokenOwnership memory ownership) {
        ownership.addr = address(uint160(packed));
        ownership.startTimestamp = uint64(packed >> _BITPOS_START_TIMESTAMP);
        ownership.burned = packed & _BITMASK_BURNED != 0;
        ownership.extraData = uint24(packed >> _BITPOS_EXTRA_DATA);
    }

    /**
     * @dev Packs ownership data into a single uint256.
     */
    function _packOwnershipData(address owner, uint256 flags) private view returns (uint256 result) {
        assembly {
            // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
            owner := and(owner, _BITMASK_ADDRESS)
            // `owner | (block.timestamp << _BITPOS_START_TIMESTAMP) | flags`.
            result := or(owner, or(shl(_BITPOS_START_TIMESTAMP, timestamp()), flags))
        }
    }

    /**
     * @dev Returns the `nextInitialized` flag set if `quantity` equals 1.
     */
    function _nextInitializedFlag(uint256 quantity) private pure returns (uint256 result) {
        // For branchless setting of the `nextInitialized` flag.
        assembly {
            // `(quantity == 1) << _BITPOS_NEXT_INITIALIZED`.
            result := shl(_BITPOS_NEXT_INITIALIZED, eq(quantity, 1))
        }
    }

    // =============================================================
    //                      APPROVAL OPERATIONS
    // =============================================================

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

        if (_msgSenderERC721A() != owner)
            if (!isApprovedForAll(owner, _msgSenderERC721A())) {
                revert ApprovalCallerNotOwnerNorApproved();
            }

        _tokenApprovals[tokenId].value = to;
        emit Approval(owner, to, tokenId);
    }

    /**
     * @dev Returns the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId].value;
    }

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

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

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted. See {_mint}.
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return
            _startTokenId() <= tokenId &&
            tokenId < _currentIndex && // If within bounds,
            _packedOwnerships[tokenId] & _BITMASK_BURNED == 0; // and not burned.
    }

    /**
     * @dev Returns whether `msgSender` is equal to `approvedAddress` or `owner`.
     */
    function _isSenderApprovedOrOwner(
        address approvedAddress,
        address owner,
        address msgSender
    ) private pure returns (bool result) {
        assembly {
            // Mask `owner` to the lower 160 bits, in case the upper bits somehow aren't clean.
            owner := and(owner, _BITMASK_ADDRESS)
            // Mask `msgSender` to the lower 160 bits, in case the upper bits somehow aren't clean.
            msgSender := and(msgSender, _BITMASK_ADDRESS)
            // `msgSender == owner || msgSender == approvedAddress`.
            result := or(eq(msgSender, owner), eq(msgSender, approvedAddress))
        }
    }

    /**
     * @dev Returns the storage slot and value for the approved address of `tokenId`.
     */
    function _getApprovedSlotAndAddress(uint256 tokenId)
        private
        view
        returns (uint256 approvedAddressSlot, address approvedAddress)
    {
        TokenApprovalRef storage tokenApproval = _tokenApprovals[tokenId];
        // The following is equivalent to `approvedAddress = _tokenApprovals[tokenId].value`.
        assembly {
            approvedAddressSlot := tokenApproval.slot
            approvedAddress := sload(approvedAddressSlot)
        }
    }

    // =============================================================
    //                      TRANSFER OPERATIONS
    // =============================================================

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token
     * by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public payable virtual override {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

        if (address(uint160(prevOwnershipPacked)) != from) revert TransferFromIncorrectOwner();

        (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);

        // The nested ifs save around 20+ gas over a compound boolean condition.
        if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
            if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();

        if (to == address(0)) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

        // Clear approvals from the previous owner.
        assembly {
            if approvedAddress {
                // This is equivalent to `delete _tokenApprovals[tokenId]`.
                sstore(approvedAddressSlot, 0)
            }
        }

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256.
        unchecked {
            // We can directly increment and decrement the balances.
            --_packedAddressData[from]; // Updates: `balance -= 1`.
            ++_packedAddressData[to]; // Updates: `balance += 1`.

            // Updates:
            // - `address` to the next owner.
            // - `startTimestamp` to the timestamp of transfering.
            // - `burned` to `false`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] = _packOwnershipData(
                to,
                _BITMASK_NEXT_INITIALIZED | _nextExtraData(from, to, prevOwnershipPacked)
            );

            // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
            if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
                uint256 nextTokenId = tokenId + 1;
                // If the next slot's address is zero and not burned (i.e. packed value is zero).
                if (_packedOwnerships[nextTokenId] == 0) {
                    // If the next slot is within bounds.
                    if (nextTokenId != _currentIndex) {
                        // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
                        _packedOwnerships[nextTokenId] = prevOwnershipPacked;
                    }
                }
            }
        }

        emit Transfer(from, to, tokenId);
        _afterTokenTransfers(from, to, tokenId, 1);
    }

    /**
     * @dev Equivalent to `safeTransferFrom(from, to, tokenId, '')`.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public payable virtual override {
        safeTransferFrom(from, to, tokenId, '');
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token
     * by either {approve} or {setApprovalForAll}.
     * - If `to` refers to a smart contract, it must implement
     * {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public payable virtual override {
        transferFrom(from, to, tokenId);
        if (to.code.length != 0)
            if (!_checkContractOnERC721Received(from, to, tokenId, _data)) {
                revert TransferToNonERC721ReceiverImplementer();
            }
    }

    /**
     * @dev Hook that is called before a set of serially-ordered token IDs
     * are about to be transferred. This includes minting.
     * And also called before burning one token.
     *
     * `startTokenId` - the first token ID to be transferred.
     * `quantity` - the amount to be transferred.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _beforeTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Hook that is called after a set of serially-ordered token IDs
     * have been transferred. This includes minting.
     * And also called after one token has been burned.
     *
     * `startTokenId` - the first token ID to be transferred.
     * `quantity` - the amount to be transferred.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` has been
     * transferred to `to`.
     * - When `from` is zero, `tokenId` has been minted for `to`.
     * - When `to` is zero, `tokenId` has been burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _afterTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}

    /**
     * @dev Private function to invoke {IERC721Receiver-onERC721Received} on a target contract.
     *
     * `from` - Previous owner of the given token ID.
     * `to` - Target address that will receive the token.
     * `tokenId` - Token ID to be transferred.
     * `_data` - Optional data to send along with the call.
     *
     * Returns whether the call correctly returned the expected magic value.
     */
    function _checkContractOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        try ERC721A__IERC721Receiver(to).onERC721Received(_msgSenderERC721A(), from, tokenId, _data) returns (
            bytes4 retval
        ) {
            return retval == ERC721A__IERC721Receiver(to).onERC721Received.selector;
        } catch (bytes memory reason) {
            if (reason.length == 0) {
                revert TransferToNonERC721ReceiverImplementer();
            } else {
                assembly {
                    revert(add(32, reason), mload(reason))
                }
            }
        }
    }

    // =============================================================
    //                        MINT OPERATIONS
    // =============================================================

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event for each mint.
     */
    function _mint(address to, uint256 quantity) internal virtual {
        uint256 startTokenId = _currentIndex;
        if (quantity == 0) revert MintZeroQuantity();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are incredibly unrealistic.
        // `balance` and `numberMinted` have a maximum limit of 2**64.
        // `tokenId` has a maximum limit of 2**256.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
            );

            uint256 toMasked;
            uint256 end = startTokenId + quantity;

            // Use assembly to loop and emit the `Transfer` event for gas savings.
            // The duplicated `log4` removes an extra check and reduces stack juggling.
            // The assembly, together with the surrounding Solidity code, have been
            // delicately arranged to nudge the compiler into producing optimized opcodes.
            assembly {
                // Mask `to` to the lower 160 bits, in case the upper bits somehow aren't clean.
                toMasked := and(to, _BITMASK_ADDRESS)
                // Emit the `Transfer` event.
                log4(
                    0, // Start of data (0, since no data).
                    0, // End of data (0, since no data).
                    _TRANSFER_EVENT_SIGNATURE, // Signature.
                    0, // `address(0)`.
                    toMasked, // `to`.
                    startTokenId // `tokenId`.
                )

                // The `iszero(eq(,))` check ensures that large values of `quantity`
                // that overflows uint256 will make the loop run out of gas.
                // The compiler will optimize the `iszero` away for performance.
                for {
                    let tokenId := add(startTokenId, 1)
                } iszero(eq(tokenId, end)) {
                    tokenId := add(tokenId, 1)
                } {
                    // Emit the `Transfer` event. Similar to above.
                    log4(0, 0, _TRANSFER_EVENT_SIGNATURE, 0, toMasked, tokenId)
                }
            }
            if (toMasked == 0) revert MintToZeroAddress();

            _currentIndex = end;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * This function is intended for efficient minting only during contract creation.
     *
     * It emits only one {ConsecutiveTransfer} as defined in
     * [ERC2309](https://eips.ethereum.org/EIPS/eip-2309),
     * instead of a sequence of {Transfer} event(s).
     *
     * Calling this function outside of contract creation WILL make your contract
     * non-compliant with the ERC721 standard.
     * For full ERC721 compliance, substituting ERC721 {Transfer} event(s) with the ERC2309
     * {ConsecutiveTransfer} event is only permissible during contract creation.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {ConsecutiveTransfer} event.
     */
    function _mintERC2309(address to, uint256 quantity) internal virtual {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();
        if (quantity > _MAX_MINT_ERC2309_QUANTITY_LIMIT) revert MintERC2309QuantityExceedsLimit();

        _beforeTokenTransfers(address(0), to, startTokenId, quantity);

        // Overflows are unrealistic due to the above check for `quantity` to be below the limit.
        unchecked {
            // Updates:
            // - `balance += quantity`.
            // - `numberMinted += quantity`.
            //
            // We can directly add to the `balance` and `numberMinted`.
            _packedAddressData[to] += quantity * ((1 << _BITPOS_NUMBER_MINTED) | 1);

            // Updates:
            // - `address` to the owner.
            // - `startTimestamp` to the timestamp of minting.
            // - `burned` to `false`.
            // - `nextInitialized` to `quantity == 1`.
            _packedOwnerships[startTokenId] = _packOwnershipData(
                to,
                _nextInitializedFlag(quantity) | _nextExtraData(address(0), to, 0)
            );

            emit ConsecutiveTransfer(startTokenId, startTokenId + quantity - 1, address(0), to);

            _currentIndex = startTokenId + quantity;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Safely mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement
     * {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
     * - `quantity` must be greater than 0.
     *
     * See {_mint}.
     *
     * Emits a {Transfer} event for each mint.
     */
    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal virtual {
        _mint(to, quantity);

        unchecked {
            if (to.code.length != 0) {
                uint256 end = _currentIndex;
                uint256 index = end - quantity;
                do {
                    if (!_checkContractOnERC721Received(address(0), to, index++, _data)) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (index < end);
                // Reentrancy protection.
                if (_currentIndex != end) revert();
            }
        }
    }

    /**
     * @dev Equivalent to `_safeMint(to, quantity, '')`.
     */
    function _safeMint(address to, uint256 quantity) internal virtual {
        _safeMint(to, quantity, '');
    }

    // =============================================================
    //                        BURN OPERATIONS
    // =============================================================

    /**
     * @dev Equivalent to `_burn(tokenId, false)`.
     */
    function _burn(uint256 tokenId) internal virtual {
        _burn(tokenId, false);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId, bool approvalCheck) internal virtual {
        uint256 prevOwnershipPacked = _packedOwnershipOf(tokenId);

        address from = address(uint160(prevOwnershipPacked));

        (uint256 approvedAddressSlot, address approvedAddress) = _getApprovedSlotAndAddress(tokenId);

        if (approvalCheck) {
            // The nested ifs save around 20+ gas over a compound boolean condition.
            if (!_isSenderApprovedOrOwner(approvedAddress, from, _msgSenderERC721A()))
                if (!isApprovedForAll(from, _msgSenderERC721A())) revert TransferCallerNotOwnerNorApproved();
        }

        _beforeTokenTransfers(from, address(0), tokenId, 1);

        // Clear approvals from the previous owner.
        assembly {
            if approvedAddress {
                // This is equivalent to `delete _tokenApprovals[tokenId]`.
                sstore(approvedAddressSlot, 0)
            }
        }

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as `tokenId` would have to be 2**256.
        unchecked {
            // Updates:
            // - `balance -= 1`.
            // - `numberBurned += 1`.
            //
            // We can directly decrement the balance, and increment the number burned.
            // This is equivalent to `packed -= 1; packed += 1 << _BITPOS_NUMBER_BURNED;`.
            _packedAddressData[from] += (1 << _BITPOS_NUMBER_BURNED) - 1;

            // Updates:
            // - `address` to the last owner.
            // - `startTimestamp` to the timestamp of burning.
            // - `burned` to `true`.
            // - `nextInitialized` to `true`.
            _packedOwnerships[tokenId] = _packOwnershipData(
                from,
                (_BITMASK_BURNED | _BITMASK_NEXT_INITIALIZED) | _nextExtraData(from, address(0), prevOwnershipPacked)
            );

            // If the next slot may not have been initialized (i.e. `nextInitialized == false`) .
            if (prevOwnershipPacked & _BITMASK_NEXT_INITIALIZED == 0) {
                uint256 nextTokenId = tokenId + 1;
                // If the next slot's address is zero and not burned (i.e. packed value is zero).
                if (_packedOwnerships[nextTokenId] == 0) {
                    // If the next slot is within bounds.
                    if (nextTokenId != _currentIndex) {
                        // Initialize the next slot to maintain correctness for `ownerOf(tokenId + 1)`.
                        _packedOwnerships[nextTokenId] = prevOwnershipPacked;
                    }
                }
            }
        }

        emit Transfer(from, address(0), tokenId);
        _afterTokenTransfers(from, address(0), tokenId, 1);

        // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
        unchecked {
            _burnCounter++;
        }
    }

    // =============================================================
    //                     EXTRA DATA OPERATIONS
    // =============================================================

    /**
     * @dev Directly sets the extra data for the ownership data `index`.
     */
    function _setExtraDataAt(uint256 index, uint24 extraData) internal virtual {
        uint256 packed = _packedOwnerships[index];
        if (packed == 0) revert OwnershipNotInitializedForExtraData();
        uint256 extraDataCasted;
        // Cast `extraData` with assembly to avoid redundant masking.
        assembly {
            extraDataCasted := extraData
        }
        packed = (packed & _BITMASK_EXTRA_DATA_COMPLEMENT) | (extraDataCasted << _BITPOS_EXTRA_DATA);
        _packedOwnerships[index] = packed;
    }

    /**
     * @dev Called during each token transfer to set the 24bit `extraData` field.
     * Intended to be overridden by the cosumer contract.
     *
     * `previousExtraData` - the value of `extraData` before transfer.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, `from`'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _extraData(
        address from,
        address to,
        uint24 previousExtraData
    ) internal view virtual returns (uint24) {}

    /**
     * @dev Returns the next extra data for the packed ownership data.
     * The returned result is shifted into position.
     */
    function _nextExtraData(
        address from,
        address to,
        uint256 prevOwnershipPacked
    ) private view returns (uint256) {
        uint24 extraData = uint24(prevOwnershipPacked >> _BITPOS_EXTRA_DATA);
        return uint256(_extraData(from, to, extraData)) << _BITPOS_EXTRA_DATA;
    }

    // =============================================================
    //                       OTHER OPERATIONS
    // =============================================================

    /**
     * @dev Returns the message sender (defaults to `msg.sender`).
     *
     * If you are writing GSN compatible contracts, you need to override this function.
     */
    function _msgSenderERC721A() internal view virtual returns (address) {
        return msg.sender;
    }

    /**
     * @dev Converts a uint256 to its ASCII string decimal representation.
     */
    function _toString(uint256 value) internal pure virtual returns (string memory str) {
        assembly {
            // The maximum value of a uint256 contains 78 digits (1 byte per digit), but
            // we allocate 0xa0 bytes to keep the free memory pointer 32-byte word aligned.
            // We will need 1 word for the trailing zeros padding, 1 word for the length,
            // and 3 words for a maximum of 78 digits. Total: 5 * 0x20 = 0xa0.
            let m := add(mload(0x40), 0xa0)
            // Update the free memory pointer to allocate.
            mstore(0x40, m)
            // Assign the `str` to the end.
            str := sub(m, 0x20)
            // Zeroize the slot after the string.
            mstore(str, 0)

            // Cache the end of the memory to calculate the length later.
            let end := str

            // We write the string from rightmost digit to leftmost digit.
            // The following is essentially a do-while loop that also handles the zero case.
            // prettier-ignore
            for { let temp := value } 1 {} {
                str := sub(str, 1)
                // Write the character to the pointer.
                // The ASCII index of the '0' character is 48.
                mstore8(str, add(48, mod(temp, 10)))
                // Keep dividing `temp` until zero.
                temp := div(temp, 10)
                // prettier-ignore
                if iszero(temp) { break }
            }

            let length := sub(end, str)
            // Move the pointer 32 bytes leftwards to make room for the length.
            str := sub(str, 0x20)
            // Store the length.
            mstore(str, length)
        }
    }
}

// File: chillorbs.sol


pragma solidity ^0.8.4;









contract ChillOrbs is
    ERC721A,
    Ownable,
    Pausable,
    ReentrancyGuard,
    DefaultOperatorFilterer
{
    constructor() ERC721A("ChillOrbs", "CHILLORBS") {}

    uint256 public MINT_START_TIME = 0;
    uint256 public MINT_END_TIME = 0;
    uint256 public MINT_PRICE = 0.0069 ether;
    uint16 public COLLECTION_SIZE = 10000;
    bool public BURN_OPEN = false;
    string private previewBaseURI = "ipfs://QmbWA9qTcgpw3oZVE5AM1iegzCzg6DjqDzEfR8ru8deDbM";
    string private tokenHtmlSourceCode = '<!doctype html><title>ChillOrb</title><script src="https://cdnjs.cloudflare.com/ajax/libs/seedrandom/3.0.5/seedrandom.min.js" integrity="sha512-+Ru50BzEpZjlFzVnjSmJfYFPFfY2hS0Kjlu/IvqaJoux7maF5lJrRVUJWJ2LevPls7rd242GLbWEt+zAo4OVVQ==" crossorigin="anonymous"></script><script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.5.0/p5.min.js" integrity="sha512-WJXVjqeINVpi5XXJ2jn0BSCfp0y80IKrYh731gLRnkAS9TKc5KNt/OfLtu+fCueqdWniouJ1ubM+VI/hbo7POQ==" crossorigin="anonymous"></script><body style="background:#000;padding:0;margin:0;overflow: hidden"><script>(()=>{"use strict";function m(m){return m<=.33?"x":m<=.66?"y":"z"}let b=new URLSearchParams(window.location.search),l=b.get("tokenId")||(0,1e3,Math.floor(1001*Math.random())+0);let W="true"===b.get("blackAndWhite"),t="%TOREPLACE.TOKENID%";t.startsWith("%TOREPLACE.")||(l=t);let e="%TOREPLACE.ISCOLORED%";e.startsWith("%TOREPLACE.")||(W="false"===e.toLowerCase());let Z=new Math.seedrandom(l);new p5((b=>{let l;function t(){let m=Z();return m>.3?200:parseInt(50*m)+2}b.preload=()=>{l=b.loadShader("data:@file/x-c;base64,YXR0cmlidXRlIHZlYzMgYVBvc2l0aW9uO2F0dHJpYnV0ZSB2ZWMzIGFOb3JtYWw7dW5pZm9ybSBtYXQ0IHVQcm9qZWN0aW9uTWF0cml4O3VuaWZvcm0gbWF0NCB1TW9kZWxWaWV3TWF0cml4O3VuaWZvcm0gZmxvYXQgZnJhbWVDb3VudDt1bmlmb3JtIGZsb2F0IG1vdmluZ1NwZWVkO3VuaWZvcm0gZmxvYXQgZnJlcXVlbmN5O3VuaWZvcm0gZmxvYXQgYW1wbGl0dWRlO3VuaWZvcm0gZmxvYXQgY29udHJhc3ROb3JtYWxpemVyO3VuaWZvcm0gZmxvYXQgYnJpZ2h0bmVzc05vcm1hbGl6ZXI7dW5pZm9ybSBmbG9hdCBzaXplO3VuaWZvcm0gZmxvYXQgY29sb3JSYW5kWDt1bmlmb3JtIGZsb2F0IGNvbG9yUmFuZFk7dW5pZm9ybSBmbG9hdCBjb2xvclJhbmRaO3VuaWZvcm0gYm9vbCBwb3NpdGlvbk1peGVyO3VuaWZvcm0gYm9vbCBwb3NpdGlvbk1vdmVyO3ZhcnlpbmcgdmVjMyB2Tm9ybWFsO3ZhcnlpbmcgZmxvYXQgdkNvbnRyYXN0Tm9ybWFsaXplcjt2YXJ5aW5nIGZsb2F0IHZCcmlnaHRuZXNzTm9ybWFsaXplcjt2YXJ5aW5nIGZsb2F0IHZDb2xvclJhbmRYO3ZhcnlpbmcgZmxvYXQgdkNvbG9yUmFuZFk7dmFyeWluZyBmbG9hdCB2Q29sb3JSYW5kWjt2ZWM0IHBvc2l0aW9uTW92ZXJGdW5jKHZlYzQgcG9zaXRpb25WZWM0LCBmbG9hdCBzdW0pIHtpZiAocG9zaXRpb25Nb3Zlcikge3Bvc2l0aW9uVmVjNC54ICs9IHN1bTt9IGVsc2Uge3Bvc2l0aW9uVmVjNC55ICs9IHN1bTt9cmV0dXJuIHBvc2l0aW9uVmVjNDt9dm9pZCBtYWluKCkge3ZlYzQgcG9zaXRpb25WZWM0ID0gdmVjNChhUG9zaXRpb24sIHNpemUpO2Zsb2F0IHJhbmRQb3NpdGlvblZlYzQgPSBwb3NpdGlvbk1peGVyID8gcG9zaXRpb25WZWM0LnggOiBwb3NpdGlvblZlYzQueTtmbG9hdCBkaXN0b3J0aW9uID0gc2luKHJhbmRQb3NpdGlvblZlYzQgKiBmcmVxdWVuY3kgKyBmcmFtZUNvdW50ICogbW92aW5nU3BlZWQpO3Bvc2l0aW9uVmVjNCA9IHBvc2l0aW9uTW92ZXJGdW5jKHBvc2l0aW9uVmVjNCwgZGlzdG9ydGlvbiAqIGFOb3JtYWwueCAqIGFtcGxpdHVkZSk7dk5vcm1hbCA9IGFOb3JtYWw7dkNvbnRyYXN0Tm9ybWFsaXplciA9IGNvbnRyYXN0Tm9ybWFsaXplcjt2Q29sb3JSYW5kWCA9IGNvbG9yUmFuZFg7dkNvbG9yUmFuZFkgPSBjb2xvclJhbmRZO3ZDb2xvclJhbmRaID0gY29sb3JSYW5kWjt2QnJpZ2h0bmVzc05vcm1hbGl6ZXIgPSBicmlnaHRuZXNzTm9ybWFsaXplcjtnbF9Qb3NpdGlvbiA9IHVQcm9qZWN0aW9uTWF0cml4ICogdU1vZGVsVmlld01hdHJpeCAqIHBvc2l0aW9uVmVjNDt9","data:@file/x-c;base64,cHJlY2lzaW9uIG1lZGl1bXAgZmxvYXQ7dmFyeWluZyB2ZWMzIHZOb3JtYWw7dmFyeWluZyBmbG9hdCB2Q29udHJhc3ROb3JtYWxpemVyO3ZhcnlpbmcgZmxvYXQgdkJyaWdodG5lc3NOb3JtYWxpemVyO3ZhcnlpbmcgZmxvYXQgdkNvbG9yUmFuZFg7dmFyeWluZyBmbG9hdCB2Q29sb3JSYW5kWTt2YXJ5aW5nIGZsb2F0IHZDb2xvclJhbmRaO2Zsb2F0IGRpbWVuc29pbk1peGVyKHZlYzMgYXJyYXksIGZsb2F0IHJhbmQpIHtpZiAocmFuZCA8PSAwLjMzKSB7cmV0dXJuIGFycmF5Lng7fSBlbHNlIGlmIChyYW5kIDw9IDAuNjYpIHtyZXR1cm4gYXJyYXkueTt9IGVsc2Uge3JldHVybiBhcnJheS56O319dm9pZCBtYWluKCkge3ZlYzMgY29sb3IgPSB2Tm9ybWFsICogdkNvbnRyYXN0Tm9ybWFsaXplciArIHZCcmlnaHRuZXNzTm9ybWFsaXplcjtnbF9GcmFnQ29sb3IgPSB2ZWM0KGRpbWVuc29pbk1peGVyKGNvbG9yLCB2Q29sb3JSYW5kWCksZGltZW5zb2luTWl4ZXIoY29sb3IsIHZDb2xvclJhbmRZKSxkaW1lbnNvaW5NaXhlcihjb2xvciwgdkNvbG9yUmFuZFopLDEuMCk7fQ==")},b.setup=()=>{b.createCanvas(b.windowWidth,b.windowHeight,b.WEBGL),b.noStroke()};const e=t(),c=t(),a=.2*Z()+.03,d=20*Z()+10,n=Z(),s=.25+.5*Z(),v=.25+.5*Z();let G=Z(),g=Z(),u=Z();const Y=Z()<=.8,o=Z()<=.8;let p=1+.5*Z();window.addEventListener("wheel",(m=>{const b=Math.sign(m.deltaY);p*=1===b?1.2:.8})),W?(g=G,u=G):m(G)===m(g)&&m(g)===m(u)&&(G>=.5?G-=.34:G+=.34),b.draw=()=>{let m=(new Date).getTime()/1e3;b.background("#000"),b.shader(l),l.setUniform("frameCount",b.frameCount),l.setUniform("movingSpeed",a),l.setUniform("frequency",d),l.setUniform("amplitude",n),l.setUniform("contrastNormalizer",s),l.setUniform("brightnessNormalizer",v),l.setUniform("size",p),l.setUniform("colorRandX",G),l.setUniform("colorRandY",g),l.setUniform("colorRandZ",u),l.setUniform("positionMixer",Y),l.setUniform("positionMover",o),b.rotateX(.6*m),b.rotateY(.3*m),b.sphere(b.width/5,e,c)},b.windowResized=()=>{b.resizeCanvas(b.windowWidth,b.windowHeight)}}))})();</script></body>';

    string private metadataBaseJSON = '{"name":"ChillOrb #%TOKENID%","image":"%PREVIEW%","animation_url":"%ORBURI%","attributes":[{"trait_type":"Colorful","value":"%COLORFUL%"}]}';

    // tokenId => isColored (stores colored tokens)
    mapping(uint256 => bool) private COLORED_TOKENS;

    // Helpers & tools
    function numberMinted(address owner) public view returns (uint256) {
        return _numberMinted(owner);
    }
    
    // Preview URI
    function tokenPreviewURI(uint256 tokenId) private view returns (string memory) {
        return string.concat(previewBaseURI, isColored(tokenId) ? "/colorful/" : "/blackAndWhite/", Utils.uintToString(tokenId), ".jpg");
    }
    
    function setTokenPreviewBaseURI(string calldata baseURI) external onlyOwner {
        previewBaseURI = baseURI;
    }

    // Working with token source
    function uploadHTML(string calldata sourceCode) external onlyOwner {
        tokenHtmlSourceCode = sourceCode;
    }

    function downloadHTML() external view onlyOwner returns (string memory) {
        return tokenHtmlSourceCode;
    }

    function generateHTML(uint256 tokenId) public view returns (string memory) {
        // %TOREPLACE.TOKENID% -> tokenId
        // %TOREPLACE.ISCOLORED% -> isColored
        string memory withTokenId = Utils.replaceInString(tokenHtmlSourceCode, "%TOREPLACE.TOKENID%", Utils.uintToString(tokenId));
        string memory coloredString = isColored(tokenId) ? "true" : "false";

        return Utils.replaceInString(withTokenId, "%TOREPLACE.ISCOLORED%", coloredString);
    }

    function orbBase64(uint256 tokenId) private view returns (string memory) {
        return Base64.encode(bytes(generateHTML(tokenId)));
    }

    function generateOrbURI(uint256 tokenId) public view returns (string memory) {
        return string.concat("data:text/html;base64,", orbBase64(tokenId));
    }

    // Initial mint to get the collection listed on marketplaces
    function initialMint() external onlyOwner {
        uint256 quantity = 1;
        _mint(msg.sender, quantity);
    }

    // Dev mint
    function devMint() external onlyOwner {
        uint256 quantity = 50;
        require(
            totalSupply() + quantity <= COLLECTION_SIZE,
            "Not enough remaining NFTs to support desired mint amount."
        );
        _mint(msg.sender, quantity);
    }

    // Mint
    function mint(uint256 quantity) external payable {
        require(
            totalSupply() + quantity <= COLLECTION_SIZE,
            "Not enough remaining NFTs to support desired mint amount."
        );

        require(
            MINT_START_TIME <= block.timestamp && MINT_START_TIME != 0,
            "Public mint is not started yet. Please check back later and follow us on twitter: @chillorbs"
        );

        require(
            MINT_END_TIME > block.timestamp,
            "Public mint is closed. Please check back later and follow us on twitter: @chillorbs"
        );

        uint256 totalCost = MINT_PRICE * quantity - (numberMinted(msg.sender) == 0 ? MINT_PRICE : 0);
        _refundIfOver(totalCost);
        _mint(msg.sender, quantity);
    }

    // Start mint at the specified time
    function startMintAt(uint256 startTimestampSeconds) public onlyOwner {
        // Locks the minting process after 24 hours
        MINT_START_TIME = startTimestampSeconds;
        MINT_END_TIME = startTimestampSeconds + 24 * 60 * 60;
    }

    // Start mint now
    function startMint() external onlyOwner {
        startMintAt(block.timestamp);
    }

    // End mint
    function endMint() external onlyOwner {
        MINT_END_TIME = block.timestamp;
    }

    // Set end time manually
    function setEndTime(uint256 endTimestampSeconds) external onlyOwner {
        MINT_END_TIME = endTimestampSeconds;
    }

    // Helpers & tools

    function _refundIfOver(uint256 price) private {
        require(msg.value >= price, "Need to send more ETH.");
        if (msg.value > price) {
            payable(msg.sender).transfer(msg.value - price);
        }
    }

    function withdrawMoney() external onlyOwner nonReentrant {
        (bool success, ) = msg.sender.call{value: address(this).balance}("");
        require(success, "Transfer failed.");
    }

    function getOwnershipData(uint256 tokenId)
        external
        view
        returns (TokenOwnership memory)
    {
        return _ownershipOf(tokenId);
    }

    // Burn
    function burn(uint256 tokenId1, uint256 tokenId2, uint256 tokenId3) public {
        require(BURN_OPEN, "Burn is currently paused.");

        _burn(tokenId1, true); // true required for approval check
        _burn(tokenId2, true); // true required for approval check

        require(
            !COLORED_TOKENS[tokenId3],
            "The third token is already colored."
        );
        require(
            ownerOf(tokenId3) == msg.sender,
            "You must be the owner of the third token."
        );
        COLORED_TOKENS[tokenId3] = true;
    }

    // Contract owner can burn any NFT if it was stolen
    function burnStolen(uint256 tokenId) external onlyOwner {
        _burn(tokenId, false);
    }

    function closeBurn() external onlyOwner {
        BURN_OPEN = false;
    }

    function openBurn() external onlyOwner {
        BURN_OPEN = true;
    }

    // Returns true if the token is colored
    function isColored(uint256 tokenId) public view returns (bool) {
        return COLORED_TOKENS[tokenId];
    }

    // metadata URI
    function generateJSON(uint256 tokenId) private view returns (string memory) {
        string memory json = metadataBaseJSON;
        json = Utils.replaceInString(json, "%TOKENID%", Utils.uintToString(tokenId));
        json = Utils.replaceInString(json, "%PREVIEW%", tokenPreviewURI(tokenId));
        json = Utils.replaceInString(json, "%ORBURI%", generateOrbURI(tokenId));
        json = Utils.replaceInString(json, "%ORBURI%", generateOrbURI(tokenId));
        json = Utils.replaceInString(json, "%COLORFUL%", isColored(tokenId) ? "Yes" : "No");
        return json;
    }

    function tokenURI(uint256 tokenId)
        public
        view
        override
        returns (string memory)
    {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

        string memory json = generateJSON(tokenId);

        return string.concat("data:application/json;base64,", Base64.encode(bytes(json)));
    }

    function setMintPrice(uint256 price) external onlyOwner {
        MINT_PRICE = price;
    }

    /* 
    Force fee collecting on-chain
    override the ERC721 transfer and approval methods (modifiers are overridable as needed)
    Source: https://github.com/ProjectOpenSea/operator-filter-registry
    */
    function setApprovalForAll(address operator, bool approved)
        public
        override
        onlyAllowedOperatorApproval(operator)
    {
        super.setApprovalForAll(operator, approved);
    }

    function approve(address operator, uint256 tokenId)
        public
        payable
        override
        onlyAllowedOperatorApproval(operator)
    {
        super.approve(operator, tokenId);
    }

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

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

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

    /* 
    Pause NFT
    Helper functions for pausing transfers (including sales) of NFTs
    */
    function pause() public onlyOwner {
        _pause();
    }

    function unpause() public onlyOwner {
        _unpause();
    }

    function _beforeTokenTransfers(
        address from,
        address to,
        uint256 tokenId,
        uint256 batchSize
    ) internal override whenNotPaused {
        super._beforeTokenTransfers(from, to, tokenId, batchSize);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"MintERC2309QuantityExceedsLimit","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[{"internalType":"address","name":"operator","type":"address"}],"name":"OperatorNotAllowed","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"OwnershipNotInitializedForExtraData","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"fromTokenId","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"toTokenId","type":"uint256"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"}],"name":"ConsecutiveTransfer","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":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"BURN_OPEN","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"COLLECTION_SIZE","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINT_END_TIME","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINT_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MINT_START_TIME","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OPERATOR_FILTER_REGISTRY","outputs":[{"internalType":"contract IOperatorFilterRegistry","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId1","type":"uint256"},{"internalType":"uint256","name":"tokenId2","type":"uint256"},{"internalType":"uint256","name":"tokenId3","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burnStolen","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"closeBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"devMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"downloadHTML","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"endMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"generateHTML","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"generateOrbURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getOwnershipData","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"},{"internalType":"uint24","name":"extraData","type":"uint24"}],"internalType":"struct IERC721A.TokenOwnership","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"initialMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"isColored","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"numberMinted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"openBurn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"endTimestampSeconds","type":"uint256"}],"name":"setEndTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"price","type":"uint256"}],"name":"setMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setTokenPreviewBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"startTimestampSeconds","type":"uint256"}],"name":"startMintAt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"sourceCode","type":"string"}],"name":"uploadHTML","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"withdrawMoney","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60806040526000600a556000600b556618838370f34000600c55612710600d60006101000a81548161ffff021916908361ffff1602179055506000600d60026101000a81548160ff0219169083151502179055506040518060600160405280603581526020016200568860359139600e90816200007d919062000731565b50604051806111c0016040528061119a8152602001620056bd61119a9139600f9081620000ab919062000731565b506040518060c00160405280608b8152602001620055fd608b913960109081620000d6919062000731565b50348015620000e457600080fd5b50733cc6cdda760b79bafa08df41ecfa224f810dceb660016040518060400160405280600981526020017f4368696c6c4f72627300000000000000000000000000000000000000000000008152506040518060400160405280600981526020017f4348494c4c4f5242530000000000000000000000000000000000000000000000815250816002908162000179919062000731565b5080600390816200018b919062000731565b506200019c620003e460201b60201c565b6000819055505050620001c4620001b8620003e960201b60201c565b620003f160201b60201c565b6000600860146101000a81548160ff021916908315150217905550600160098190555060006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115620003dc578015620002a2576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16637d3e3dbe30846040518363ffffffff1660e01b8152600401620002689291906200085d565b600060405180830381600087803b1580156200028357600080fd5b505af115801562000298573d6000803e3d6000fd5b50505050620003db565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16146200035c576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663a0af290330846040518363ffffffff1660e01b8152600401620003229291906200085d565b600060405180830381600087803b1580156200033d57600080fd5b505af115801562000352573d6000803e3d6000fd5b50505050620003da565b6daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff16634420e486306040518263ffffffff1660e01b8152600401620003a591906200088a565b600060405180830381600087803b158015620003c057600080fd5b505af1158015620003d5573d6000803e3d6000fd5b505050505b5b5b5050620008a7565b600090565b600033905090565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600081519050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b600060028204905060018216806200053957607f821691505b6020821081036200054f576200054e620004f1565b5b50919050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b600060088302620005b97fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff826200057a565b620005c586836200057a565b95508019841693508086168417925050509392505050565b6000819050919050565b6000819050919050565b6000620006126200060c6200060684620005dd565b620005e7565b620005dd565b9050919050565b6000819050919050565b6200062e83620005f1565b620006466200063d8262000619565b84845462000587565b825550505050565b600090565b6200065d6200064e565b6200066a81848462000623565b505050565b5b8181101562000692576200068660008262000653565b60018101905062000670565b5050565b601f821115620006e157620006ab8162000555565b620006b6846200056a565b81016020851015620006c6578190505b620006de620006d5856200056a565b8301826200066f565b50505b505050565b600082821c905092915050565b60006200070660001984600802620006e6565b1980831691505092915050565b6000620007218383620006f3565b9150826002028217905092915050565b6200073c82620004b7565b67ffffffffffffffff811115620007585762000757620004c2565b5b62000764825462000520565b6200077182828562000696565b600060209050601f831160018114620007a9576000841562000794578287015190505b620007a0858262000713565b86555062000810565b601f198416620007b98662000555565b60005b82811015620007e357848901518255600182019150602085019450602081019050620007bc565b86831015620008035784890151620007ff601f891682620006f3565b8355505b6001600288020188555050505b505050505050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000620008458262000818565b9050919050565b620008578162000838565b82525050565b60006040820190506200087460008301856200084c565b6200088360208301846200084c565b9392505050565b6000602082019050620008a160008301846200084c565b92915050565b614d4680620008b76000396000f3fe6080604052600436106102885760003560e01c80638456cb591161015a578063c002d23d116100c1578063cfcf61a41161007a578063cfcf61a4146108f3578063d8258d951461091c578063dc33e68114610947578063e985e9c514610984578063f2fde38b146109c1578063f4a0a528146109ea57610288565b8063c002d23d146107e5578063c5130d3514610810578063c87b56dd14610839578063c8b7d46a14610876578063ccb98ffc1461089f578063cd674e3f146108c857610288565b80639fc5ce2a116101135780639fc5ce2a14610719578063a0712d6814610730578063a22cb4651461074c578063ac44600214610775578063b08d893c1461078c578063b88d4fde146107c957610288565b80638456cb591461060957806384bc8593146106205780638d24d3c21461065d5780638da5cb5b146106865780639231ab2a146106b157806395d89b41146106ee57610288565b806329cbec1a116101fe5780636352211e116101b75780636352211e1461050b5780636fc9b24b1461054857806370a0823114610573578063715018a6146105b05780637c69e207146105c75780637e2ade0c146105de57610288565b806329cbec1a146104545780632be095611461046b5780633f4ba83a1461048257806341f434341461049957806342842e0e146104c45780635c975abb146104e057610288565b8063081812fc11610250578063081812fc14610360578063095ea7b31461039d5780630f34f1c6146103b957806318160ddd146103d05780631c4b8f3f146103fb57806323b872dd1461043857610288565b8063017043a51461028d57806301ffc9a7146102a457806305a10028146102e157806306fdde031461030a57806307bd632214610335575b600080fd5b34801561029957600080fd5b506102a2610a13565b005b3480156102b057600080fd5b506102cb60048036038101906102c69190613615565b610a24565b6040516102d8919061365d565b60405180910390f35b3480156102ed57600080fd5b50610308600480360381019061030391906136ae565b610ab6565b005b34801561031657600080fd5b5061031f610c23565b60405161032c9190613791565b60405180910390f35b34801561034157600080fd5b5061034a610cb5565b60405161035791906137c2565b60405180910390f35b34801561036c57600080fd5b50610387600480360381019061038291906137dd565b610cbb565b604051610394919061384b565b60405180910390f35b6103b760048036038101906103b29190613892565b610d3a565b005b3480156103c557600080fd5b506103ce610d53565b005b3480156103dc57600080fd5b506103e5610d78565b6040516103f291906137c2565b60405180910390f35b34801561040757600080fd5b50610422600480360381019061041d91906137dd565b610d8f565b60405161042f9190613791565b60405180910390f35b610452600480360381019061044d91906138d2565b610dc0565b005b34801561046057600080fd5b50610469610e0f565b005b34801561047757600080fd5b50610480610e34565b005b34801561048e57600080fd5b50610497610e47565b005b3480156104a557600080fd5b506104ae610e59565b6040516104bb9190613984565b60405180910390f35b6104de60048036038101906104d991906138d2565b610e6b565b005b3480156104ec57600080fd5b506104f5610eba565b604051610502919061365d565b60405180910390f35b34801561051757600080fd5b50610532600480360381019061052d91906137dd565b610ed1565b60405161053f919061384b565b60405180910390f35b34801561055457600080fd5b5061055d610ee3565b60405161056a9190613791565b60405180910390f35b34801561057f57600080fd5b5061059a6004803603810190610595919061399f565b610f7d565b6040516105a791906137c2565b60405180910390f35b3480156105bc57600080fd5b506105c5611035565b005b3480156105d357600080fd5b506105dc611049565b005b3480156105ea57600080fd5b506105f36110cd565b60405161060091906137c2565b60405180910390f35b34801561061557600080fd5b5061061e6110d3565b005b34801561062c57600080fd5b50610647600480360381019061064291906137dd565b6110e5565b6040516106549190613791565b60405180910390f35b34801561066957600080fd5b50610684600480360381019061067f91906137dd565b611289565b005b34801561069257600080fd5b5061069b61129f565b6040516106a8919061384b565b60405180910390f35b3480156106bd57600080fd5b506106d860048036038101906106d391906137dd565b6112c9565b6040516106e59190613a80565b60405180910390f35b3480156106fa57600080fd5b506107036112e1565b6040516107109190613791565b60405180910390f35b34801561072557600080fd5b5061072e611373565b005b61074a600480360381019061074591906137dd565b61138e565b005b34801561075857600080fd5b50610773600480360381019061076e9190613ac7565b6114dc565b005b34801561078157600080fd5b5061078a6114f5565b005b34801561079857600080fd5b506107b360048036038101906107ae91906137dd565b6115bc565b6040516107c0919061365d565b60405180910390f35b6107e360048036038101906107de9190613c3c565b6115e6565b005b3480156107f157600080fd5b506107fa611637565b60405161080791906137c2565b60405180910390f35b34801561081c57600080fd5b5061083760048036038101906108329190613d1f565b61163d565b005b34801561084557600080fd5b50610860600480360381019061085b91906137dd565b61165b565b60405161086d9190613791565b60405180910390f35b34801561088257600080fd5b5061089d600480360381019061089891906137dd565b6116d9565b005b3480156108ab57600080fd5b506108c660048036038101906108c191906137dd565b611700565b005b3480156108d457600080fd5b506108dd611712565b6040516108ea919061365d565b60405180910390f35b3480156108ff57600080fd5b5061091a60048036038101906109159190613d1f565b611725565b005b34801561092857600080fd5b50610931611743565b60405161093e9190613d89565b60405180910390f35b34801561095357600080fd5b5061096e6004803603810190610969919061399f565b611757565b60405161097b91906137c2565b60405180910390f35b34801561099057600080fd5b506109ab60048036038101906109a69190613da4565b611769565b6040516109b8919061365d565b60405180910390f35b3480156109cd57600080fd5b506109e860048036038101906109e3919061399f565b6117fd565b005b3480156109f657600080fd5b50610a116004803603810190610a0c91906137dd565b611880565b005b610a1b611892565b42600b81905550565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610a7f57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610aaf5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b600d60029054906101000a900460ff16610b05576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610afc90613e30565b60405180910390fd5b610b10836001611910565b610b1b826001611910565b6011600082815260200190815260200160002060009054906101000a900460ff1615610b7c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b7390613ec2565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16610b9c82610ed1565b73ffffffffffffffffffffffffffffffffffffffff1614610bf2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610be990613f54565b60405180910390fd5b60016011600083815260200190815260200160002060006101000a81548160ff021916908315150217905550505050565b606060028054610c3290613fa3565b80601f0160208091040260200160405190810160405280929190818152602001828054610c5e90613fa3565b8015610cab5780601f10610c8057610100808354040283529160200191610cab565b820191906000526020600020905b815481529060010190602001808311610c8e57829003601f168201915b5050505050905090565b600b5481565b6000610cc682611b62565b610cfc576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b81610d4481611bc1565b610d4e8383611cbe565b505050565b610d5b611892565b6000600d60026101000a81548160ff021916908315150217905550565b6000610d82611e02565b6001546000540303905090565b6060610d9a82611e07565b604051602001610daa9190614036565b6040516020818303038152906040529050919050565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610dfe57610dfd33611bc1565b5b610e09848484611e21565b50505050565b610e17611892565b6001600d60026101000a81548160ff021916908315150217905550565b610e3c611892565b610e45426116d9565b565b610e4f611892565b610e57612143565b565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610ea957610ea833611bc1565b5b610eb48484846121a6565b50505050565b6000600860149054906101000a900460ff16905090565b6000610edc826121c6565b9050919050565b6060610eed611892565b600f8054610efa90613fa3565b80601f0160208091040260200160405190810160405280929190818152602001828054610f2690613fa3565b8015610f735780601f10610f4857610100808354040283529160200191610f73565b820191906000526020600020905b815481529060010190602001808311610f5657829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610fe4576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b61103d611892565b6110476000612292565b565b611051611892565b600060329050600d60009054906101000a900461ffff1661ffff1681611075610d78565b61107f919061408b565b11156110c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b790614131565b60405180910390fd5b6110ca3382612358565b50565b600a5481565b6110db611892565b6110e3612513565b565b606060006111bb600f80546110f990613fa3565b80601f016020809104026020016040519081016040528092919081815260200182805461112590613fa3565b80156111725780601f1061114757610100808354040283529160200191611172565b820191906000526020600020905b81548152906001019060200180831161115557829003601f168201915b50505050506040518060400160405280601381526020017f25544f5245504c4143452e544f4b454e494425000000000000000000000000008152506111b686612576565b61279d565b905060006111c8846115bc565b611207576040518060400160405280600581526020017f66616c736500000000000000000000000000000000000000000000000000000081525061123e565b6040518060400160405280600481526020017f74727565000000000000000000000000000000000000000000000000000000008152505b9050611280826040518060400160405280601581526020017f25544f5245504c4143452e4953434f4c4f5245442500000000000000000000008152508361279d565b92505050919050565b611291611892565b61129c816000611910565b50565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6112d161355a565b6112da82612930565b9050919050565b6060600380546112f090613fa3565b80601f016020809104026020016040519081016040528092919081815260200182805461131c90613fa3565b80156113695780601f1061133e57610100808354040283529160200191611369565b820191906000526020600020905b81548152906001019060200180831161134c57829003601f168201915b5050505050905090565b61137b611892565b60006001905061138b3382612358565b50565b600d60009054906101000a900461ffff1661ffff16816113ac610d78565b6113b6919061408b565b11156113f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ee90614131565b60405180910390fd5b42600a541115801561140c57506000600a5414155b61144b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611442906141e9565b60405180910390fd5b42600b541161148f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611486906142a1565b60405180910390fd5b60008061149b33611757565b146114a75760006114ab565b600c545b82600c546114b991906142c1565b6114c39190614303565b90506114ce81612950565b6114d83383612358565b5050565b816114e681611bc1565b6114f083836129f1565b505050565b6114fd611892565b611505612afc565b60003373ffffffffffffffffffffffffffffffffffffffff164760405161152b90614368565b60006040518083038185875af1925050503d8060008114611568576040519150601f19603f3d011682016040523d82523d6000602084013e61156d565b606091505b50509050806115b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115a8906143c9565b60405180910390fd5b506115ba612b4b565b565b60006011600083815260200190815260200160002060009054906101000a900460ff169050919050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146116245761162333611bc1565b5b61163085858585612b55565b5050505050565b600c5481565b611645611892565b8181600f9182611656929190614596565b505050565b606061166682611b62565b61169c576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006116a783612bc8565b90506116b281612e4a565b6040516020016116c2919061468c565b604051602081830303815290604052915050919050565b6116e1611892565b80600a8190555062015180816116f7919061408b565b600b8190555050565b611708611892565b80600b8190555050565b600d60029054906101000a900460ff1681565b61172d611892565b8181600e918261173e929190614596565b505050565b600d60009054906101000a900461ffff1681565b600061176282612fad565b9050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611805611892565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611874576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186b90614724565b60405180910390fd5b61187d81612292565b50565b611888611892565b80600c8190555050565b61189a613004565b73ffffffffffffffffffffffffffffffffffffffff166118b861129f565b73ffffffffffffffffffffffffffffffffffffffff161461190e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161190590614790565b60405180910390fd5b565b600061191b836121c6565b9050600081905060008061192e8661300c565b9150915084156119975761194a8184611945613033565b61303b565b6119965761195f8361195a613033565b611769565b611995576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b6119a583600088600161307f565b80156119b057600082555b600160806001901b03600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550611a5883611a1585600088613099565b7c02000000000000000000000000000000000000000000000000000000007c010000000000000000000000000000000000000000000000000000000017176130c1565b600460008881526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000851603611ade5760006001870190506000600460008381526020019081526020016000205403611adc576000548114611adb578460046000838152602001908152602001600020819055505b5b505b85600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611b488360008860016130ec565b600160008154809291906001019190505550505050505050565b600081611b6d611e02565b11158015611b7c575060005482105b8015611bba575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611cbb576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401611c389291906147b0565b602060405180830381865afa158015611c55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c7991906147ee565b611cba57806040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401611cb1919061384b565b60405180910390fd5b5b50565b6000611cc982610ed1565b90508073ffffffffffffffffffffffffffffffffffffffff16611cea613033565b73ffffffffffffffffffffffffffffffffffffffff1614611d4d57611d1681611d11613033565b611769565b611d4c576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600090565b6060611e1a611e15836110e5565b612e4a565b9050919050565b6000611e2c826121c6565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611e93576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080611e9f8461300c565b91509150611eb58187611eb0613033565b61303b565b611f0157611eca86611ec5613033565b611769565b611f00576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611f67576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f74868686600161307f565b8015611f7f57600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001019190508190555061204d85612029888887613099565b7c0200000000000000000000000000000000000000000000000000000000176130c1565b600460008681526020019081526020016000208190555060007c02000000000000000000000000000000000000000000000000000000008416036120d357600060018501905060006004600083815260200190815260200160002054036120d15760005481146120d0578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461213b86868660016130ec565b505050505050565b61214b6130f2565b6000600860146101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61218f613004565b60405161219c919061384b565b60405180910390a1565b6121c1838383604051806020016040528060008152506115e6565b505050565b600080829050806121d5611e02565b1161225b5760005481101561225a5760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603612258575b6000810361224e576004600083600190039350838152602001908152602001600020549050612224565b809250505061228d565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008054905060008203612398576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123a5600084838561307f565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061241c8361240d6000866000613099565b6124168561313b565b176130c1565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b8181146124bd57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050612482565b50600082036124f8576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600081905550505061250e60008483856130ec565b505050565b61251b61314b565b6001600860146101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861255f613004565b60405161256c919061384b565b60405180910390a1565b6060600082036125bd576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612798565b60006064905060008167ffffffffffffffff8111156125df576125de613b11565b5b6040519080825280601f01601f1916602001820160405280156126115781602001600182028036833780820191505090505b50905060005b600085146126a3576000600a8661262e919061484a565b9050600a8661263d919061487b565b955080603061264c919061408b565b60f81b83838061265b906148ac565b94508151811061266e5761266d6148f4565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050612617565b60008167ffffffffffffffff8111156126bf576126be613b11565b5b6040519080825280601f01601f1916602001820160405280156126f15781602001600182028036833780820191505090505b50905060005b8281101561278957836001828561270e9190614303565b6127189190614303565b81518110612729576127286148f4565b5b602001015160f81c60f81b828281518110612747576127466148f4565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508080612781906148ac565b9150506126f7565b50600081905080955050505050505b919050565b6060600084905060008490508151815111156127bd578592505050612929565b60008060005b835185516127d19190614303565b81116128bd5760006001905060005b8551811015612895578581815181106127fc576127fb6148f4565b5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916878285612836919061408b565b81518110612847576128466148f4565b5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146128825760009150612895565b808061288d906148ac565b9150506127e0565b5080156128a95760019350819250506128bd565b5080806128b5906148ac565b9150506127c3565b5081156129215760006128d289600084613195565b905060006128ee8a8651856128e7919061408b565b8851613195565b905081888260405160200161290593929190614923565b6040516020818303038152906040529650505050505050612929565b879450505050505b9392505050565b61293861355a565b612949612944836121c6565b613291565b9050919050565b80341015612993576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161298a906149a0565b60405180910390fd5b803411156129ee573373ffffffffffffffffffffffffffffffffffffffff166108fc82346129c19190614303565b9081150290604051600060405180830381858888f193505050501580156129ec573d6000803e3d6000fd5b505b50565b80600760006129fe613033565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612aab613033565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612af0919061365d565b60405180910390a35050565b600260095403612b41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b3890614a0c565b60405180910390fd5b6002600981905550565b6001600981905550565b612b60848484610dc0565b60008373ffffffffffffffffffffffffffffffffffffffff163b14612bc257612b8b84848484613347565b612bc1576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b6060600060108054612bd990613fa3565b80601f0160208091040260200160405190810160405280929190818152602001828054612c0590613fa3565b8015612c525780601f10612c2757610100808354040283529160200191612c52565b820191906000526020600020905b815481529060010190602001808311612c3557829003601f168201915b50505050509050612ca1816040518060400160405280600981526020017f25544f4b454e4944250000000000000000000000000000000000000000000000815250612c9c86612576565b61279d565b9050612ceb816040518060400160405280600981526020017f2550524556494557250000000000000000000000000000000000000000000000815250612ce686613497565b61279d565b9050612d35816040518060400160405280600881526020017f254f524255524925000000000000000000000000000000000000000000000000815250612d3086610d8f565b61279d565b9050612d7f816040518060400160405280600881526020017f254f524255524925000000000000000000000000000000000000000000000000815250612d7a86610d8f565b61279d565b9050612e3f816040518060400160405280600a81526020017f25434f4c4f5246554c2500000000000000000000000000000000000000000000815250612dc4866115bc565b612e03576040518060400160405280600281526020017f4e6f000000000000000000000000000000000000000000000000000000000000815250612e3a565b6040518060400160405280600381526020017f59657300000000000000000000000000000000000000000000000000000000008152505b61279d565b905080915050919050565b60606000825103612e6c57604051806020016040528060008152509050612fa8565b6000604051806060016040528060408152602001614cd16040913990506000600360028551612e9b919061408b565b612ea5919061487b565b6004612eb191906142c1565b67ffffffffffffffff811115612eca57612ec9613b11565b5b6040519080825280601f01601f191660200182016040528015612efc5781602001600182028036833780820191505090505b509050600182016020820185865187015b80821015612f68576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845360018401935050612f0d565b5050600386510660018114612f845760028114612f9757612f9f565b603d6001830353603d6002830353612f9f565b603d60018303535b50505080925050505b919050565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b600033905090565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b61308761314b565b6130938484848461354b565b50505050565b60008060e883901c905060e86130b0868684613551565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6130fa610eba565b613139576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161313090614a78565b60405180910390fd5b565b60006001821460e11b9050919050565b613153610eba565b15613193576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161318a90614ae4565b60405180910390fd5b565b60606000849050600084846131aa9190614303565b67ffffffffffffffff8111156131c3576131c2613b11565b5b6040519080825280601f01601f1916602001820160405280156131f55781602001600182028036833780820191505090505b50905060008590505b8481101561328457828181518110613219576132186148f4565b5b602001015160f81c60f81b8287836132319190614303565b81518110613242576132416148f4565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350808061327c906148ac565b9150506131fe565b5080925050509392505050565b61329961355a565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c01000000000000000000000000000000000000000000000000000000008316141581604001901515908115158152505060e882901c816060019062ffffff16908162ffffff1681525050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261336d613033565b8786866040518563ffffffff1660e01b815260040161338f9493929190614b59565b6020604051808303816000875af19250505080156133cb57506040513d601f19601f820116820180604052508101906133c89190614bba565b60015b613444573d80600081146133fb576040519150601f19603f3d011682016040523d82523d6000602084013e613400565b606091505b50600081510361343c576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6060600e6134a4836115bc565b6134e3576040518060400160405280600f81526020017f2f626c61636b416e6457686974652f000000000000000000000000000000000081525061351a565b6040518060400160405280600a81526020017f2f636f6c6f7266756c2f000000000000000000000000000000000000000000008152505b61352384612576565b60405160200161353593929190614c90565b6040516020818303038152906040529050919050565b50505050565b60009392505050565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff168152602001600015158152602001600062ffffff1681525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6135f2816135bd565b81146135fd57600080fd5b50565b60008135905061360f816135e9565b92915050565b60006020828403121561362b5761362a6135b3565b5b600061363984828501613600565b91505092915050565b60008115159050919050565b61365781613642565b82525050565b6000602082019050613672600083018461364e565b92915050565b6000819050919050565b61368b81613678565b811461369657600080fd5b50565b6000813590506136a881613682565b92915050565b6000806000606084860312156136c7576136c66135b3565b5b60006136d586828701613699565b93505060206136e686828701613699565b92505060406136f786828701613699565b9150509250925092565b600081519050919050565b600082825260208201905092915050565b60005b8381101561373b578082015181840152602081019050613720565b60008484015250505050565b6000601f19601f8301169050919050565b600061376382613701565b61376d818561370c565b935061377d81856020860161371d565b61378681613747565b840191505092915050565b600060208201905081810360008301526137ab8184613758565b905092915050565b6137bc81613678565b82525050565b60006020820190506137d760008301846137b3565b92915050565b6000602082840312156137f3576137f26135b3565b5b600061380184828501613699565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006138358261380a565b9050919050565b6138458161382a565b82525050565b6000602082019050613860600083018461383c565b92915050565b61386f8161382a565b811461387a57600080fd5b50565b60008135905061388c81613866565b92915050565b600080604083850312156138a9576138a86135b3565b5b60006138b78582860161387d565b92505060206138c885828601613699565b9150509250929050565b6000806000606084860312156138eb576138ea6135b3565b5b60006138f98682870161387d565b935050602061390a8682870161387d565b925050604061391b86828701613699565b9150509250925092565b6000819050919050565b600061394a6139456139408461380a565b613925565b61380a565b9050919050565b600061395c8261392f565b9050919050565b600061396e82613951565b9050919050565b61397e81613963565b82525050565b60006020820190506139996000830184613975565b92915050565b6000602082840312156139b5576139b46135b3565b5b60006139c38482850161387d565b91505092915050565b6139d58161382a565b82525050565b600067ffffffffffffffff82169050919050565b6139f8816139db565b82525050565b613a0781613642565b82525050565b600062ffffff82169050919050565b613a2581613a0d565b82525050565b608082016000820151613a4160008501826139cc565b506020820151613a5460208501826139ef565b506040820151613a6760408501826139fe565b506060820151613a7a6060850182613a1c565b50505050565b6000608082019050613a956000830184613a2b565b92915050565b613aa481613642565b8114613aaf57600080fd5b50565b600081359050613ac181613a9b565b92915050565b60008060408385031215613ade57613add6135b3565b5b6000613aec8582860161387d565b9250506020613afd85828601613ab2565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613b4982613747565b810181811067ffffffffffffffff82111715613b6857613b67613b11565b5b80604052505050565b6000613b7b6135a9565b9050613b878282613b40565b919050565b600067ffffffffffffffff821115613ba757613ba6613b11565b5b613bb082613747565b9050602081019050919050565b82818337600083830152505050565b6000613bdf613bda84613b8c565b613b71565b905082815260208101848484011115613bfb57613bfa613b0c565b5b613c06848285613bbd565b509392505050565b600082601f830112613c2357613c22613b07565b5b8135613c33848260208601613bcc565b91505092915050565b60008060008060808587031215613c5657613c556135b3565b5b6000613c648782880161387d565b9450506020613c758782880161387d565b9350506040613c8687828801613699565b925050606085013567ffffffffffffffff811115613ca757613ca66135b8565b5b613cb387828801613c0e565b91505092959194509250565b600080fd5b600080fd5b60008083601f840112613cdf57613cde613b07565b5b8235905067ffffffffffffffff811115613cfc57613cfb613cbf565b5b602083019150836001820283011115613d1857613d17613cc4565b5b9250929050565b60008060208385031215613d3657613d356135b3565b5b600083013567ffffffffffffffff811115613d5457613d536135b8565b5b613d6085828601613cc9565b92509250509250929050565b600061ffff82169050919050565b613d8381613d6c565b82525050565b6000602082019050613d9e6000830184613d7a565b92915050565b60008060408385031215613dbb57613dba6135b3565b5b6000613dc98582860161387d565b9250506020613dda8582860161387d565b9150509250929050565b7f4275726e2069732063757272656e746c79207061757365642e00000000000000600082015250565b6000613e1a60198361370c565b9150613e2582613de4565b602082019050919050565b60006020820190508181036000830152613e4981613e0d565b9050919050565b7f54686520746869726420746f6b656e20697320616c726561647920636f6c6f7260008201527f65642e0000000000000000000000000000000000000000000000000000000000602082015250565b6000613eac60238361370c565b9150613eb782613e50565b604082019050919050565b60006020820190508181036000830152613edb81613e9f565b9050919050565b7f596f75206d75737420626520746865206f776e6572206f66207468652074686960008201527f726420746f6b656e2e0000000000000000000000000000000000000000000000602082015250565b6000613f3e60298361370c565b9150613f4982613ee2565b604082019050919050565b60006020820190508181036000830152613f6d81613f31565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613fbb57607f821691505b602082108103613fce57613fcd613f74565b5b50919050565b7f646174613a746578742f68746d6c3b6261736536342c00000000000000000000815250565b600081905092915050565b600061401082613701565b61401a8185613ffa565b935061402a81856020860161371d565b80840191505092915050565b600061404182613fd4565b6016820191506140518284614005565b915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061409682613678565b91506140a183613678565b92508282019050808211156140b9576140b861405c565b5b92915050565b7f4e6f7420656e6f7567682072656d61696e696e67204e46547320746f2073757060008201527f706f72742064657369726564206d696e7420616d6f756e742e00000000000000602082015250565b600061411b60398361370c565b9150614126826140bf565b604082019050919050565b6000602082019050818103600083015261414a8161410e565b9050919050565b7f5075626c6963206d696e74206973206e6f742073746172746564207965742e2060008201527f506c6561736520636865636b206261636b206c6174657220616e6420666f6c6c60208201527f6f77207573206f6e20747769747465723a20406368696c6c6f72627300000000604082015250565b60006141d3605c8361370c565b91506141de82614151565b606082019050919050565b60006020820190508181036000830152614202816141c6565b9050919050565b7f5075626c6963206d696e7420697320636c6f7365642e20506c6561736520636860008201527f65636b206261636b206c6174657220616e6420666f6c6c6f77207573206f6e2060208201527f747769747465723a20406368696c6c6f72627300000000000000000000000000604082015250565b600061428b60538361370c565b915061429682614209565b606082019050919050565b600060208201905081810360008301526142ba8161427e565b9050919050565b60006142cc82613678565b91506142d783613678565b92508282026142e581613678565b915082820484148315176142fc576142fb61405c565b5b5092915050565b600061430e82613678565b915061431983613678565b92508282039050818111156143315761433061405c565b5b92915050565b600081905092915050565b50565b6000614352600083614337565b915061435d82614342565b600082019050919050565b600061437382614345565b9150819050919050565b7f5472616e73666572206661696c65642e00000000000000000000000000000000600082015250565b60006143b360108361370c565b91506143be8261437d565b602082019050919050565b600060208201905081810360008301526143e2816143a6565b9050919050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026144567fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614419565b6144608683614419565b95508019841693508086168417925050509392505050565b600061449361448e61448984613678565b613925565b613678565b9050919050565b6000819050919050565b6144ad83614478565b6144c16144b98261449a565b848454614426565b825550505050565b600090565b6144d66144c9565b6144e18184846144a4565b505050565b5b81811015614505576144fa6000826144ce565b6001810190506144e7565b5050565b601f82111561454a5761451b816143f4565b61452484614409565b81016020851015614533578190505b61454761453f85614409565b8301826144e6565b50505b505050565b600082821c905092915050565b600061456d6000198460080261454f565b1980831691505092915050565b6000614586838361455c565b9150826002028217905092915050565b6145a083836143e9565b67ffffffffffffffff8111156145b9576145b8613b11565b5b6145c38254613fa3565b6145ce828285614509565b6000601f8311600181146145fd57600084156145eb578287013590505b6145f5858261457a565b86555061465d565b601f19841661460b866143f4565b60005b828110156146335784890135825560018201915060208501945060208101905061460e565b86831015614650578489013561464c601f89168261455c565b8355505b6001600288020188555050505b50505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000815250565b600061469782614666565b601d820191506146a78284614005565b915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061470e60268361370c565b9150614719826146b2565b604082019050919050565b6000602082019050818103600083015261473d81614701565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061477a60208361370c565b915061478582614744565b602082019050919050565b600060208201905081810360008301526147a98161476d565b9050919050565b60006040820190506147c5600083018561383c565b6147d2602083018461383c565b9392505050565b6000815190506147e881613a9b565b92915050565b600060208284031215614804576148036135b3565b5b6000614812848285016147d9565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061485582613678565b915061486083613678565b9250826148705761486f61481b565b5b828206905092915050565b600061488682613678565b915061489183613678565b9250826148a1576148a061481b565b5b828204905092915050565b60006148b782613678565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036148e9576148e861405c565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061492f8286614005565b915061493b8285614005565b91506149478284614005565b9150819050949350505050565b7f4e65656420746f2073656e64206d6f7265204554482e00000000000000000000600082015250565b600061498a60168361370c565b915061499582614954565b602082019050919050565b600060208201905081810360008301526149b98161497d565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006149f6601f8361370c565b9150614a01826149c0565b602082019050919050565b60006020820190508181036000830152614a25816149e9565b9050919050565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b6000614a6260148361370c565b9150614a6d82614a2c565b602082019050919050565b60006020820190508181036000830152614a9181614a55565b9050919050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b6000614ace60108361370c565b9150614ad982614a98565b602082019050919050565b60006020820190508181036000830152614afd81614ac1565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000614b2b82614b04565b614b358185614b0f565b9350614b4581856020860161371d565b614b4e81613747565b840191505092915050565b6000608082019050614b6e600083018761383c565b614b7b602083018661383c565b614b8860408301856137b3565b8181036060830152614b9a8184614b20565b905095945050505050565b600081519050614bb4816135e9565b92915050565b600060208284031215614bd057614bcf6135b3565b5b6000614bde84828501614ba5565b91505092915050565b60008154614bf481613fa3565b614bfe8186613ffa565b94506001821660008114614c195760018114614c2e57614c61565b60ff1983168652811515820286019350614c61565b614c37856143f4565b60005b83811015614c5957815481890152600182019150602081019050614c3a565b838801955050505b50505092915050565b7f2e6a706700000000000000000000000000000000000000000000000000000000815250565b6000614c9c8286614be7565b9150614ca88285614005565b9150614cb48284614005565b9150614cbf82614c6a565b60048201915081905094935050505056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa264697066735822122076202cd8db7b1f25ad212eba6c2b69822772fa1e6b9fbaf3b5201006d6b7dc8264736f6c634300081200337b226e616d65223a224368696c6c4f7262202325544f4b454e494425222c22696d616765223a22255052455649455725222c22616e696d6174696f6e5f75726c223a22254f524255524925222c2261747472696275746573223a5b7b2274726169745f74797065223a22436f6c6f7266756c222c2276616c7565223a2225434f4c4f5246554c25227d5d7d697066733a2f2f516d62574139715463677077336f5a564535414d316965677a437a6736446a71447a45665238727538646544624d3c21646f63747970652068746d6c3e3c7469746c653e4368696c6c4f72623c2f7469746c653e3c736372697074207372633d2268747470733a2f2f63646e6a732e636c6f7564666c6172652e636f6d2f616a61782f6c6962732f7365656472616e646f6d2f332e302e352f7365656472616e646f6d2e6d696e2e6a732220696e746567726974793d227368613531322d2b52753530427a45705a6a6c467a566e6a536d4a66594650466659326853304b6a6c752f497671614a6f7578376d6146356c4a725256554a574a324c6576506c73377264323432474c625745742b7a416f344f5656513d3d222063726f73736f726967696e3d22616e6f6e796d6f7573223e3c2f7363726970743e3c736372697074207372633d2268747470733a2f2f63646e6a732e636c6f7564666c6172652e636f6d2f616a61782f6c6962732f70352e6a732f312e352e302f70352e6d696e2e6a732220696e746567726974793d227368613531322d574a58566a7165494e5670693558584a326a6e30425343667030793830494b725968373331674c526e6b415339544b63354b4e742f4f664c74752b664375657164576e696f754a3175624d2b56492f68626f37504f513d3d222063726f73736f726967696e3d22616e6f6e796d6f7573223e3c2f7363726970743e3c626f6479207374796c653d226261636b67726f756e643a233030303b70616464696e673a303b6d617267696e3a303b6f766572666c6f773a2068696464656e223e3c7363726970743e2828293d3e7b2275736520737472696374223b66756e6374696f6e206d286d297b72657475726e206d3c3d2e33333f2278223a6d3c3d2e36363f2279223a227a227d6c657420623d6e65772055524c536561726368506172616d732877696e646f772e6c6f636174696f6e2e736561726368292c6c3d622e6765742822746f6b656e496422297c7c28302c3165332c4d6174682e666c6f6f7228313030312a4d6174682e72616e646f6d2829292b30293b6c657420573d2274727565223d3d3d622e6765742822626c61636b416e64576869746522292c743d2225544f5245504c4143452e544f4b454e494425223b742e73746172747357697468282225544f5245504c4143452e22297c7c286c3d74293b6c657420653d2225544f5245504c4143452e4953434f4c4f52454425223b652e73746172747357697468282225544f5245504c4143452e22297c7c28573d2266616c7365223d3d3d652e746f4c6f776572436173652829293b6c6574205a3d6e6577204d6174682e7365656472616e646f6d286c293b6e65772070352828623d3e7b6c6574206c3b66756e6374696f6e207428297b6c6574206d3d5a28293b72657475726e206d3e2e333f3230303a7061727365496e742835302a6d292b327d622e7072656c6f61643d28293d3e7b6c3d622e6c6f61645368616465722822646174613a4066696c652f782d633b6261736536342c59585230636d6c696458526c49485a6c597a4d675956427663326c30615739754f32463064484a70596e56305a5342325a574d7a4947464f62334a7459577737645735705a6d3979625342745958513049485651636d39715a574e306157397554574630636d6c344f33567561575a76636d3067625746304e4342315457396b5a5778576157563354574630636d6c344f33567561575a76636d30675a6d7876595851675a6e4a68625756446233567564447431626d6c6d62334a7449475a736232463049473176646d6c755a314e775a57566b4f33567561575a76636d30675a6d7876595851675a6e4a6c6358566c626d4e354f33567561575a76636d30675a6d7876595851675957317762476c306457526c4f33567561575a76636d30675a6d7876595851675932397564484a686333524f62334a7459577870656d56794f33567561575a76636d30675a6d787659585167596e4a705a326830626d567a63303576636d316862476c365a584937645735705a6d39796253426d624739686443427a6158706c4f33567561575a76636d30675a6d7876595851675932397362334a535957356b57447431626d6c6d62334a7449475a736232463049474e7662473979556d46755a466b37645735705a6d39796253426d624739686443426a62327876636c4a68626d52614f33567561575a76636d3067596d39766243427762334e7064476c76626b3170654756794f33567561575a76636d3067596d39766243427762334e7064476c76626b3176646d56794f335a68636e6c70626d6367646d566a4d794232546d3979625746734f335a68636e6c70626d63675a6d787659585167646b4e76626e527959584e30546d3979625746736158706c636a743259584a356157356e49475a736232463049485a43636d6c6e614852755a584e7a546d3979625746736158706c636a743259584a356157356e49475a736232463049485a4462327876636c4a68626d52594f335a68636e6c70626d63675a6d787659585167646b4e7662473979556d46755a466b37646d467965576c755a79426d62473968644342325132397362334a535957356b576a74325a574d304948427663326c3061573975545739325a584a476457356a4b485a6c597a51676347397a61585270623235575a574d304c43426d624739686443427a64573070494874705a69416f6347397a615852706232354e62335a6c63696b676533427663326c3061573975566d566a4e4335344943733949484e316254743949475673633255676533427663326c3061573975566d566a4e4335354943733949484e3162547439636d563064584a754948427663326c3061573975566d566a4e447439646d39705a43427459576c754b436b6765335a6c597a51676347397a61585270623235575a574d3049443067646d566a4e4368685547397a615852706232347349484e70656d55704f325a736232463049484a68626d525162334e7064476c76626c5a6c597a51675053427762334e7064476c76626b317065475679494438676347397a61585270623235575a574d304c6e67674f69427762334e7064476c76626c5a6c597a51756554746d624739686443426b61584e3062334a30615739754944306763326c754b484a68626d525162334e7064476c76626c5a6c597a51674b69426d636d56786457567559336b674b79426d636d46745a554e766457353049436f67625739326157356e5533426c5a5751704f33427663326c3061573975566d566a4e4341394948427663326c3061573975545739325a584a476457356a4b48427663326c3061573975566d566a4e4377675a476c7a6447397964476c76626941714947464f62334a74595777756543417149474674634778706448566b5a536b37646b3576636d3168624341394947464f62334a7459577737646b4e76626e527959584e30546d3979625746736158706c6369413949474e76626e527959584e30546d3979625746736158706c636a74325132397362334a535957356b5743413949474e7662473979556d46755a466737646b4e7662473979556d46755a466b675053426a62327876636c4a68626d525a4f335a4462327876636c4a68626d5261494430675932397362334a535957356b576a7432516e4a705a326830626d567a63303576636d316862476c365a58496750534269636d6c6e614852755a584e7a546d3979625746736158706c636a746e6246395162334e7064476c766269413949485651636d39715a574e306157397554574630636d6c3449436f67645531765a475673566d6c6c6430316864484a70654341714948427663326c3061573975566d566a4e447439222c22646174613a4066696c652f782d633b6261736536342c63484a6c59326c7a615739754947316c5a476c31625841675a6d787659585137646d467965576c755a7942325a574d7a49485a4f62334a7459577737646d467965576c755a79426d62473968644342325132397564484a686333524f62334a7459577870656d56794f335a68636e6c70626d63675a6d787659585167646b4a796157646f6447356c63334e4f62334a7459577870656d56794f335a68636e6c70626d63675a6d787659585167646b4e7662473979556d46755a466737646d467965576c755a79426d62473968644342325132397362334a535957356b5754743259584a356157356e49475a736232463049485a4462327876636c4a68626d52614f325a7362324630494752706257567563323970626b3170654756794b485a6c597a4d6759584a7959586b7349475a736232463049484a68626d5170494874705a69416f636d46755a434138505341774c6a4d7a4b534237636d563064584a7549474679636d46354c6e67376653426c62484e6c49476c6d494368795957356b49447739494441754e6a5970494874795a585231636d346759584a7959586b7565547439494756736332556765334a6c6448567962694268636e4a68655335364f333139646d39705a43427459576c754b436b6765335a6c597a4d67593239736233496750534232546d39796257467349436f67646b4e76626e527959584e30546d3979625746736158706c6369417249485a43636d6c6e614852755a584e7a546d3979625746736158706c636a746e62463947636d466e5132397362334967505342325a574d304b4752706257567563323970626b3170654756794b474e76624739794c4342325132397362334a535957356b57436b735a476c745a57357a62326c7554576c345a58496f593239736233497349485a4462327876636c4a68626d525a4b53786b6157316c626e4e766157354e6158686c6369686a6232787663697767646b4e7662473979556d46755a466f704c4445754d436b3766513d3d22297d2c622e73657475703d28293d3e7b622e63726561746543616e76617328622e77696e646f7757696474682c622e77696e646f774865696768742c622e574542474c292c622e6e6f5374726f6b6528297d3b636f6e737420653d7428292c633d7428292c613d2e322a5a28292b2e30332c643d32302a5a28292b31302c6e3d5a28292c733d2e32352b2e352a5a28292c763d2e32352b2e352a5a28293b6c657420473d5a28292c673d5a28292c753d5a28293b636f6e737420593d5a28293c3d2e382c6f3d5a28293c3d2e383b6c657420703d312b2e352a5a28293b77696e646f772e6164644576656e744c697374656e65722822776865656c222c286d3d3e7b636f6e737420623d4d6174682e7369676e286d2e64656c746159293b702a3d313d3d3d623f312e323a2e387d29292c573f28673d472c753d47293a6d2847293d3d3d6d28672926266d2867293d3d3d6d287529262628473e3d2e353f472d3d2e33343a472b3d2e3334292c622e647261773d28293d3e7b6c6574206d3d286e65772044617465292e67657454696d6528292f3165333b622e6261636b67726f756e6428222330303022292c622e736861646572286c292c6c2e736574556e69666f726d28226672616d65436f756e74222c622e6672616d65436f756e74292c6c2e736574556e69666f726d28226d6f76696e675370656564222c61292c6c2e736574556e69666f726d28226672657175656e6379222c64292c6c2e736574556e69666f726d2822616d706c6974756465222c6e292c6c2e736574556e69666f726d2822636f6e74726173744e6f726d616c697a6572222c73292c6c2e736574556e69666f726d28226272696768746e6573734e6f726d616c697a6572222c76292c6c2e736574556e69666f726d282273697a65222c70292c6c2e736574556e69666f726d2822636f6c6f7252616e6458222c47292c6c2e736574556e69666f726d2822636f6c6f7252616e6459222c67292c6c2e736574556e69666f726d2822636f6c6f7252616e645a222c75292c6c2e736574556e69666f726d2822706f736974696f6e4d69786572222c59292c6c2e736574556e69666f726d2822706f736974696f6e4d6f766572222c6f292c622e726f7461746558282e362a6d292c622e726f7461746559282e332a6d292c622e73706865726528622e77696474682f352c652c63297d2c622e77696e646f77526573697a65643d28293d3e7b622e726573697a6543616e76617328622e77696e646f7757696474682c622e77696e646f77486569676874297d7d29297d2928293b3c2f7363726970743e3c2f626f64793e

Deployed Bytecode

0x6080604052600436106102885760003560e01c80638456cb591161015a578063c002d23d116100c1578063cfcf61a41161007a578063cfcf61a4146108f3578063d8258d951461091c578063dc33e68114610947578063e985e9c514610984578063f2fde38b146109c1578063f4a0a528146109ea57610288565b8063c002d23d146107e5578063c5130d3514610810578063c87b56dd14610839578063c8b7d46a14610876578063ccb98ffc1461089f578063cd674e3f146108c857610288565b80639fc5ce2a116101135780639fc5ce2a14610719578063a0712d6814610730578063a22cb4651461074c578063ac44600214610775578063b08d893c1461078c578063b88d4fde146107c957610288565b80638456cb591461060957806384bc8593146106205780638d24d3c21461065d5780638da5cb5b146106865780639231ab2a146106b157806395d89b41146106ee57610288565b806329cbec1a116101fe5780636352211e116101b75780636352211e1461050b5780636fc9b24b1461054857806370a0823114610573578063715018a6146105b05780637c69e207146105c75780637e2ade0c146105de57610288565b806329cbec1a146104545780632be095611461046b5780633f4ba83a1461048257806341f434341461049957806342842e0e146104c45780635c975abb146104e057610288565b8063081812fc11610250578063081812fc14610360578063095ea7b31461039d5780630f34f1c6146103b957806318160ddd146103d05780631c4b8f3f146103fb57806323b872dd1461043857610288565b8063017043a51461028d57806301ffc9a7146102a457806305a10028146102e157806306fdde031461030a57806307bd632214610335575b600080fd5b34801561029957600080fd5b506102a2610a13565b005b3480156102b057600080fd5b506102cb60048036038101906102c69190613615565b610a24565b6040516102d8919061365d565b60405180910390f35b3480156102ed57600080fd5b50610308600480360381019061030391906136ae565b610ab6565b005b34801561031657600080fd5b5061031f610c23565b60405161032c9190613791565b60405180910390f35b34801561034157600080fd5b5061034a610cb5565b60405161035791906137c2565b60405180910390f35b34801561036c57600080fd5b50610387600480360381019061038291906137dd565b610cbb565b604051610394919061384b565b60405180910390f35b6103b760048036038101906103b29190613892565b610d3a565b005b3480156103c557600080fd5b506103ce610d53565b005b3480156103dc57600080fd5b506103e5610d78565b6040516103f291906137c2565b60405180910390f35b34801561040757600080fd5b50610422600480360381019061041d91906137dd565b610d8f565b60405161042f9190613791565b60405180910390f35b610452600480360381019061044d91906138d2565b610dc0565b005b34801561046057600080fd5b50610469610e0f565b005b34801561047757600080fd5b50610480610e34565b005b34801561048e57600080fd5b50610497610e47565b005b3480156104a557600080fd5b506104ae610e59565b6040516104bb9190613984565b60405180910390f35b6104de60048036038101906104d991906138d2565b610e6b565b005b3480156104ec57600080fd5b506104f5610eba565b604051610502919061365d565b60405180910390f35b34801561051757600080fd5b50610532600480360381019061052d91906137dd565b610ed1565b60405161053f919061384b565b60405180910390f35b34801561055457600080fd5b5061055d610ee3565b60405161056a9190613791565b60405180910390f35b34801561057f57600080fd5b5061059a6004803603810190610595919061399f565b610f7d565b6040516105a791906137c2565b60405180910390f35b3480156105bc57600080fd5b506105c5611035565b005b3480156105d357600080fd5b506105dc611049565b005b3480156105ea57600080fd5b506105f36110cd565b60405161060091906137c2565b60405180910390f35b34801561061557600080fd5b5061061e6110d3565b005b34801561062c57600080fd5b50610647600480360381019061064291906137dd565b6110e5565b6040516106549190613791565b60405180910390f35b34801561066957600080fd5b50610684600480360381019061067f91906137dd565b611289565b005b34801561069257600080fd5b5061069b61129f565b6040516106a8919061384b565b60405180910390f35b3480156106bd57600080fd5b506106d860048036038101906106d391906137dd565b6112c9565b6040516106e59190613a80565b60405180910390f35b3480156106fa57600080fd5b506107036112e1565b6040516107109190613791565b60405180910390f35b34801561072557600080fd5b5061072e611373565b005b61074a600480360381019061074591906137dd565b61138e565b005b34801561075857600080fd5b50610773600480360381019061076e9190613ac7565b6114dc565b005b34801561078157600080fd5b5061078a6114f5565b005b34801561079857600080fd5b506107b360048036038101906107ae91906137dd565b6115bc565b6040516107c0919061365d565b60405180910390f35b6107e360048036038101906107de9190613c3c565b6115e6565b005b3480156107f157600080fd5b506107fa611637565b60405161080791906137c2565b60405180910390f35b34801561081c57600080fd5b5061083760048036038101906108329190613d1f565b61163d565b005b34801561084557600080fd5b50610860600480360381019061085b91906137dd565b61165b565b60405161086d9190613791565b60405180910390f35b34801561088257600080fd5b5061089d600480360381019061089891906137dd565b6116d9565b005b3480156108ab57600080fd5b506108c660048036038101906108c191906137dd565b611700565b005b3480156108d457600080fd5b506108dd611712565b6040516108ea919061365d565b60405180910390f35b3480156108ff57600080fd5b5061091a60048036038101906109159190613d1f565b611725565b005b34801561092857600080fd5b50610931611743565b60405161093e9190613d89565b60405180910390f35b34801561095357600080fd5b5061096e6004803603810190610969919061399f565b611757565b60405161097b91906137c2565b60405180910390f35b34801561099057600080fd5b506109ab60048036038101906109a69190613da4565b611769565b6040516109b8919061365d565b60405180910390f35b3480156109cd57600080fd5b506109e860048036038101906109e3919061399f565b6117fd565b005b3480156109f657600080fd5b50610a116004803603810190610a0c91906137dd565b611880565b005b610a1b611892565b42600b81905550565b60006301ffc9a760e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480610a7f57506380ac58cd60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80610aaf5750635b5e139f60e01b827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b9050919050565b600d60029054906101000a900460ff16610b05576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610afc90613e30565b60405180910390fd5b610b10836001611910565b610b1b826001611910565b6011600082815260200190815260200160002060009054906101000a900460ff1615610b7c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b7390613ec2565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff16610b9c82610ed1565b73ffffffffffffffffffffffffffffffffffffffff1614610bf2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610be990613f54565b60405180910390fd5b60016011600083815260200190815260200160002060006101000a81548160ff021916908315150217905550505050565b606060028054610c3290613fa3565b80601f0160208091040260200160405190810160405280929190818152602001828054610c5e90613fa3565b8015610cab5780601f10610c8057610100808354040283529160200191610cab565b820191906000526020600020905b815481529060010190602001808311610c8e57829003601f168201915b5050505050905090565b600b5481565b6000610cc682611b62565b610cfc576040517fcf4700e400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060000160009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b81610d4481611bc1565b610d4e8383611cbe565b505050565b610d5b611892565b6000600d60026101000a81548160ff021916908315150217905550565b6000610d82611e02565b6001546000540303905090565b6060610d9a82611e07565b604051602001610daa9190614036565b6040516020818303038152906040529050919050565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610dfe57610dfd33611bc1565b5b610e09848484611e21565b50505050565b610e17611892565b6001600d60026101000a81548160ff021916908315150217905550565b610e3c611892565b610e45426116d9565b565b610e4f611892565b610e57612143565b565b6daaeb6d7670e522a718067333cd4e81565b823373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614610ea957610ea833611bc1565b5b610eb48484846121a6565b50505050565b6000600860149054906101000a900460ff16905090565b6000610edc826121c6565b9050919050565b6060610eed611892565b600f8054610efa90613fa3565b80601f0160208091040260200160405190810160405280929190818152602001828054610f2690613fa3565b8015610f735780601f10610f4857610100808354040283529160200191610f73565b820191906000526020600020905b815481529060010190602001808311610f5657829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1603610fe4576040517f8f4eb60400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b67ffffffffffffffff600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054169050919050565b61103d611892565b6110476000612292565b565b611051611892565b600060329050600d60009054906101000a900461ffff1661ffff1681611075610d78565b61107f919061408b565b11156110c0576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110b790614131565b60405180910390fd5b6110ca3382612358565b50565b600a5481565b6110db611892565b6110e3612513565b565b606060006111bb600f80546110f990613fa3565b80601f016020809104026020016040519081016040528092919081815260200182805461112590613fa3565b80156111725780601f1061114757610100808354040283529160200191611172565b820191906000526020600020905b81548152906001019060200180831161115557829003601f168201915b50505050506040518060400160405280601381526020017f25544f5245504c4143452e544f4b454e494425000000000000000000000000008152506111b686612576565b61279d565b905060006111c8846115bc565b611207576040518060400160405280600581526020017f66616c736500000000000000000000000000000000000000000000000000000081525061123e565b6040518060400160405280600481526020017f74727565000000000000000000000000000000000000000000000000000000008152505b9050611280826040518060400160405280601581526020017f25544f5245504c4143452e4953434f4c4f5245442500000000000000000000008152508361279d565b92505050919050565b611291611892565b61129c816000611910565b50565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6112d161355a565b6112da82612930565b9050919050565b6060600380546112f090613fa3565b80601f016020809104026020016040519081016040528092919081815260200182805461131c90613fa3565b80156113695780601f1061133e57610100808354040283529160200191611369565b820191906000526020600020905b81548152906001019060200180831161134c57829003601f168201915b5050505050905090565b61137b611892565b60006001905061138b3382612358565b50565b600d60009054906101000a900461ffff1661ffff16816113ac610d78565b6113b6919061408b565b11156113f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ee90614131565b60405180910390fd5b42600a541115801561140c57506000600a5414155b61144b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611442906141e9565b60405180910390fd5b42600b541161148f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611486906142a1565b60405180910390fd5b60008061149b33611757565b146114a75760006114ab565b600c545b82600c546114b991906142c1565b6114c39190614303565b90506114ce81612950565b6114d83383612358565b5050565b816114e681611bc1565b6114f083836129f1565b505050565b6114fd611892565b611505612afc565b60003373ffffffffffffffffffffffffffffffffffffffff164760405161152b90614368565b60006040518083038185875af1925050503d8060008114611568576040519150601f19603f3d011682016040523d82523d6000602084013e61156d565b606091505b50509050806115b1576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115a8906143c9565b60405180910390fd5b506115ba612b4b565b565b60006011600083815260200190815260200160002060009054906101000a900460ff169050919050565b833373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16146116245761162333611bc1565b5b61163085858585612b55565b5050505050565b600c5481565b611645611892565b8181600f9182611656929190614596565b505050565b606061166682611b62565b61169c576040517fa14c4b5000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60006116a783612bc8565b90506116b281612e4a565b6040516020016116c2919061468c565b604051602081830303815290604052915050919050565b6116e1611892565b80600a8190555062015180816116f7919061408b565b600b8190555050565b611708611892565b80600b8190555050565b600d60029054906101000a900460ff1681565b61172d611892565b8181600e918261173e929190614596565b505050565b600d60009054906101000a900461ffff1681565b600061176282612fad565b9050919050565b6000600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611805611892565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1603611874576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161186b90614724565b60405180910390fd5b61187d81612292565b50565b611888611892565b80600c8190555050565b61189a613004565b73ffffffffffffffffffffffffffffffffffffffff166118b861129f565b73ffffffffffffffffffffffffffffffffffffffff161461190e576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161190590614790565b60405180910390fd5b565b600061191b836121c6565b9050600081905060008061192e8661300c565b9150915084156119975761194a8184611945613033565b61303b565b6119965761195f8361195a613033565b611769565b611995576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b5b6119a583600088600161307f565b80156119b057600082555b600160806001901b03600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282540192505081905550611a5883611a1585600088613099565b7c02000000000000000000000000000000000000000000000000000000007c010000000000000000000000000000000000000000000000000000000017176130c1565b600460008881526020019081526020016000208190555060007c0200000000000000000000000000000000000000000000000000000000851603611ade5760006001870190506000600460008381526020019081526020016000205403611adc576000548114611adb578460046000838152602001908152602001600020819055505b5b505b85600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4611b488360008860016130ec565b600160008154809291906001019190505550505050505050565b600081611b6d611e02565b11158015611b7c575060005482105b8015611bba575060007c0100000000000000000000000000000000000000000000000000000000600460008581526020019081526020016000205416145b9050919050565b60006daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff163b1115611cbb576daaeb6d7670e522a718067333cd4e73ffffffffffffffffffffffffffffffffffffffff1663c617113430836040518363ffffffff1660e01b8152600401611c389291906147b0565b602060405180830381865afa158015611c55573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c7991906147ee565b611cba57806040517fede71dcc000000000000000000000000000000000000000000000000000000008152600401611cb1919061384b565b60405180910390fd5b5b50565b6000611cc982610ed1565b90508073ffffffffffffffffffffffffffffffffffffffff16611cea613033565b73ffffffffffffffffffffffffffffffffffffffff1614611d4d57611d1681611d11613033565b611769565b611d4c576040517fcfb3b94200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b826006600084815260200190815260200160002060000160006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550818373ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a4505050565b600090565b6060611e1a611e15836110e5565b612e4a565b9050919050565b6000611e2c826121c6565b90508373ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614611e93576040517fa114810000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600080611e9f8461300c565b91509150611eb58187611eb0613033565b61303b565b611f0157611eca86611ec5613033565b611769565b611f00576040517f59c896be00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b600073ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff1603611f67576040517fea553b3400000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b611f74868686600161307f565b8015611f7f57600082555b600560008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001900391905081905550600560008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600081546001019190508190555061204d85612029888887613099565b7c0200000000000000000000000000000000000000000000000000000000176130c1565b600460008681526020019081526020016000208190555060007c02000000000000000000000000000000000000000000000000000000008416036120d357600060018501905060006004600083815260200190815260200160002054036120d15760005481146120d0578360046000838152602001908152602001600020819055505b5b505b838573ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a461213b86868660016130ec565b505050505050565b61214b6130f2565b6000600860146101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa61218f613004565b60405161219c919061384b565b60405180910390a1565b6121c1838383604051806020016040528060008152506115e6565b505050565b600080829050806121d5611e02565b1161225b5760005481101561225a5760006004600083815260200190815260200160002054905060007c0100000000000000000000000000000000000000000000000000000000821603612258575b6000810361224e576004600083600190039350838152602001908152602001600020549050612224565b809250505061228d565b505b5b6040517fdf2d9b4200000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b919050565b6000600860009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600860006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60008054905060008203612398576040517fb562e8dd00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6123a5600084838561307f565b600160406001901b178202600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254019250508190555061241c8361240d6000866000613099565b6124168561313b565b176130c1565b6004600083815260200190815260200160002081905550600080838301905073ffffffffffffffffffffffffffffffffffffffff85169150828260007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600183015b8181146124bd57808360007fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef600080a4600181019050612482565b50600082036124f8576040517f2e07630000000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b80600081905550505061250e60008483856130ec565b505050565b61251b61314b565b6001600860146101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a25861255f613004565b60405161256c919061384b565b60405180910390a1565b6060600082036125bd576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612798565b60006064905060008167ffffffffffffffff8111156125df576125de613b11565b5b6040519080825280601f01601f1916602001820160405280156126115781602001600182028036833780820191505090505b50905060005b600085146126a3576000600a8661262e919061484a565b9050600a8661263d919061487b565b955080603061264c919061408b565b60f81b83838061265b906148ac565b94508151811061266e5761266d6148f4565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a90535050612617565b60008167ffffffffffffffff8111156126bf576126be613b11565b5b6040519080825280601f01601f1916602001820160405280156126f15781602001600182028036833780820191505090505b50905060005b8281101561278957836001828561270e9190614303565b6127189190614303565b81518110612729576127286148f4565b5b602001015160f81c60f81b828281518110612747576127466148f4565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053508080612781906148ac565b9150506126f7565b50600081905080955050505050505b919050565b6060600084905060008490508151815111156127bd578592505050612929565b60008060005b835185516127d19190614303565b81116128bd5760006001905060005b8551811015612895578581815181106127fc576127fb6148f4565b5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916878285612836919061408b565b81518110612847576128466148f4565b5b602001015160f81c60f81b7effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146128825760009150612895565b808061288d906148ac565b9150506127e0565b5080156128a95760019350819250506128bd565b5080806128b5906148ac565b9150506127c3565b5081156129215760006128d289600084613195565b905060006128ee8a8651856128e7919061408b565b8851613195565b905081888260405160200161290593929190614923565b6040516020818303038152906040529650505050505050612929565b879450505050505b9392505050565b61293861355a565b612949612944836121c6565b613291565b9050919050565b80341015612993576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161298a906149a0565b60405180910390fd5b803411156129ee573373ffffffffffffffffffffffffffffffffffffffff166108fc82346129c19190614303565b9081150290604051600060405180830381858888f193505050501580156129ec573d6000803e3d6000fd5b505b50565b80600760006129fe613033565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff16612aab613033565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3183604051612af0919061365d565b60405180910390a35050565b600260095403612b41576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612b3890614a0c565b60405180910390fd5b6002600981905550565b6001600981905550565b612b60848484610dc0565b60008373ffffffffffffffffffffffffffffffffffffffff163b14612bc257612b8b84848484613347565b612bc1576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b5b50505050565b6060600060108054612bd990613fa3565b80601f0160208091040260200160405190810160405280929190818152602001828054612c0590613fa3565b8015612c525780601f10612c2757610100808354040283529160200191612c52565b820191906000526020600020905b815481529060010190602001808311612c3557829003601f168201915b50505050509050612ca1816040518060400160405280600981526020017f25544f4b454e4944250000000000000000000000000000000000000000000000815250612c9c86612576565b61279d565b9050612ceb816040518060400160405280600981526020017f2550524556494557250000000000000000000000000000000000000000000000815250612ce686613497565b61279d565b9050612d35816040518060400160405280600881526020017f254f524255524925000000000000000000000000000000000000000000000000815250612d3086610d8f565b61279d565b9050612d7f816040518060400160405280600881526020017f254f524255524925000000000000000000000000000000000000000000000000815250612d7a86610d8f565b61279d565b9050612e3f816040518060400160405280600a81526020017f25434f4c4f5246554c2500000000000000000000000000000000000000000000815250612dc4866115bc565b612e03576040518060400160405280600281526020017f4e6f000000000000000000000000000000000000000000000000000000000000815250612e3a565b6040518060400160405280600381526020017f59657300000000000000000000000000000000000000000000000000000000008152505b61279d565b905080915050919050565b60606000825103612e6c57604051806020016040528060008152509050612fa8565b6000604051806060016040528060408152602001614cd16040913990506000600360028551612e9b919061408b565b612ea5919061487b565b6004612eb191906142c1565b67ffffffffffffffff811115612eca57612ec9613b11565b5b6040519080825280601f01601f191660200182016040528015612efc5781602001600182028036833780820191505090505b509050600182016020820185865187015b80821015612f68576003820191508151603f8160121c168501518453600184019350603f81600c1c168501518453600184019350603f8160061c168501518453600184019350603f8116850151845360018401935050612f0d565b5050600386510660018114612f845760028114612f9757612f9f565b603d6001830353603d6002830353612f9f565b603d60018303535b50505080925050505b919050565b600067ffffffffffffffff6040600560008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054901c169050919050565b600033905090565b60008060006006600085815260200190815260200160002090508092508254915050915091565b600033905090565b600073ffffffffffffffffffffffffffffffffffffffff8316925073ffffffffffffffffffffffffffffffffffffffff821691508382148383141790509392505050565b61308761314b565b6130938484848461354b565b50505050565b60008060e883901c905060e86130b0868684613551565b62ffffff16901b9150509392505050565b600073ffffffffffffffffffffffffffffffffffffffff83169250814260a01b178317905092915050565b50505050565b6130fa610eba565b613139576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161313090614a78565b60405180910390fd5b565b60006001821460e11b9050919050565b613153610eba565b15613193576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161318a90614ae4565b60405180910390fd5b565b60606000849050600084846131aa9190614303565b67ffffffffffffffff8111156131c3576131c2613b11565b5b6040519080825280601f01601f1916602001820160405280156131f55781602001600182028036833780820191505090505b50905060008590505b8481101561328457828181518110613219576132186148f4565b5b602001015160f81c60f81b8287836132319190614303565b81518110613242576132416148f4565b5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350808061327c906148ac565b9150506131fe565b5080925050509392505050565b61329961355a565b81816000019073ffffffffffffffffffffffffffffffffffffffff16908173ffffffffffffffffffffffffffffffffffffffff168152505060a082901c816020019067ffffffffffffffff16908167ffffffffffffffff168152505060007c01000000000000000000000000000000000000000000000000000000008316141581604001901515908115158152505060e882901c816060019062ffffff16908162ffffff1681525050919050565b60008373ffffffffffffffffffffffffffffffffffffffff1663150b7a0261336d613033565b8786866040518563ffffffff1660e01b815260040161338f9493929190614b59565b6020604051808303816000875af19250505080156133cb57506040513d601f19601f820116820180604052508101906133c89190614bba565b60015b613444573d80600081146133fb576040519150601f19603f3d011682016040523d82523d6000602084013e613400565b606091505b50600081510361343c576040517fd1a57ed600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050949350505050565b6060600e6134a4836115bc565b6134e3576040518060400160405280600f81526020017f2f626c61636b416e6457686974652f000000000000000000000000000000000081525061351a565b6040518060400160405280600a81526020017f2f636f6c6f7266756c2f000000000000000000000000000000000000000000008152505b61352384612576565b60405160200161353593929190614c90565b6040516020818303038152906040529050919050565b50505050565b60009392505050565b6040518060800160405280600073ffffffffffffffffffffffffffffffffffffffff168152602001600067ffffffffffffffff168152602001600015158152602001600062ffffff1681525090565b6000604051905090565b600080fd5b600080fd5b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b6135f2816135bd565b81146135fd57600080fd5b50565b60008135905061360f816135e9565b92915050565b60006020828403121561362b5761362a6135b3565b5b600061363984828501613600565b91505092915050565b60008115159050919050565b61365781613642565b82525050565b6000602082019050613672600083018461364e565b92915050565b6000819050919050565b61368b81613678565b811461369657600080fd5b50565b6000813590506136a881613682565b92915050565b6000806000606084860312156136c7576136c66135b3565b5b60006136d586828701613699565b93505060206136e686828701613699565b92505060406136f786828701613699565b9150509250925092565b600081519050919050565b600082825260208201905092915050565b60005b8381101561373b578082015181840152602081019050613720565b60008484015250505050565b6000601f19601f8301169050919050565b600061376382613701565b61376d818561370c565b935061377d81856020860161371d565b61378681613747565b840191505092915050565b600060208201905081810360008301526137ab8184613758565b905092915050565b6137bc81613678565b82525050565b60006020820190506137d760008301846137b3565b92915050565b6000602082840312156137f3576137f26135b3565b5b600061380184828501613699565b91505092915050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60006138358261380a565b9050919050565b6138458161382a565b82525050565b6000602082019050613860600083018461383c565b92915050565b61386f8161382a565b811461387a57600080fd5b50565b60008135905061388c81613866565b92915050565b600080604083850312156138a9576138a86135b3565b5b60006138b78582860161387d565b92505060206138c885828601613699565b9150509250929050565b6000806000606084860312156138eb576138ea6135b3565b5b60006138f98682870161387d565b935050602061390a8682870161387d565b925050604061391b86828701613699565b9150509250925092565b6000819050919050565b600061394a6139456139408461380a565b613925565b61380a565b9050919050565b600061395c8261392f565b9050919050565b600061396e82613951565b9050919050565b61397e81613963565b82525050565b60006020820190506139996000830184613975565b92915050565b6000602082840312156139b5576139b46135b3565b5b60006139c38482850161387d565b91505092915050565b6139d58161382a565b82525050565b600067ffffffffffffffff82169050919050565b6139f8816139db565b82525050565b613a0781613642565b82525050565b600062ffffff82169050919050565b613a2581613a0d565b82525050565b608082016000820151613a4160008501826139cc565b506020820151613a5460208501826139ef565b506040820151613a6760408501826139fe565b506060820151613a7a6060850182613a1c565b50505050565b6000608082019050613a956000830184613a2b565b92915050565b613aa481613642565b8114613aaf57600080fd5b50565b600081359050613ac181613a9b565b92915050565b60008060408385031215613ade57613add6135b3565b5b6000613aec8582860161387d565b9250506020613afd85828601613ab2565b9150509250929050565b600080fd5b600080fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b613b4982613747565b810181811067ffffffffffffffff82111715613b6857613b67613b11565b5b80604052505050565b6000613b7b6135a9565b9050613b878282613b40565b919050565b600067ffffffffffffffff821115613ba757613ba6613b11565b5b613bb082613747565b9050602081019050919050565b82818337600083830152505050565b6000613bdf613bda84613b8c565b613b71565b905082815260208101848484011115613bfb57613bfa613b0c565b5b613c06848285613bbd565b509392505050565b600082601f830112613c2357613c22613b07565b5b8135613c33848260208601613bcc565b91505092915050565b60008060008060808587031215613c5657613c556135b3565b5b6000613c648782880161387d565b9450506020613c758782880161387d565b9350506040613c8687828801613699565b925050606085013567ffffffffffffffff811115613ca757613ca66135b8565b5b613cb387828801613c0e565b91505092959194509250565b600080fd5b600080fd5b60008083601f840112613cdf57613cde613b07565b5b8235905067ffffffffffffffff811115613cfc57613cfb613cbf565b5b602083019150836001820283011115613d1857613d17613cc4565b5b9250929050565b60008060208385031215613d3657613d356135b3565b5b600083013567ffffffffffffffff811115613d5457613d536135b8565b5b613d6085828601613cc9565b92509250509250929050565b600061ffff82169050919050565b613d8381613d6c565b82525050565b6000602082019050613d9e6000830184613d7a565b92915050565b60008060408385031215613dbb57613dba6135b3565b5b6000613dc98582860161387d565b9250506020613dda8582860161387d565b9150509250929050565b7f4275726e2069732063757272656e746c79207061757365642e00000000000000600082015250565b6000613e1a60198361370c565b9150613e2582613de4565b602082019050919050565b60006020820190508181036000830152613e4981613e0d565b9050919050565b7f54686520746869726420746f6b656e20697320616c726561647920636f6c6f7260008201527f65642e0000000000000000000000000000000000000000000000000000000000602082015250565b6000613eac60238361370c565b9150613eb782613e50565b604082019050919050565b60006020820190508181036000830152613edb81613e9f565b9050919050565b7f596f75206d75737420626520746865206f776e6572206f66207468652074686960008201527f726420746f6b656e2e0000000000000000000000000000000000000000000000602082015250565b6000613f3e60298361370c565b9150613f4982613ee2565b604082019050919050565b60006020820190508181036000830152613f6d81613f31565b9050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b60006002820490506001821680613fbb57607f821691505b602082108103613fce57613fcd613f74565b5b50919050565b7f646174613a746578742f68746d6c3b6261736536342c00000000000000000000815250565b600081905092915050565b600061401082613701565b61401a8185613ffa565b935061402a81856020860161371d565b80840191505092915050565b600061404182613fd4565b6016820191506140518284614005565b915081905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b600061409682613678565b91506140a183613678565b92508282019050808211156140b9576140b861405c565b5b92915050565b7f4e6f7420656e6f7567682072656d61696e696e67204e46547320746f2073757060008201527f706f72742064657369726564206d696e7420616d6f756e742e00000000000000602082015250565b600061411b60398361370c565b9150614126826140bf565b604082019050919050565b6000602082019050818103600083015261414a8161410e565b9050919050565b7f5075626c6963206d696e74206973206e6f742073746172746564207965742e2060008201527f506c6561736520636865636b206261636b206c6174657220616e6420666f6c6c60208201527f6f77207573206f6e20747769747465723a20406368696c6c6f72627300000000604082015250565b60006141d3605c8361370c565b91506141de82614151565b606082019050919050565b60006020820190508181036000830152614202816141c6565b9050919050565b7f5075626c6963206d696e7420697320636c6f7365642e20506c6561736520636860008201527f65636b206261636b206c6174657220616e6420666f6c6c6f77207573206f6e2060208201527f747769747465723a20406368696c6c6f72627300000000000000000000000000604082015250565b600061428b60538361370c565b915061429682614209565b606082019050919050565b600060208201905081810360008301526142ba8161427e565b9050919050565b60006142cc82613678565b91506142d783613678565b92508282026142e581613678565b915082820484148315176142fc576142fb61405c565b5b5092915050565b600061430e82613678565b915061431983613678565b92508282039050818111156143315761433061405c565b5b92915050565b600081905092915050565b50565b6000614352600083614337565b915061435d82614342565b600082019050919050565b600061437382614345565b9150819050919050565b7f5472616e73666572206661696c65642e00000000000000000000000000000000600082015250565b60006143b360108361370c565b91506143be8261437d565b602082019050919050565b600060208201905081810360008301526143e2816143a6565b9050919050565b600082905092915050565b60008190508160005260206000209050919050565b60006020601f8301049050919050565b600082821b905092915050565b6000600883026144567fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82614419565b6144608683614419565b95508019841693508086168417925050509392505050565b600061449361448e61448984613678565b613925565b613678565b9050919050565b6000819050919050565b6144ad83614478565b6144c16144b98261449a565b848454614426565b825550505050565b600090565b6144d66144c9565b6144e18184846144a4565b505050565b5b81811015614505576144fa6000826144ce565b6001810190506144e7565b5050565b601f82111561454a5761451b816143f4565b61452484614409565b81016020851015614533578190505b61454761453f85614409565b8301826144e6565b50505b505050565b600082821c905092915050565b600061456d6000198460080261454f565b1980831691505092915050565b6000614586838361455c565b9150826002028217905092915050565b6145a083836143e9565b67ffffffffffffffff8111156145b9576145b8613b11565b5b6145c38254613fa3565b6145ce828285614509565b6000601f8311600181146145fd57600084156145eb578287013590505b6145f5858261457a565b86555061465d565b601f19841661460b866143f4565b60005b828110156146335784890135825560018201915060208501945060208101905061460e565b86831015614650578489013561464c601f89168261455c565b8355505b6001600288020188555050505b50505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000815250565b600061469782614666565b601d820191506146a78284614005565b915081905092915050565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b600061470e60268361370c565b9150614719826146b2565b604082019050919050565b6000602082019050818103600083015261473d81614701565b9050919050565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b600061477a60208361370c565b915061478582614744565b602082019050919050565b600060208201905081810360008301526147a98161476d565b9050919050565b60006040820190506147c5600083018561383c565b6147d2602083018461383c565b9392505050565b6000815190506147e881613a9b565b92915050565b600060208284031215614804576148036135b3565b5b6000614812848285016147d9565b91505092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b600061485582613678565b915061486083613678565b9250826148705761486f61481b565b5b828206905092915050565b600061488682613678565b915061489183613678565b9250826148a1576148a061481b565b5b828204905092915050565b60006148b782613678565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff82036148e9576148e861405c565b5b600182019050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b600061492f8286614005565b915061493b8285614005565b91506149478284614005565b9150819050949350505050565b7f4e65656420746f2073656e64206d6f7265204554482e00000000000000000000600082015250565b600061498a60168361370c565b915061499582614954565b602082019050919050565b600060208201905081810360008301526149b98161497d565b9050919050565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b60006149f6601f8361370c565b9150614a01826149c0565b602082019050919050565b60006020820190508181036000830152614a25816149e9565b9050919050565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b6000614a6260148361370c565b9150614a6d82614a2c565b602082019050919050565b60006020820190508181036000830152614a9181614a55565b9050919050565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b6000614ace60108361370c565b9150614ad982614a98565b602082019050919050565b60006020820190508181036000830152614afd81614ac1565b9050919050565b600081519050919050565b600082825260208201905092915050565b6000614b2b82614b04565b614b358185614b0f565b9350614b4581856020860161371d565b614b4e81613747565b840191505092915050565b6000608082019050614b6e600083018761383c565b614b7b602083018661383c565b614b8860408301856137b3565b8181036060830152614b9a8184614b20565b905095945050505050565b600081519050614bb4816135e9565b92915050565b600060208284031215614bd057614bcf6135b3565b5b6000614bde84828501614ba5565b91505092915050565b60008154614bf481613fa3565b614bfe8186613ffa565b94506001821660008114614c195760018114614c2e57614c61565b60ff1983168652811515820286019350614c61565b614c37856143f4565b60005b83811015614c5957815481890152600182019150602081019050614c3a565b838801955050505b50505092915050565b7f2e6a706700000000000000000000000000000000000000000000000000000000815250565b6000614c9c8286614be7565b9150614ca88285614005565b9150614cb48284614005565b9150614cbf82614c6a565b60048201915081905094935050505056fe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2fa264697066735822122076202cd8db7b1f25ad212eba6c2b69822772fa1e6b9fbaf3b5201006d6b7dc8264736f6c63430008120033

Deployed Bytecode Sourcemap

95494:13560:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;104178:88;;;;;;;;;;;;;:::i;:::-;;62392:639;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;105081:577;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;63294:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;95717:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69785:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;107660:206;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;105827:76;;;;;;;;;;;;;:::i;:::-;;59045:323;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;102279:162;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;107874:205;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;105911:74;;;;;;;;;;;;;:::i;:::-;;104066:87;;;;;;;;;;;;;:::i;:::-;;108734:65;;;;;;;;;;;;;:::i;:::-;;13832:143;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;108087:213;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;40313:86;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64687:152;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101518:117;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60229:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43171:103;;;;;;;;;;;;;:::i;:::-;;102659:277;;;;;;;;;;;;;:::i;:::-;;95676:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;108665:61;;;;;;;;;;;;;:::i;:::-;;101643:478;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;105723:96;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;42530:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;104892:168;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;63470:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;102515:119;;;;;;;;;;;;;:::i;:::-;;102957:786;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;107444:208;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;104693:191;;;;;;;;;;;;;:::i;:::-;;106038:112;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;108308:247;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;95756:40;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101392:118;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;106770:348;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;103792:243;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;104304:122;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;95847:29;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;101231:119;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;95803:37;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;100848:113;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70734:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;43429:201;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;107126:93;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;104178:88;42416:13;:11;:13::i;:::-;104243:15:::1;104227:13;:31;;;;104178:88::o:0;62392:639::-;62477:4;62816:10;62801:25;;:11;:25;;;;:102;;;;62893:10;62878:25;;:11;:25;;;;62801:102;:179;;;;62970:10;62955:25;;:11;:25;;;;62801:179;62781:199;;62392:639;;;:::o;105081:577::-;105175:9;;;;;;;;;;;105167:47;;;;;;;;;;;;:::i;:::-;;;;;;;;;105227:21;105233:8;105243:4;105227:5;:21::i;:::-;105295;105301:8;105311:4;105295:5;:21::i;:::-;105388:14;:24;105403:8;105388:24;;;;;;;;;;;;;;;;;;;;;105387:25;105365:110;;;;;;;;;;;;:::i;:::-;;;;;;;;;105529:10;105508:31;;:17;105516:8;105508:7;:17::i;:::-;:31;;;105486:122;;;;;;;;;;;;:::i;:::-;;;;;;;;;105646:4;105619:14;:24;105634:8;105619:24;;;;;;;;;;;;:31;;;;;;;;;;;;;;;;;;105081:577;;;:::o;63294:100::-;63348:13;63381:5;63374:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63294:100;:::o;95717:32::-;;;;:::o;69785:218::-;69861:7;69886:16;69894:7;69886;:16::i;:::-;69881:64;;69911:34;;;;;;;;;;;;;;69881:64;69965:15;:24;69981:7;69965:24;;;;;;;;;;;:30;;;;;;;;;;;;69958:37;;69785:218;;;:::o;107660:206::-;107800:8;15614:30;15635:8;15614:20;:30::i;:::-;107826:32:::1;107840:8;107850:7;107826:13;:32::i;:::-;107660:206:::0;;;:::o;105827:76::-;42416:13;:11;:13::i;:::-;105890:5:::1;105878:9;;:17;;;;;;;;;;;;;;;;;;105827:76::o:0;59045:323::-;59106:7;59334:15;:13;:15::i;:::-;59319:12;;59303:13;;:28;:46;59296:53;;59045:323;:::o;102279:162::-;102341:13;102414:18;102424:7;102414:9;:18::i;:::-;102374:59;;;;;;;;:::i;:::-;;;;;;;;;;;;;102367:66;;102279:162;;;:::o;107874:205::-;108017:4;15348:10;15340:18;;:4;:18;;;15336:83;;15375:32;15396:10;15375:20;:32::i;:::-;15336:83;108034:37:::1;108053:4;108059:2;108063:7;108034:18;:37::i;:::-;107874:205:::0;;;;:::o;105911:74::-;42416:13;:11;:13::i;:::-;105973:4:::1;105961:9;;:16;;;;;;;;;;;;;;;;;;105911:74::o:0;104066:87::-;42416:13;:11;:13::i;:::-;104117:28:::1;104129:15;104117:11;:28::i;:::-;104066:87::o:0;108734:65::-;42416:13;:11;:13::i;:::-;108781:10:::1;:8;:10::i;:::-;108734:65::o:0;13832:143::-;6248:42;13832:143;:::o;108087:213::-;108234:4;15348:10;15340:18;;:4;:18;;;15336:83;;15375:32;15396:10;15375:20;:32::i;:::-;15336:83;108251:41:::1;108274:4;108280:2;108284:7;108251:22;:41::i;:::-;108087:213:::0;;;;:::o;40313:86::-;40360:4;40384:7;;;;;;;;;;;40377:14;;40313:86;:::o;64687:152::-;64759:7;64802:27;64821:7;64802:18;:27::i;:::-;64779:52;;64687:152;;;:::o;101518:117::-;101575:13;42416;:11;:13::i;:::-;101608:19:::1;101601:26;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;101518:117:::0;:::o;60229:233::-;60301:7;60342:1;60325:19;;:5;:19;;;60321:60;;60353:28;;;;;;;;;;;;;;60321:60;54388:13;60399:18;:25;60418:5;60399:25;;;;;;;;;;;;;;;;:55;60392:62;;60229:233;;;:::o;43171:103::-;42416:13;:11;:13::i;:::-;43236:30:::1;43263:1;43236:18;:30::i;:::-;43171:103::o:0;102659:277::-;42416:13;:11;:13::i;:::-;102708:16:::1;102727:2;102708:21;;102790:15;;;;;;;;;;;102762:43;;102778:8;102762:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:43;;102740:150;;;;;;;;;;;;:::i;:::-;;;;;;;;;102901:27;102907:10;102919:8;102901:5;:27::i;:::-;102697:239;102659:277::o:0;95676:34::-;;;;:::o;108665:61::-;42416:13;:11;:13::i;:::-;108710:8:::1;:6;:8::i;:::-;108665:61::o:0;101643:478::-;101703:13;101819:25;101847:94;101869:19;101847:94;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;101913:27;101932:7;101913:18;:27::i;:::-;101847:21;:94::i;:::-;101819:122;;101952:27;101982:18;101992:7;101982:9;:18::i;:::-;:37;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;101952:67;;102039:74;102061:11;102039:74;;;;;;;;;;;;;;;;;102099:13;102039:21;:74::i;:::-;102032:81;;;;101643:478;;;:::o;105723:96::-;42416:13;:11;:13::i;:::-;105790:21:::1;105796:7;105805:5;105790;:21::i;:::-;105723:96:::0;:::o;42530:87::-;42576:7;42603:6;;;;;;;;;;;42596:13;;42530:87;:::o;104892:168::-;104985:21;;:::i;:::-;105031;105044:7;105031:12;:21::i;:::-;105024:28;;104892:168;;;:::o;63470:104::-;63526:13;63559:7;63552:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63470:104;:::o;102515:119::-;42416:13;:11;:13::i;:::-;102568:16:::1;102587:1;102568:20;;102599:27;102605:10;102617:8;102599:5;:27::i;:::-;102557:77;102515:119::o:0;102957:786::-;103067:15;;;;;;;;;;;103039:43;;103055:8;103039:13;:11;:13::i;:::-;:24;;;;:::i;:::-;:43;;103017:150;;;;;;;;;;;;:::i;:::-;;;;;;;;;103221:15;103202;;:34;;:58;;;;;103259:1;103240:15;;:20;;103202:58;103180:200;;;;;;;;;;;;:::i;:::-;;;;;;;;;103431:15;103415:13;;:31;103393:164;;;;;;;;;;;;:::i;:::-;;;;;;;;;103570:17;103643:1;103615:24;103628:10;103615:12;:24::i;:::-;:29;:46;;103660:1;103615:46;;;103647:10;;103615:46;103603:8;103590:10;;:21;;;;:::i;:::-;:72;;;;:::i;:::-;103570:92;;103673:24;103687:9;103673:13;:24::i;:::-;103708:27;103714:10;103726:8;103708:5;:27::i;:::-;103006:737;102957:786;:::o;107444:208::-;107575:8;15614:30;15635:8;15614:20;:30::i;:::-;107601:43:::1;107625:8;107635;107601:23;:43::i;:::-;107444:208:::0;;;:::o;104693:191::-;42416:13;:11;:13::i;:::-;36852:21:::1;:19;:21::i;:::-;104762:12:::2;104780:10;:15;;104803:21;104780:49;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;104761:68;;;104848:7;104840:36;;;;;;;;;;;;:::i;:::-;;;;;;;;;104750:134;36896:20:::1;:18;:20::i;:::-;104693:191::o:0;106038:112::-;106095:4;106119:14;:23;106134:7;106119:23;;;;;;;;;;;;;;;;;;;;;106112:30;;106038:112;;;:::o;108308:247::-;108483:4;15348:10;15340:18;;:4;:18;;;15336:83;;15375:32;15396:10;15375:20;:32::i;:::-;15336:83;108500:47:::1;108523:4;108529:2;108533:7;108542:4;108500:22;:47::i;:::-;108308:247:::0;;;;;:::o;95756:40::-;;;;:::o;101392:118::-;42416:13;:11;:13::i;:::-;101492:10:::1;;101470:19;:32;;;;;;;:::i;:::-;;101392:118:::0;;:::o;106770:348::-;106871:13;106907:16;106915:7;106907;:16::i;:::-;106902:59;;106932:29;;;;;;;;;;;;;;106902:59;106974:18;106995:21;107008:7;106995:12;:21::i;:::-;106974:42;;107083:26;107103:4;107083:13;:26::i;:::-;107036:74;;;;;;;;:::i;:::-;;;;;;;;;;;;;107029:81;;;106770:348;;;:::o;103792:243::-;42416:13;:11;:13::i;:::-;103943:21:::1;103925:15;:39;;;;104015:12;103991:21;:36;;;;:::i;:::-;103975:13;:52;;;;103792:243:::0;:::o;104304:122::-;42416:13;:11;:13::i;:::-;104399:19:::1;104383:13;:35;;;;104304:122:::0;:::o;95847:29::-;;;;;;;;;;;;;:::o;101231:119::-;42416:13;:11;:13::i;:::-;101335:7:::1;;101318:14;:24;;;;;;;:::i;:::-;;101231:119:::0;;:::o;95803:37::-;;;;;;;;;;;;;:::o;100848:113::-;100906:7;100933:20;100947:5;100933:13;:20::i;:::-;100926:27;;100848:113;;;:::o;70734:164::-;70831:4;70855:18;:25;70874:5;70855:25;;;;;;;;;;;;;;;:35;70881:8;70855:35;;;;;;;;;;;;;;;;;;;;;;;;;70848:42;;70734:164;;;;:::o;43429:201::-;42416:13;:11;:13::i;:::-;43538:1:::1;43518:22;;:8;:22;;::::0;43510:73:::1;;;;;;;;;;;;:::i;:::-;;;;;;;;;43594:28;43613:8;43594:18;:28::i;:::-;43429:201:::0;:::o;107126:93::-;42416:13;:11;:13::i;:::-;107206:5:::1;107193:10;:18;;;;107126:93:::0;:::o;42695:132::-;42770:12;:10;:12::i;:::-;42759:23;;:7;:5;:7::i;:::-;:23;;;42751:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;42695:132::o;87993:3081::-;88073:27;88103;88122:7;88103:18;:27::i;:::-;88073:57;;88143:12;88174:19;88143:52;;88209:27;88238:23;88265:35;88292:7;88265:26;:35::i;:::-;88208:92;;;;88317:13;88313:316;;;88438:68;88463:15;88480:4;88486:19;:17;:19::i;:::-;88438:24;:68::i;:::-;88433:184;;88530:43;88547:4;88553:19;:17;:19::i;:::-;88530:16;:43::i;:::-;88525:92;;88582:35;;;;;;;;;;;;;;88525:92;88433:184;88313:316;88641:51;88663:4;88677:1;88681:7;88690:1;88641:21;:51::i;:::-;88785:15;88782:160;;;88925:1;88904:19;88897:30;88782:160;89603:1;54653:3;89573:1;:26;;89572:32;89544:18;:24;89563:4;89544:24;;;;;;;;;;;;;;;;:60;;;;;;;;;;;89871:176;89908:4;89979:53;89994:4;90008:1;90012:19;89979:14;:53::i;:::-;55444:8;55164;89932:43;89931:101;89871:18;:176::i;:::-;89842:17;:26;89860:7;89842:26;;;;;;;;;;;:205;;;;90218:1;55444:8;90167:19;:47;:52;90163:627;;90240:19;90272:1;90262:7;:11;90240:33;;90429:1;90395:17;:30;90413:11;90395:30;;;;;;;;;;;;:35;90391:384;;90533:13;;90518:11;:28;90514:242;;90713:19;90680:17;:30;90698:11;90680:30;;;;;;;;;;;:52;;;;90514:242;90391:384;90221:569;90163:627;90845:7;90841:1;90818:35;;90827:4;90818:35;;;;;;;;;;;;90864:50;90885:4;90899:1;90903:7;90912:1;90864:20;:50::i;:::-;91041:12;;:14;;;;;;;;;;;;;88062:3012;;;;87993:3081;;:::o;71156:282::-;71221:4;71277:7;71258:15;:13;:15::i;:::-;:26;;:66;;;;;71311:13;;71301:7;:23;71258:66;:153;;;;;71410:1;55164:8;71362:17;:26;71380:7;71362:26;;;;;;;;;;;;:44;:49;71258:153;71238:173;;71156:282;;;:::o;15757:647::-;15996:1;6248:42;15948:45;;;:49;15944:453;;;6248:42;16247;;;16298:4;16305:8;16247:67;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;16242:144;;16361:8;16342:28;;;;;;;;;;;:::i;:::-;;;;;;;;16242:144;15944:453;15757:647;:::o;69218:408::-;69307:13;69323:16;69331:7;69323;:16::i;:::-;69307:32;;69379:5;69356:28;;:19;:17;:19::i;:::-;:28;;;69352:175;;69404:44;69421:5;69428:19;:17;:19::i;:::-;69404:16;:44::i;:::-;69399:128;;69476:35;;;;;;;;;;;;;;69399:128;69352:175;69572:2;69539:15;:24;69555:7;69539:24;;;;;;;;;;;:30;;;:35;;;;;;;;;;;;;;;;;;69610:7;69606:2;69590:28;;69599:5;69590:28;;;;;;;;;;;;69296:330;69218:408;;:::o;58561:92::-;58617:7;58561:92;:::o;102129:142::-;102187:13;102220:43;102240:21;102253:7;102240:12;:21::i;:::-;102220:13;:43::i;:::-;102213:50;;102129:142;;;:::o;73424:2825::-;73566:27;73596;73615:7;73596:18;:27::i;:::-;73566:57;;73681:4;73640:45;;73656:19;73640:45;;;73636:86;;73694:28;;;;;;;;;;;;;;73636:86;73736:27;73765:23;73792:35;73819:7;73792:26;:35::i;:::-;73735:92;;;;73927:68;73952:15;73969:4;73975:19;:17;:19::i;:::-;73927:24;:68::i;:::-;73922:180;;74015:43;74032:4;74038:19;:17;:19::i;:::-;74015:16;:43::i;:::-;74010:92;;74067:35;;;;;;;;;;;;;;74010:92;73922:180;74133:1;74119:16;;:2;:16;;;74115:52;;74144:23;;;;;;;;;;;;;;74115:52;74180:43;74202:4;74208:2;74212:7;74221:1;74180:21;:43::i;:::-;74316:15;74313:160;;;74456:1;74435:19;74428:30;74313:160;74853:18;:24;74872:4;74853:24;;;;;;;;;;;;;;;;74851:26;;;;;;;;;;;;74922:18;:22;74941:2;74922:22;;;;;;;;;;;;;;;;74920:24;;;;;;;;;;;75244:146;75281:2;75330:45;75345:4;75351:2;75355:19;75330:14;:45::i;:::-;55444:8;75302:73;75244:18;:146::i;:::-;75215:17;:26;75233:7;75215:26;;;;;;;;;;;:175;;;;75561:1;55444:8;75510:19;:47;:52;75506:627;;75583:19;75615:1;75605:7;:11;75583:33;;75772:1;75738:17;:30;75756:11;75738:30;;;;;;;;;;;;:35;75734:384;;75876:13;;75861:11;:28;75857:242;;76056:19;76023:17;:30;76041:11;76023:30;;;;;;;;;;;:52;;;;75857:242;75734:384;75564:569;75506:627;76180:7;76176:2;76161:27;;76170:4;76161:27;;;;;;;;;;;;76199:42;76220:4;76226:2;76230:7;76239:1;76199:20;:42::i;:::-;73555:2694;;;73424:2825;;;:::o;41168:120::-;40177:16;:14;:16::i;:::-;41237:5:::1;41227:7;;:15;;;;;;;;;;;;;;;;;;41258:22;41267:12;:10;:12::i;:::-;41258:22;;;;;;:::i;:::-;;;;;;;;41168:120::o:0;76345:193::-;76491:39;76508:4;76514:2;76518:7;76491:39;;;;;;;;;;;;:16;:39::i;:::-;76345:193;;;:::o;65842:1275::-;65909:7;65929:12;65944:7;65929:22;;66012:4;65993:15;:13;:15::i;:::-;:23;65989:1061;;66046:13;;66039:4;:20;66035:1015;;;66084:14;66101:17;:23;66119:4;66101:23;;;;;;;;;;;;66084:40;;66218:1;55164:8;66190:6;:24;:29;66186:845;;66855:113;66872:1;66862:6;:11;66855:113;;66915:17;:25;66933:6;;;;;;;66915:25;;;;;;;;;;;;66906:34;;66855:113;;;67001:6;66994:13;;;;;;66186:845;66061:989;66035:1015;65989:1061;67078:31;;;;;;;;;;;;;;65842:1275;;;;:::o;43790:191::-;43864:16;43883:6;;;;;;;;;;;43864:25;;43909:8;43900:6;;:17;;;;;;;;;;;;;;;;;;43964:8;43933:40;;43954:8;43933:40;;;;;;;;;;;;43853:128;43790:191;:::o;80805:2966::-;80878:20;80901:13;;80878:36;;80941:1;80929:8;:13;80925:44;;80951:18;;;;;;;;;;;;;;80925:44;80982:61;81012:1;81016:2;81020:12;81034:8;80982:21;:61::i;:::-;81526:1;54526:2;81496:1;:26;;81495:32;81483:8;:45;81457:18;:22;81476:2;81457:22;;;;;;;;;;;;;;;;:71;;;;;;;;;;;81805:139;81842:2;81896:33;81919:1;81923:2;81927:1;81896:14;:33::i;:::-;81863:30;81884:8;81863:20;:30::i;:::-;:66;81805:18;:139::i;:::-;81771:17;:31;81789:12;81771:31;;;;;;;;;;;:173;;;;81961:16;81992:11;82021:8;82006:12;:23;81992:37;;82542:16;82538:2;82534:25;82522:37;;82914:12;82874:8;82833:1;82771:25;82712:1;82651;82624:335;83285:1;83271:12;83267:20;83225:346;83326:3;83317:7;83314:16;83225:346;;83544:7;83534:8;83531:1;83504:25;83501:1;83498;83493:59;83379:1;83370:7;83366:15;83355:26;;83225:346;;;83229:77;83616:1;83604:8;:13;83600:45;;83626:19;;;;;;;;;;;;;;83600:45;83678:3;83662:13;:19;;;;81231:2462;;83703:60;83732:1;83736:2;83740:12;83754:8;83703:20;:60::i;:::-;80867:2904;80805:2966;;:::o;40909:118::-;39918:19;:17;:19::i;:::-;40979:4:::1;40969:7;;:14;;;;;;;;;;;;;;;;;;40999:20;41006:12;:10;:12::i;:::-;40999:20;;;;;;:::i;:::-;;;;;;;;40909:118::o:0;1765:677::-;1818:13;1853:1;1848;:6;1844:22;;1856:10;;;;;;;;;;;;;;;;;;;;;1844:22;1877:14;1894:3;1877:20;;1908:21;1942:9;1932:20;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1908:44;;1963:6;1984:150;1996:1;1991;:6;1984:150;;2014:14;2035:2;2031:1;:6;;;;:::i;:::-;2014:23;;2060:2;2056:1;:6;;;;:::i;:::-;2052:10;;2111:9;2106:2;:14;;;;:::i;:::-;2093:29;;2077:8;2086:3;;;;;:::i;:::-;;;2077:13;;;;;;;;:::i;:::-;;;;;:45;;;;;;;;;;;1999:135;1984:150;;;2144:14;2171:1;2161:12;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2144:29;;2213:6;2208:115;2229:1;2225;:5;2208:115;;;2259:8;2276:1;2272;2268;:5;;;;:::i;:::-;:9;;;;:::i;:::-;2259:19;;;;;;;;:::i;:::-;;;;;;;;;;2252:1;2254;2252:4;;;;;;;;:::i;:::-;;;;;:26;;;;;;;;;;;2232:3;;;;;:::i;:::-;;;;2208:115;;;;2333:17;2360:1;2333:29;;2431:3;2424:10;;;;;;;1765:677;;;;:::o;455:1302::-;578:13;604:24;637:10;604:44;;659:24;692:6;659:40;;737:11;:18;716:11;:18;:39;712:89;;;779:10;772:17;;;;;;712:89;856:10;885:16;921:9;916:447;962:11;:18;941:11;:18;:39;;;;:::i;:::-;936:1;:44;916:447;;1002:9;1014:4;1002:16;;1038:9;1033:193;1057:11;:18;1053:1;:22;1033:193;;;1126:11;1139:1;1126:15;;;;;;;;:::i;:::-;;;;;;;;;;1103:38;;;:11;1120:1;1116;:5;;;;:::i;:::-;1103:19;;;;;;;;:::i;:::-;;;;;;;;;;:38;;;;1099:127;;1173:5;1166:12;;1201:5;;1099:127;1077:3;;;;;:::i;:::-;;;;1033:193;;;;1244:4;1240:112;;;1277:4;1269:12;;1311:1;1300:12;;1331:5;;;1240:112;987:376;982:3;;;;;:::i;:::-;;;;916:447;;;;1431:5;1427:285;;;1453:23;1479:34;1489:10;1501:1;1504:8;1479:9;:34::i;:::-;1453:60;;1528:24;1555:72;1565:10;1588:11;:18;1577:8;:29;;;;:::i;:::-;1608:11;:18;1555:9;:72::i;:::-;1528:99;;1665:9;1676:11;1689:10;1651:49;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;1644:56;;;;;;;;;;1427:285;1739:10;1732:17;;;;;;455:1302;;;;;;:::o;65028:166::-;65098:21;;:::i;:::-;65139:47;65158:27;65177:7;65158:18;:27::i;:::-;65139:18;:47::i;:::-;65132:54;;65028:166;;;:::o;104460:225::-;104538:5;104525:9;:18;;104517:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;104597:5;104585:9;:17;104581:97;;;104627:10;104619:28;;:47;104660:5;104648:9;:17;;;;:::i;:::-;104619:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;104581:97;104460:225;:::o;70343:234::-;70490:8;70438:18;:39;70457:19;:17;:19::i;:::-;70438:39;;;;;;;;;;;;;;;:49;70478:8;70438:49;;;;;;;;;;;;;;;;:60;;;;;;;;;;;;;;;;;;70550:8;70514:55;;70529:19;:17;:19::i;:::-;70514:55;;;70560:8;70514:55;;;;;;:::i;:::-;;;;;;;;70343:234;;:::o;36932:293::-;36334:1;37066:7;;:19;37058:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;36334:1;37199:7;:18;;;;36932:293::o;37233:213::-;36290:1;37416:7;:22;;;;37233:213::o;77136:407::-;77311:31;77324:4;77330:2;77334:7;77311:12;:31::i;:::-;77375:1;77357:2;:14;;;:19;77353:183;;77396:56;77427:4;77433:2;77437:7;77446:5;77396:30;:56::i;:::-;77391:145;;77480:40;;;;;;;;;;;;;;77391:145;77353:183;77136:407;;;;:::o;106179:583::-;106240:13;106266:18;106287:16;106266:37;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;106321:69;106343:4;106321:69;;;;;;;;;;;;;;;;;106362:27;106381:7;106362:18;:27::i;:::-;106321:21;:69::i;:::-;106314:76;;106408:66;106430:4;106408:66;;;;;;;;;;;;;;;;;106449:24;106465:7;106449:15;:24::i;:::-;106408:21;:66::i;:::-;106401:73;;106492:64;106514:4;106492:64;;;;;;;;;;;;;;;;;106532:23;106547:7;106532:14;:23::i;:::-;106492:21;:64::i;:::-;106485:71;;106574:64;106596:4;106574:64;;;;;;;;;;;;;;;;;106614:23;106629:7;106614:14;:23::i;:::-;106574:21;:64::i;:::-;106567:71;;106656:76;106678:4;106656:76;;;;;;;;;;;;;;;;;106698:18;106708:7;106698:9;:18::i;:::-;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;106656:21;:76::i;:::-;106649:83;;106750:4;106743:11;;;106179:583;;;:::o;2993:3097::-;3051:13;3303:1;3288:4;:11;:16;3284:31;;3306:9;;;;;;;;;;;;;;;;3284:31;3368:19;3390:6;;;;;;;;;;;;;;;;;3368:28;;3807:20;3866:1;3861;3847:4;:11;:15;;;;:::i;:::-;3846:21;;;;:::i;:::-;3841:1;:27;;;;:::i;:::-;3830:39;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3807:62;;4049:1;4042:5;4038:13;4153:2;4145:6;4141:15;4264:4;4316;4310:11;4304:4;4300:22;4226:1432;4350:6;4341:7;4338:19;4226:1432;;;4456:1;4447:7;4443:15;4432:26;;4495:7;4489:14;5148:4;5140:5;5136:2;5132:14;5128:25;5118:8;5114:40;5108:47;5097:9;5089:67;5202:1;5191:9;5187:17;5174:30;;5294:4;5286:5;5282:2;5278:14;5274:25;5264:8;5260:40;5254:47;5243:9;5235:67;5348:1;5337:9;5333:17;5320:30;;5439:4;5431:5;5428:1;5424:13;5420:24;5410:8;5406:39;5400:46;5389:9;5381:66;5493:1;5482:9;5478:17;5465:30;;5576:4;5569:5;5565:16;5555:8;5551:31;5545:38;5534:9;5526:58;5630:1;5619:9;5615:17;5602:30;;4377:1281;4226:1432;;;4230:107;;5820:1;5813:4;5807:11;5803:19;5841:1;5836:123;;;;5978:1;5973:73;;;;5796:250;;5836:123;5889:4;5885:1;5874:9;5870:17;5862:32;5939:4;5935:1;5924:9;5920:17;5912:32;5836:123;;5973:73;6026:4;6022:1;6011:9;6007:17;5999:32;5796:250;;3935:2122;;6076:6;6069:13;;;;2993:3097;;;;:::o;60544:178::-;60605:7;54388:13;54526:2;60633:18;:25;60652:5;60633:25;;;;;;;;;;;;;;;;:50;;60632:82;60625:89;;60544:178;;;:::o;38426:98::-;38479:7;38506:10;38499:17;;38426:98;:::o;72319:485::-;72421:27;72450:23;72491:38;72532:15;:24;72548:7;72532:24;;;;;;;;;;;72491:65;;72709:18;72686:41;;72766:19;72760:26;72741:45;;72671:126;72319:485;;;:::o;93464:105::-;93524:7;93551:10;93544:17;;93464:105;:::o;71547:659::-;71696:11;71861:16;71854:5;71850:28;71841:37;;72021:16;72010:9;72006:32;71993:45;;72171:15;72160:9;72157:30;72149:5;72138:9;72135:20;72132:56;72122:66;;71547:659;;;;;:::o;108807:244::-;39918:19;:17;:19::i;:::-;108986:57:::1;109014:4;109020:2;109024:7;109033:9;108986:27;:57::i;:::-;108807:244:::0;;;;:::o;92773:311::-;92908:7;92928:16;55568:3;92954:19;:41;;92928:68;;55568:3;93022:31;93033:4;93039:2;93043:9;93022:10;:31::i;:::-;93014:40;;:62;;93007:69;;;92773:311;;;;;:::o;67665:450::-;67745:14;67913:16;67906:5;67902:28;67893:37;;68090:5;68076:11;68051:23;68047:41;68044:52;68037:5;68034:63;68024:73;;67665:450;;;;:::o;79029:158::-;;;;;:::o;40657:108::-;40724:8;:6;:8::i;:::-;40716:41;;;;;;;;;;;;:::i;:::-;;;;;;;;;40657:108::o;68217:324::-;68287:14;68520:1;68510:8;68507:15;68481:24;68477:46;68467:56;;68217:324;;;:::o;40472:108::-;40543:8;:6;:8::i;:::-;40542:9;40534:38;;;;;;;;;;;;:::i;:::-;;;;;;;;;40472:108::o;76:371::-;169:13;195:21;225:3;195:34;;240:19;281:10;272:8;:19;;;;:::i;:::-;262:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;240:52;;307:6;316:10;307:19;;303:105;332:8;328:1;:12;303:105;;;385:8;394:1;385:11;;;;;;;;:::i;:::-;;;;;;;;;;362:6;371:10;369:1;:12;;;;:::i;:::-;362:20;;;;;;;;:::i;:::-;;;;;:34;;;;;;;;;;;342:3;;;;;:::i;:::-;;;;303:105;;;;432:6;418:21;;;;76:371;;;;;:::o;67216:366::-;67282:31;;:::i;:::-;67359:6;67326:9;:14;;:41;;;;;;;;;;;55047:3;67412:6;:33;;67378:9;:24;;:68;;;;;;;;;;;67504:1;55164:8;67476:6;:24;:29;;67457:9;:16;;:48;;;;;;;;;;;55568:3;67545:6;:28;;67516:9;:19;;:58;;;;;;;;;;;67216:366;;;:::o;79627:716::-;79790:4;79836:2;79811:45;;;79857:19;:17;:19::i;:::-;79878:4;79884:7;79893:5;79811:88;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;79807:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;80111:1;80094:6;:13;:18;80090:235;;80140:40;;;;;;;;;;;;;;80090:235;80283:6;80277:13;80268:6;80264:2;80260:15;80253:38;79807:529;79980:54;;;79970:64;;;:6;:64;;;;79963:71;;;79627:716;;;;;;:::o;100993:226::-;101057:13;101104:14;101120:18;101130:7;101120:9;:18::i;:::-;:53;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;101175:27;101194:7;101175:18;:27::i;:::-;101090:121;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;101083:128;;100993:226;;;:::o;78205:159::-;;;;;:::o;92474:147::-;92611:6;92474:147;;;;;:::o;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;7:75:1:-;40:6;73:2;67:9;57:19;;7:75;:::o;88:117::-;197:1;194;187:12;211:117;320:1;317;310:12;334:149;370:7;410:66;403:5;399:78;388:89;;334:149;;;:::o;489:120::-;561:23;578:5;561:23;:::i;:::-;554:5;551:34;541:62;;599:1;596;589:12;541:62;489:120;:::o;615:137::-;660:5;698:6;685:20;676:29;;714:32;740:5;714:32;:::i;:::-;615:137;;;;:::o;758:327::-;816:6;865:2;853:9;844:7;840:23;836:32;833:119;;;871:79;;:::i;:::-;833:119;991:1;1016:52;1060:7;1051:6;1040:9;1036:22;1016:52;:::i;:::-;1006:62;;962:116;758:327;;;;:::o;1091:90::-;1125:7;1168:5;1161:13;1154:21;1143:32;;1091:90;;;:::o;1187:109::-;1268:21;1283:5;1268:21;:::i;:::-;1263:3;1256:34;1187:109;;:::o;1302:210::-;1389:4;1427:2;1416:9;1412:18;1404:26;;1440:65;1502:1;1491:9;1487:17;1478:6;1440:65;:::i;:::-;1302:210;;;;:::o;1518:77::-;1555:7;1584:5;1573:16;;1518:77;;;:::o;1601:122::-;1674:24;1692:5;1674:24;:::i;:::-;1667:5;1664:35;1654:63;;1713:1;1710;1703:12;1654:63;1601:122;:::o;1729:139::-;1775:5;1813:6;1800:20;1791:29;;1829:33;1856:5;1829:33;:::i;:::-;1729:139;;;;:::o;1874:619::-;1951:6;1959;1967;2016:2;2004:9;1995:7;1991:23;1987:32;1984:119;;;2022:79;;:::i;:::-;1984:119;2142:1;2167:53;2212:7;2203:6;2192:9;2188:22;2167:53;:::i;:::-;2157:63;;2113:117;2269:2;2295:53;2340:7;2331:6;2320:9;2316:22;2295:53;:::i;:::-;2285:63;;2240:118;2397:2;2423:53;2468:7;2459:6;2448:9;2444:22;2423:53;:::i;:::-;2413:63;;2368:118;1874:619;;;;;:::o;2499:99::-;2551:6;2585:5;2579:12;2569:22;;2499:99;;;:::o;2604:169::-;2688:11;2722:6;2717:3;2710:19;2762:4;2757:3;2753:14;2738:29;;2604:169;;;;:::o;2779:246::-;2860:1;2870:113;2884:6;2881:1;2878:13;2870:113;;;2969:1;2964:3;2960:11;2954:18;2950:1;2945:3;2941:11;2934:39;2906:2;2903:1;2899:10;2894:15;;2870:113;;;3017:1;3008:6;3003:3;2999:16;2992:27;2841:184;2779:246;;;:::o;3031:102::-;3072:6;3123:2;3119:7;3114:2;3107:5;3103:14;3099:28;3089:38;;3031:102;;;:::o;3139:377::-;3227:3;3255:39;3288:5;3255:39;:::i;:::-;3310:71;3374:6;3369:3;3310:71;:::i;:::-;3303:78;;3390:65;3448:6;3443:3;3436:4;3429:5;3425:16;3390:65;:::i;:::-;3480:29;3502:6;3480:29;:::i;:::-;3475:3;3471:39;3464:46;;3231:285;3139:377;;;;:::o;3522:313::-;3635:4;3673:2;3662:9;3658:18;3650:26;;3722:9;3716:4;3712:20;3708:1;3697:9;3693:17;3686:47;3750:78;3823:4;3814:6;3750:78;:::i;:::-;3742:86;;3522:313;;;;:::o;3841:118::-;3928:24;3946:5;3928:24;:::i;:::-;3923:3;3916:37;3841:118;;:::o;3965:222::-;4058:4;4096:2;4085:9;4081:18;4073:26;;4109:71;4177:1;4166:9;4162:17;4153:6;4109:71;:::i;:::-;3965:222;;;;:::o;4193:329::-;4252:6;4301:2;4289:9;4280:7;4276:23;4272:32;4269:119;;;4307:79;;:::i;:::-;4269:119;4427:1;4452:53;4497:7;4488:6;4477:9;4473:22;4452:53;:::i;:::-;4442:63;;4398:117;4193:329;;;;:::o;4528:126::-;4565:7;4605:42;4598:5;4594:54;4583:65;;4528:126;;;:::o;4660:96::-;4697:7;4726:24;4744:5;4726:24;:::i;:::-;4715:35;;4660:96;;;:::o;4762:118::-;4849:24;4867:5;4849:24;:::i;:::-;4844:3;4837:37;4762:118;;:::o;4886:222::-;4979:4;5017:2;5006:9;5002:18;4994:26;;5030:71;5098:1;5087:9;5083:17;5074:6;5030:71;:::i;:::-;4886:222;;;;:::o;5114:122::-;5187:24;5205:5;5187:24;:::i;:::-;5180:5;5177:35;5167:63;;5226:1;5223;5216:12;5167:63;5114:122;:::o;5242:139::-;5288:5;5326:6;5313:20;5304:29;;5342:33;5369:5;5342:33;:::i;:::-;5242:139;;;;:::o;5387:474::-;5455:6;5463;5512:2;5500:9;5491:7;5487:23;5483:32;5480:119;;;5518:79;;:::i;:::-;5480:119;5638:1;5663:53;5708:7;5699:6;5688:9;5684:22;5663:53;:::i;:::-;5653:63;;5609:117;5765:2;5791:53;5836:7;5827:6;5816:9;5812:22;5791:53;:::i;:::-;5781:63;;5736:118;5387:474;;;;;:::o;5867:619::-;5944:6;5952;5960;6009:2;5997:9;5988:7;5984:23;5980:32;5977:119;;;6015:79;;:::i;:::-;5977:119;6135:1;6160:53;6205:7;6196:6;6185:9;6181:22;6160:53;:::i;:::-;6150:63;;6106:117;6262:2;6288:53;6333:7;6324:6;6313:9;6309:22;6288:53;:::i;:::-;6278:63;;6233:118;6390:2;6416:53;6461:7;6452:6;6441:9;6437:22;6416:53;:::i;:::-;6406:63;;6361:118;5867:619;;;;;:::o;6492:60::-;6520:3;6541:5;6534:12;;6492:60;;;:::o;6558:142::-;6608:9;6641:53;6659:34;6668:24;6686:5;6668:24;:::i;:::-;6659:34;:::i;:::-;6641:53;:::i;:::-;6628:66;;6558:142;;;:::o;6706:126::-;6756:9;6789:37;6820:5;6789:37;:::i;:::-;6776:50;;6706:126;;;:::o;6838:157::-;6919:9;6952:37;6983:5;6952:37;:::i;:::-;6939:50;;6838:157;;;:::o;7001:193::-;7119:68;7181:5;7119:68;:::i;:::-;7114:3;7107:81;7001:193;;:::o;7200:284::-;7324:4;7362:2;7351:9;7347:18;7339:26;;7375:102;7474:1;7463:9;7459:17;7450:6;7375:102;:::i;:::-;7200:284;;;;:::o;7490:329::-;7549:6;7598:2;7586:9;7577:7;7573:23;7569:32;7566:119;;;7604:79;;:::i;:::-;7566:119;7724:1;7749:53;7794:7;7785:6;7774:9;7770:22;7749:53;:::i;:::-;7739:63;;7695:117;7490:329;;;;:::o;7825:108::-;7902:24;7920:5;7902:24;:::i;:::-;7897:3;7890:37;7825:108;;:::o;7939:101::-;7975:7;8015:18;8008:5;8004:30;7993:41;;7939:101;;;:::o;8046:105::-;8121:23;8138:5;8121:23;:::i;:::-;8116:3;8109:36;8046:105;;:::o;8157:99::-;8228:21;8243:5;8228:21;:::i;:::-;8223:3;8216:34;8157:99;;:::o;8262:91::-;8298:7;8338:8;8331:5;8327:20;8316:31;;8262:91;;;:::o;8359:105::-;8434:23;8451:5;8434:23;:::i;:::-;8429:3;8422:36;8359:105;;:::o;8542:876::-;8703:4;8698:3;8694:14;8790:4;8783:5;8779:16;8773:23;8809:63;8866:4;8861:3;8857:14;8843:12;8809:63;:::i;:::-;8718:164;8974:4;8967:5;8963:16;8957:23;8993:61;9048:4;9043:3;9039:14;9025:12;8993:61;:::i;:::-;8892:172;9148:4;9141:5;9137:16;9131:23;9167:57;9218:4;9213:3;9209:14;9195:12;9167:57;:::i;:::-;9074:160;9321:4;9314:5;9310:16;9304:23;9340:61;9395:4;9390:3;9386:14;9372:12;9340:61;:::i;:::-;9244:167;8672:746;8542:876;;:::o;9424:351::-;9581:4;9619:3;9608:9;9604:19;9596:27;;9633:135;9765:1;9754:9;9750:17;9741:6;9633:135;:::i;:::-;9424:351;;;;:::o;9781:116::-;9851:21;9866:5;9851:21;:::i;:::-;9844:5;9841:32;9831:60;;9887:1;9884;9877:12;9831:60;9781:116;:::o;9903:133::-;9946:5;9984:6;9971:20;9962:29;;10000:30;10024:5;10000:30;:::i;:::-;9903:133;;;;:::o;10042:468::-;10107:6;10115;10164:2;10152:9;10143:7;10139:23;10135:32;10132:119;;;10170:79;;:::i;:::-;10132:119;10290:1;10315:53;10360:7;10351:6;10340:9;10336:22;10315:53;:::i;:::-;10305:63;;10261:117;10417:2;10443:50;10485:7;10476:6;10465:9;10461:22;10443:50;:::i;:::-;10433:60;;10388:115;10042:468;;;;;:::o;10516:117::-;10625:1;10622;10615:12;10639:117;10748:1;10745;10738:12;10762:180;10810:77;10807:1;10800:88;10907:4;10904:1;10897:15;10931:4;10928:1;10921:15;10948:281;11031:27;11053:4;11031:27;:::i;:::-;11023:6;11019:40;11161:6;11149:10;11146:22;11125:18;11113:10;11110:34;11107:62;11104:88;;;11172:18;;:::i;:::-;11104:88;11212:10;11208:2;11201:22;10991:238;10948:281;;:::o;11235:129::-;11269:6;11296:20;;:::i;:::-;11286:30;;11325:33;11353:4;11345:6;11325:33;:::i;:::-;11235:129;;;:::o;11370:307::-;11431:4;11521:18;11513:6;11510:30;11507:56;;;11543:18;;:::i;:::-;11507:56;11581:29;11603:6;11581:29;:::i;:::-;11573:37;;11665:4;11659;11655:15;11647:23;;11370:307;;;:::o;11683:146::-;11780:6;11775:3;11770;11757:30;11821:1;11812:6;11807:3;11803:16;11796:27;11683:146;;;:::o;11835:423::-;11912:5;11937:65;11953:48;11994:6;11953:48;:::i;:::-;11937:65;:::i;:::-;11928:74;;12025:6;12018:5;12011:21;12063:4;12056:5;12052:16;12101:3;12092:6;12087:3;12083:16;12080:25;12077:112;;;12108:79;;:::i;:::-;12077:112;12198:54;12245:6;12240:3;12235;12198:54;:::i;:::-;11918:340;11835:423;;;;;:::o;12277:338::-;12332:5;12381:3;12374:4;12366:6;12362:17;12358:27;12348:122;;12389:79;;:::i;:::-;12348:122;12506:6;12493:20;12531:78;12605:3;12597:6;12590:4;12582:6;12578:17;12531:78;:::i;:::-;12522:87;;12338:277;12277:338;;;;:::o;12621:943::-;12716:6;12724;12732;12740;12789:3;12777:9;12768:7;12764:23;12760:33;12757:120;;;12796:79;;:::i;:::-;12757:120;12916:1;12941:53;12986:7;12977:6;12966:9;12962:22;12941:53;:::i;:::-;12931:63;;12887:117;13043:2;13069:53;13114:7;13105:6;13094:9;13090:22;13069:53;:::i;:::-;13059:63;;13014:118;13171:2;13197:53;13242:7;13233:6;13222:9;13218:22;13197:53;:::i;:::-;13187:63;;13142:118;13327:2;13316:9;13312:18;13299:32;13358:18;13350:6;13347:30;13344:117;;;13380:79;;:::i;:::-;13344:117;13485:62;13539:7;13530:6;13519:9;13515:22;13485:62;:::i;:::-;13475:72;;13270:287;12621:943;;;;;;;:::o;13570:117::-;13679:1;13676;13669:12;13693:117;13802:1;13799;13792:12;13830:553;13888:8;13898:6;13948:3;13941:4;13933:6;13929:17;13925:27;13915:122;;13956:79;;:::i;:::-;13915:122;14069:6;14056:20;14046:30;;14099:18;14091:6;14088:30;14085:117;;;14121:79;;:::i;:::-;14085:117;14235:4;14227:6;14223:17;14211:29;;14289:3;14281:4;14273:6;14269:17;14259:8;14255:32;14252:41;14249:128;;;14296:79;;:::i;:::-;14249:128;13830:553;;;;;:::o;14389:529::-;14460:6;14468;14517:2;14505:9;14496:7;14492:23;14488:32;14485:119;;;14523:79;;:::i;:::-;14485:119;14671:1;14660:9;14656:17;14643:31;14701:18;14693:6;14690:30;14687:117;;;14723:79;;:::i;:::-;14687:117;14836:65;14893:7;14884:6;14873:9;14869:22;14836:65;:::i;:::-;14818:83;;;;14614:297;14389:529;;;;;:::o;14924:89::-;14960:7;15000:6;14993:5;14989:18;14978:29;;14924:89;;;:::o;15019:115::-;15104:23;15121:5;15104:23;:::i;:::-;15099:3;15092:36;15019:115;;:::o;15140:218::-;15231:4;15269:2;15258:9;15254:18;15246:26;;15282:69;15348:1;15337:9;15333:17;15324:6;15282:69;:::i;:::-;15140:218;;;;:::o;15364:474::-;15432:6;15440;15489:2;15477:9;15468:7;15464:23;15460:32;15457:119;;;15495:79;;:::i;:::-;15457:119;15615:1;15640:53;15685:7;15676:6;15665:9;15661:22;15640:53;:::i;:::-;15630:63;;15586:117;15742:2;15768:53;15813:7;15804:6;15793:9;15789:22;15768:53;:::i;:::-;15758:63;;15713:118;15364:474;;;;;:::o;15844:175::-;15984:27;15980:1;15972:6;15968:14;15961:51;15844:175;:::o;16025:366::-;16167:3;16188:67;16252:2;16247:3;16188:67;:::i;:::-;16181:74;;16264:93;16353:3;16264:93;:::i;:::-;16382:2;16377:3;16373:12;16366:19;;16025:366;;;:::o;16397:419::-;16563:4;16601:2;16590:9;16586:18;16578:26;;16650:9;16644:4;16640:20;16636:1;16625:9;16621:17;16614:47;16678:131;16804:4;16678:131;:::i;:::-;16670:139;;16397:419;;;:::o;16822:222::-;16962:34;16958:1;16950:6;16946:14;16939:58;17031:5;17026:2;17018:6;17014:15;17007:30;16822:222;:::o;17050:366::-;17192:3;17213:67;17277:2;17272:3;17213:67;:::i;:::-;17206:74;;17289:93;17378:3;17289:93;:::i;:::-;17407:2;17402:3;17398:12;17391:19;;17050:366;;;:::o;17422:419::-;17588:4;17626:2;17615:9;17611:18;17603:26;;17675:9;17669:4;17665:20;17661:1;17650:9;17646:17;17639:47;17703:131;17829:4;17703:131;:::i;:::-;17695:139;;17422:419;;;:::o;17847:228::-;17987:34;17983:1;17975:6;17971:14;17964:58;18056:11;18051:2;18043:6;18039:15;18032:36;17847:228;:::o;18081:366::-;18223:3;18244:67;18308:2;18303:3;18244:67;:::i;:::-;18237:74;;18320:93;18409:3;18320:93;:::i;:::-;18438:2;18433:3;18429:12;18422:19;;18081:366;;;:::o;18453:419::-;18619:4;18657:2;18646:9;18642:18;18634:26;;18706:9;18700:4;18696:20;18692:1;18681:9;18677:17;18670:47;18734:131;18860:4;18734:131;:::i;:::-;18726:139;;18453:419;;;:::o;18878:180::-;18926:77;18923:1;18916:88;19023:4;19020:1;19013:15;19047:4;19044:1;19037:15;19064:320;19108:6;19145:1;19139:4;19135:12;19125:22;;19192:1;19186:4;19182:12;19213:18;19203:81;;19269:4;19261:6;19257:17;19247:27;;19203:81;19331:2;19323:6;19320:14;19300:18;19297:38;19294:84;;19350:18;;:::i;:::-;19294:84;19115:269;19064:320;;;:::o;19390:200::-;19559:24;19554:3;19547:37;19390:200;:::o;19596:148::-;19698:11;19735:3;19720:18;;19596:148;;;;:::o;19750:390::-;19856:3;19884:39;19917:5;19884:39;:::i;:::-;19939:89;20021:6;20016:3;19939:89;:::i;:::-;19932:96;;20037:65;20095:6;20090:3;20083:4;20076:5;20072:16;20037:65;:::i;:::-;20127:6;20122:3;20118:16;20111:23;;19860:280;19750:390;;;;:::o;20146:542::-;20369:3;20384:138;20518:3;20384:138;:::i;:::-;20547:2;20542:3;20538:12;20531:19;;20567:95;20658:3;20649:6;20567:95;:::i;:::-;20560:102;;20679:3;20672:10;;20146:542;;;;:::o;20694:180::-;20742:77;20739:1;20732:88;20839:4;20836:1;20829:15;20863:4;20860:1;20853:15;20880:191;20920:3;20939:20;20957:1;20939:20;:::i;:::-;20934:25;;20973:20;20991:1;20973:20;:::i;:::-;20968:25;;21016:1;21013;21009:9;21002:16;;21037:3;21034:1;21031:10;21028:36;;;21044:18;;:::i;:::-;21028:36;20880:191;;;;:::o;21077:244::-;21217:34;21213:1;21205:6;21201:14;21194:58;21286:27;21281:2;21273:6;21269:15;21262:52;21077:244;:::o;21327:366::-;21469:3;21490:67;21554:2;21549:3;21490:67;:::i;:::-;21483:74;;21566:93;21655:3;21566:93;:::i;:::-;21684:2;21679:3;21675:12;21668:19;;21327:366;;;:::o;21699:419::-;21865:4;21903:2;21892:9;21888:18;21880:26;;21952:9;21946:4;21942:20;21938:1;21927:9;21923:17;21916:47;21980:131;22106:4;21980:131;:::i;:::-;21972:139;;21699:419;;;:::o;22124:316::-;22264:34;22260:1;22252:6;22248:14;22241:58;22333:34;22328:2;22320:6;22316:15;22309:59;22402:30;22397:2;22389:6;22385:15;22378:55;22124:316;:::o;22446:366::-;22588:3;22609:67;22673:2;22668:3;22609:67;:::i;:::-;22602:74;;22685:93;22774:3;22685:93;:::i;:::-;22803:2;22798:3;22794:12;22787:19;;22446:366;;;:::o;22818:419::-;22984:4;23022:2;23011:9;23007:18;22999:26;;23071:9;23065:4;23061:20;23057:1;23046:9;23042:17;23035:47;23099:131;23225:4;23099:131;:::i;:::-;23091:139;;22818:419;;;:::o;23243:307::-;23383:34;23379:1;23371:6;23367:14;23360:58;23452:34;23447:2;23439:6;23435:15;23428:59;23521:21;23516:2;23508:6;23504:15;23497:46;23243:307;:::o;23556:366::-;23698:3;23719:67;23783:2;23778:3;23719:67;:::i;:::-;23712:74;;23795:93;23884:3;23795:93;:::i;:::-;23913:2;23908:3;23904:12;23897:19;;23556:366;;;:::o;23928:419::-;24094:4;24132:2;24121:9;24117:18;24109:26;;24181:9;24175:4;24171:20;24167:1;24156:9;24152:17;24145:47;24209:131;24335:4;24209:131;:::i;:::-;24201:139;;23928:419;;;:::o;24353:410::-;24393:7;24416:20;24434:1;24416:20;:::i;:::-;24411:25;;24450:20;24468:1;24450:20;:::i;:::-;24445:25;;24505:1;24502;24498:9;24527:30;24545:11;24527:30;:::i;:::-;24516:41;;24706:1;24697:7;24693:15;24690:1;24687:22;24667:1;24660:9;24640:83;24617:139;;24736:18;;:::i;:::-;24617:139;24401:362;24353:410;;;;:::o;24769:194::-;24809:4;24829:20;24847:1;24829:20;:::i;:::-;24824:25;;24863:20;24881:1;24863:20;:::i;:::-;24858:25;;24907:1;24904;24900:9;24892:17;;24931:1;24925:4;24922:11;24919:37;;;24936:18;;:::i;:::-;24919:37;24769:194;;;;:::o;24969:147::-;25070:11;25107:3;25092:18;;24969:147;;;;:::o;25122:114::-;;:::o;25242:398::-;25401:3;25422:83;25503:1;25498:3;25422:83;:::i;:::-;25415:90;;25514:93;25603:3;25514:93;:::i;:::-;25632:1;25627:3;25623:11;25616:18;;25242:398;;;:::o;25646:379::-;25830:3;25852:147;25995:3;25852:147;:::i;:::-;25845:154;;26016:3;26009:10;;25646:379;;;:::o;26031:166::-;26171:18;26167:1;26159:6;26155:14;26148:42;26031:166;:::o;26203:366::-;26345:3;26366:67;26430:2;26425:3;26366:67;:::i;:::-;26359:74;;26442:93;26531:3;26442:93;:::i;:::-;26560:2;26555:3;26551:12;26544:19;;26203:366;;;:::o;26575:419::-;26741:4;26779:2;26768:9;26764:18;26756:26;;26828:9;26822:4;26818:20;26814:1;26803:9;26799:17;26792:47;26856:131;26982:4;26856:131;:::i;:::-;26848:139;;26575:419;;;:::o;27000:97::-;27059:6;27087:3;27077:13;;27000:97;;;;:::o;27103:141::-;27152:4;27175:3;27167:11;;27198:3;27195:1;27188:14;27232:4;27229:1;27219:18;27211:26;;27103:141;;;:::o;27250:93::-;27287:6;27334:2;27329;27322:5;27318:14;27314:23;27304:33;;27250:93;;;:::o;27349:107::-;27393:8;27443:5;27437:4;27433:16;27412:37;;27349:107;;;;:::o;27462:393::-;27531:6;27581:1;27569:10;27565:18;27604:97;27634:66;27623:9;27604:97;:::i;:::-;27722:39;27752:8;27741:9;27722:39;:::i;:::-;27710:51;;27794:4;27790:9;27783:5;27779:21;27770:30;;27843:4;27833:8;27829:19;27822:5;27819:30;27809:40;;27538:317;;27462:393;;;;;:::o;27861:142::-;27911:9;27944:53;27962:34;27971:24;27989:5;27971:24;:::i;:::-;27962:34;:::i;:::-;27944:53;:::i;:::-;27931:66;;27861:142;;;:::o;28009:75::-;28052:3;28073:5;28066:12;;28009:75;;;:::o;28090:269::-;28200:39;28231:7;28200:39;:::i;:::-;28261:91;28310:41;28334:16;28310:41;:::i;:::-;28302:6;28295:4;28289:11;28261:91;:::i;:::-;28255:4;28248:105;28166:193;28090:269;;;:::o;28365:73::-;28410:3;28365:73;:::o;28444:189::-;28521:32;;:::i;:::-;28562:65;28620:6;28612;28606:4;28562:65;:::i;:::-;28497:136;28444:189;;:::o;28639:186::-;28699:120;28716:3;28709:5;28706:14;28699:120;;;28770:39;28807:1;28800:5;28770:39;:::i;:::-;28743:1;28736:5;28732:13;28723:22;;28699:120;;;28639:186;;:::o;28831:543::-;28932:2;28927:3;28924:11;28921:446;;;28966:38;28998:5;28966:38;:::i;:::-;29050:29;29068:10;29050:29;:::i;:::-;29040:8;29036:44;29233:2;29221:10;29218:18;29215:49;;;29254:8;29239:23;;29215:49;29277:80;29333:22;29351:3;29333:22;:::i;:::-;29323:8;29319:37;29306:11;29277:80;:::i;:::-;28936:431;;28921:446;28831:543;;;:::o;29380:117::-;29434:8;29484:5;29478:4;29474:16;29453:37;;29380:117;;;;:::o;29503:169::-;29547:6;29580:51;29628:1;29624:6;29616:5;29613:1;29609:13;29580:51;:::i;:::-;29576:56;29661:4;29655;29651:15;29641:25;;29554:118;29503:169;;;;:::o;29677:295::-;29753:4;29899:29;29924:3;29918:4;29899:29;:::i;:::-;29891:37;;29961:3;29958:1;29954:11;29948:4;29945:21;29937:29;;29677:295;;;;:::o;29977:1403::-;30101:44;30141:3;30136;30101:44;:::i;:::-;30210:18;30202:6;30199:30;30196:56;;;30232:18;;:::i;:::-;30196:56;30276:38;30308:4;30302:11;30276:38;:::i;:::-;30361:67;30421:6;30413;30407:4;30361:67;:::i;:::-;30455:1;30484:2;30476:6;30473:14;30501:1;30496:632;;;;31172:1;31189:6;31186:84;;;31245:9;31240:3;31236:19;31223:33;31214:42;;31186:84;31296:67;31356:6;31349:5;31296:67;:::i;:::-;31290:4;31283:81;31145:229;30466:908;;30496:632;30548:4;30544:9;30536:6;30532:22;30582:37;30614:4;30582:37;:::i;:::-;30641:1;30655:215;30669:7;30666:1;30663:14;30655:215;;;30755:9;30750:3;30746:19;30733:33;30725:6;30718:49;30806:1;30798:6;30794:14;30784:24;;30853:2;30842:9;30838:18;30825:31;;30692:4;30689:1;30685:12;30680:17;;30655:215;;;30898:6;30889:7;30886:19;30883:186;;;30963:9;30958:3;30954:19;30941:33;31006:48;31048:4;31040:6;31036:17;31025:9;31006:48;:::i;:::-;30998:6;30991:64;30906:163;30883:186;31115:1;31111;31103:6;31099:14;31095:22;31089:4;31082:36;30503:625;;;30466:908;;30076:1304;;;29977:1403;;;:::o;31386:207::-;31555:31;31550:3;31543:44;31386:207;:::o;31599:542::-;31822:3;31837:138;31971:3;31837:138;:::i;:::-;32000:2;31995:3;31991:12;31984:19;;32020:95;32111:3;32102:6;32020:95;:::i;:::-;32013:102;;32132:3;32125:10;;31599:542;;;;:::o;32147:225::-;32287:34;32283:1;32275:6;32271:14;32264:58;32356:8;32351:2;32343:6;32339:15;32332:33;32147:225;:::o;32378:366::-;32520:3;32541:67;32605:2;32600:3;32541:67;:::i;:::-;32534:74;;32617:93;32706:3;32617:93;:::i;:::-;32735:2;32730:3;32726:12;32719:19;;32378:366;;;:::o;32750:419::-;32916:4;32954:2;32943:9;32939:18;32931:26;;33003:9;32997:4;32993:20;32989:1;32978:9;32974:17;32967:47;33031:131;33157:4;33031:131;:::i;:::-;33023:139;;32750:419;;;:::o;33175:182::-;33315:34;33311:1;33303:6;33299:14;33292:58;33175:182;:::o;33363:366::-;33505:3;33526:67;33590:2;33585:3;33526:67;:::i;:::-;33519:74;;33602:93;33691:3;33602:93;:::i;:::-;33720:2;33715:3;33711:12;33704:19;;33363:366;;;:::o;33735:419::-;33901:4;33939:2;33928:9;33924:18;33916:26;;33988:9;33982:4;33978:20;33974:1;33963:9;33959:17;33952:47;34016:131;34142:4;34016:131;:::i;:::-;34008:139;;33735:419;;;:::o;34160:332::-;34281:4;34319:2;34308:9;34304:18;34296:26;;34332:71;34400:1;34389:9;34385:17;34376:6;34332:71;:::i;:::-;34413:72;34481:2;34470:9;34466:18;34457:6;34413:72;:::i;:::-;34160:332;;;;;:::o;34498:137::-;34552:5;34583:6;34577:13;34568:22;;34599:30;34623:5;34599:30;:::i;:::-;34498:137;;;;:::o;34641:345::-;34708:6;34757:2;34745:9;34736:7;34732:23;34728:32;34725:119;;;34763:79;;:::i;:::-;34725:119;34883:1;34908:61;34961:7;34952:6;34941:9;34937:22;34908:61;:::i;:::-;34898:71;;34854:125;34641:345;;;;:::o;34992:180::-;35040:77;35037:1;35030:88;35137:4;35134:1;35127:15;35161:4;35158:1;35151:15;35178:176;35210:1;35227:20;35245:1;35227:20;:::i;:::-;35222:25;;35261:20;35279:1;35261:20;:::i;:::-;35256:25;;35300:1;35290:35;;35305:18;;:::i;:::-;35290:35;35346:1;35343;35339:9;35334:14;;35178:176;;;;:::o;35360:185::-;35400:1;35417:20;35435:1;35417:20;:::i;:::-;35412:25;;35451:20;35469:1;35451:20;:::i;:::-;35446:25;;35490:1;35480:35;;35495:18;;:::i;:::-;35480:35;35537:1;35534;35530:9;35525:14;;35360:185;;;;:::o;35551:233::-;35590:3;35613:24;35631:5;35613:24;:::i;:::-;35604:33;;35659:66;35652:5;35649:77;35646:103;;35729:18;;:::i;:::-;35646:103;35776:1;35769:5;35765:13;35758:20;;35551:233;;;:::o;35790:180::-;35838:77;35835:1;35828:88;35935:4;35932:1;35925:15;35959:4;35956:1;35949:15;35976:595;36204:3;36226:95;36317:3;36308:6;36226:95;:::i;:::-;36219:102;;36338:95;36429:3;36420:6;36338:95;:::i;:::-;36331:102;;36450:95;36541:3;36532:6;36450:95;:::i;:::-;36443:102;;36562:3;36555:10;;35976:595;;;;;;:::o;36577:172::-;36717:24;36713:1;36705:6;36701:14;36694:48;36577:172;:::o;36755:366::-;36897:3;36918:67;36982:2;36977:3;36918:67;:::i;:::-;36911:74;;36994:93;37083:3;36994:93;:::i;:::-;37112:2;37107:3;37103:12;37096:19;;36755:366;;;:::o;37127:419::-;37293:4;37331:2;37320:9;37316:18;37308:26;;37380:9;37374:4;37370:20;37366:1;37355:9;37351:17;37344:47;37408:131;37534:4;37408:131;:::i;:::-;37400:139;;37127:419;;;:::o;37552:181::-;37692:33;37688:1;37680:6;37676:14;37669:57;37552:181;:::o;37739:366::-;37881:3;37902:67;37966:2;37961:3;37902:67;:::i;:::-;37895:74;;37978:93;38067:3;37978:93;:::i;:::-;38096:2;38091:3;38087:12;38080:19;;37739:366;;;:::o;38111:419::-;38277:4;38315:2;38304:9;38300:18;38292:26;;38364:9;38358:4;38354:20;38350:1;38339:9;38335:17;38328:47;38392:131;38518:4;38392:131;:::i;:::-;38384:139;;38111:419;;;:::o;38536:170::-;38676:22;38672:1;38664:6;38660:14;38653:46;38536:170;:::o;38712:366::-;38854:3;38875:67;38939:2;38934:3;38875:67;:::i;:::-;38868:74;;38951:93;39040:3;38951:93;:::i;:::-;39069:2;39064:3;39060:12;39053:19;;38712:366;;;:::o;39084:419::-;39250:4;39288:2;39277:9;39273:18;39265:26;;39337:9;39331:4;39327:20;39323:1;39312:9;39308:17;39301:47;39365:131;39491:4;39365:131;:::i;:::-;39357:139;;39084:419;;;:::o;39509:166::-;39649:18;39645:1;39637:6;39633:14;39626:42;39509:166;:::o;39681:366::-;39823:3;39844:67;39908:2;39903:3;39844:67;:::i;:::-;39837:74;;39920:93;40009:3;39920:93;:::i;:::-;40038:2;40033:3;40029:12;40022:19;;39681:366;;;:::o;40053:419::-;40219:4;40257:2;40246:9;40242:18;40234:26;;40306:9;40300:4;40296:20;40292:1;40281:9;40277:17;40270:47;40334:131;40460:4;40334:131;:::i;:::-;40326:139;;40053:419;;;:::o;40478:98::-;40529:6;40563:5;40557:12;40547:22;;40478:98;;;:::o;40582:168::-;40665:11;40699:6;40694:3;40687:19;40739:4;40734:3;40730:14;40715:29;;40582:168;;;;:::o;40756:373::-;40842:3;40870:38;40902:5;40870:38;:::i;:::-;40924:70;40987:6;40982:3;40924:70;:::i;:::-;40917:77;;41003:65;41061:6;41056:3;41049:4;41042:5;41038:16;41003:65;:::i;:::-;41093:29;41115:6;41093:29;:::i;:::-;41088:3;41084:39;41077:46;;40846:283;40756:373;;;;:::o;41135:640::-;41330:4;41368:3;41357:9;41353:19;41345:27;;41382:71;41450:1;41439:9;41435:17;41426:6;41382:71;:::i;:::-;41463:72;41531:2;41520:9;41516:18;41507:6;41463:72;:::i;:::-;41545;41613:2;41602:9;41598:18;41589:6;41545:72;:::i;:::-;41664:9;41658:4;41654:20;41649:2;41638:9;41634:18;41627:48;41692:76;41763:4;41754:6;41692:76;:::i;:::-;41684:84;;41135:640;;;;;;;:::o;41781:141::-;41837:5;41868:6;41862:13;41853:22;;41884:32;41910:5;41884:32;:::i;:::-;41781:141;;;;:::o;41928:349::-;41997:6;42046:2;42034:9;42025:7;42021:23;42017:32;42014:119;;;42052:79;;:::i;:::-;42014:119;42172:1;42197:63;42252:7;42243:6;42232:9;42228:22;42197:63;:::i;:::-;42187:73;;42143:127;41928:349;;;;:::o;42307:874::-;42410:3;42447:5;42441:12;42476:36;42502:9;42476:36;:::i;:::-;42528:89;42610:6;42605:3;42528:89;:::i;:::-;42521:96;;42648:1;42637:9;42633:17;42664:1;42659:166;;;;42839:1;42834:341;;;;42626:549;;42659:166;42743:4;42739:9;42728;42724:25;42719:3;42712:38;42805:6;42798:14;42791:22;42783:6;42779:35;42774:3;42770:45;42763:52;;42659:166;;42834:341;42901:38;42933:5;42901:38;:::i;:::-;42961:1;42975:154;42989:6;42986:1;42983:13;42975:154;;;43063:7;43057:14;43053:1;43048:3;43044:11;43037:35;43113:1;43104:7;43100:15;43089:26;;43011:4;43008:1;43004:12;42999:17;;42975:154;;;43158:6;43153:3;43149:16;43142:23;;42841:334;;42626:549;;42414:767;;42307:874;;;;:::o;43187:181::-;43355:6;43350:3;43343:19;43187:181;:::o;43374:853::-;43689:3;43711:92;43799:3;43790:6;43711:92;:::i;:::-;43704:99;;43820:95;43911:3;43902:6;43820:95;:::i;:::-;43813:102;;43932:95;44023:3;44014:6;43932:95;:::i;:::-;43925:102;;44037:137;44170:3;44037:137;:::i;:::-;44199:1;44194:3;44190:11;44183:18;;44218:3;44211:10;;43374:853;;;;;;:::o

Swarm Source

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