ETH Price: $3,268.97 (+0.80%)
Gas: 2 Gwei

Token

Meme City (MEMECITY)
 

Overview

Max Total Supply

1,000 MEMECITY

Holders

8

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
3.263836050318690424 MEMECITY
0x8b714478902df5fa4fa6a8121535d108a059f429
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:
MEMECITY

Compiler Version
v0.8.24+commit.e11b9ed9

Optimization Enabled:
Yes with 420 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

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

/**

 _____ ______   _______   _____ ______   _______           ________  ___  _________    ___    ___ 
|\   _ \  _   \|\  ___ \ |\   _ \  _   \|\  ___ \         |\   ____\|\  \|\___   ___\ |\  \  /  /|
\ \  \\\__\ \  \ \   __/|\ \  \\\__\ \  \ \   __/|        \ \  \___|\ \  \|___ \  \_| \ \  \/  / /
 \ \  \\|__| \  \ \  \_|/_\ \  \\|__| \  \ \  \_|/__       \ \  \    \ \  \   \ \  \   \ \    / / 
  \ \  \    \ \  \ \  \_|\ \ \  \    \ \  \ \  \_|\ \       \ \  \____\ \  \   \ \  \   \/  /  /  
   \ \__\    \ \__\ \_______\ \__\    \ \__\ \_______\       \ \_______\ \__\   \ \__\__/  / /    
    \|__|     \|__|\|_______|\|__|     \|__|\|_______|        \|_______|\|__|    \|__|\___/ /     
                                                                                     \|___|/      

Meme City is a collection based on the ERC404x token standard, consisting of 1,000 buildings,
coins, stickers, and characters that reside on the blockchain.


Telegram: https://t.me/MemeCity404
Twitter: https://twitter.com/MemeCity404
Website: https://memecity404.io


*/

// SPDX-License-Identifier: MIT


pragma solidity ^0.8.20;

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

abstract contract ERC165 is IERC165 {
    /**
     * @dev See {IERC165-supportsInterface}.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return interfaceId == type(IERC165).interfaceId;
    }
}

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

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

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

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

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

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, 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
    ) external;

    /**
     * @dev Transfers `tokenId` token 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;

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

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

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

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

interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

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

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

interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

abstract contract Ownable {
    event OwnershipTransferred(address indexed user, address indexed newOwner);

    error Unauthorized();
    error InvalidOwner();

    address public owner;

    modifier onlyOwner() virtual {
        if (msg.sender != owner) revert Unauthorized();

        _;
    }

    constructor(address _owner) {
        if (_owner == address(0x0)) revert InvalidOwner();

        owner = _owner;

        emit OwnershipTransferred(address(0x0), _owner);
    }

    function transferOwnership(address _owner) public virtual onlyOwner {
        if (_owner == address(0x0)) revert InvalidOwner();

        owner = _owner;

        emit OwnershipTransferred(msg.sender, _owner);
    }

    function revokeOwnership() public virtual onlyOwner {
        owner = address(0x0);

        emit OwnershipTransferred(msg.sender, address(0x0));
    }
}

abstract contract ERC721Receiver {
    function onERC721Received(
        address,
        address,
        uint256,
        bytes calldata
    ) external virtual returns (bytes4) {
        return ERC721Receiver.onERC721Received.selector;
    }
}

library Packer
{
    struct Data
    {
        uint64 _popFrontIndex;
        uint64 _popFrontSign;
        uint64 _nextInternalIndex;
        uint64 _len;
        mapping(uint256 => uint256) _values;
    }

    error OutOfBounds();
    error UnevenEdit();
    error InsaneBulk();

    function push(Data storage self, uint256 valuesInElement, uint256 bitsInValue, uint256 value) internal returns(uint256) {
        unchecked {
            if (self._nextInternalIndex == valuesInElement || self._nextInternalIndex == 0)
            {
                self._values[self._len++] = value;
                self._nextInternalIndex = 1;
            }
            else
            {
                self._values[self._len - 1] += value << (self._nextInternalIndex++ * bitsInValue);
            }

            return (self._len - 1) * valuesInElement + self._nextInternalIndex - 1;
        }
    }

    function pushMany(Data storage self, uint256 valuesInElement, uint256 bitsInValue, uint256[] memory values) internal returns(uint256[] memory) {
        uint256 nextInternalIndex = self._nextInternalIndex;
        uint256 len = self._len;

        uint256 addLen = values.length;
        uint256[] memory returnIndexes = new uint256[](addLen);
        unchecked {
            uint256 currentValue = self._values[len - 1];
            for (uint256 i = 0; i < addLen; ++i) {
                if (nextInternalIndex == valuesInElement || nextInternalIndex == 0)
                {
                    self._values[len - 1] = currentValue;
                    self._values[len++] = values[i];
                    nextInternalIndex = 1;

                    currentValue = values[i];
                }
                else
                {
                    currentValue += values[i] << (nextInternalIndex++ * bitsInValue);
                }

                returnIndexes[i] = (len - 1) * valuesInElement + nextInternalIndex - 1;
            }

            self._values[len - 1] = currentValue;
        }

        self._nextInternalIndex = uint64(nextInternalIndex);
        self._len = uint64(len);

        return returnIndexes;
    }

    function get(Data storage self, uint256 valuesInElement, uint256 bitsInValue, uint256 index) internal view returns(uint256) {
        unchecked
        {
            if (self._len == 0 || index >= (self._len - 1) * valuesInElement + self._nextInternalIndex) {
                revert OutOfBounds();
            }

            uint256 arrIndex = index / valuesInElement;
            uint256 internalIndex = index % valuesInElement;
            uint256 number = self._values[arrIndex];

            if (internalIndex < valuesInElement - 1) {
                number = number >> internalIndex * bitsInValue;
                return number - ((number >> bitsInValue) << bitsInValue);
            }
            else {
                return number >> internalIndex * bitsInValue;
            }
        }
    }

    function edit(Data storage self, uint256 valuesInElement, uint256 bitsInValue, uint256 index, uint256 value) internal {
        unchecked
        {
            if (self._len == 0 || index >= (self._len - 1) * valuesInElement + self._nextInternalIndex) {
                revert OutOfBounds();
            }

            _edit(self, valuesInElement, bitsInValue, index, value);
        }
    }

    function editMany(Data storage self, uint256 valuesInElement, uint256 bitsInValue, uint256[] memory indexes, uint256[] memory values) internal {
        uint256 len = self._len;
        uint256 editLen = indexes.length;

        if (editLen != values.length) {
            revert UnevenEdit();
        }

        if (len == 0) {
            revert OutOfBounds();
        }
        
        unchecked {
            uint256 trueLen = (len - 1) * valuesInElement + self._nextInternalIndex;

            for (uint256 i = 0; i < editLen; ++i) {
                uint256 index = indexes[i];
                uint256 value = values[i];
            
                if (index >= trueLen) {
                    revert OutOfBounds();
                }

                _edit(self, valuesInElement, bitsInValue, index, value);
            }
        }
    }

    function _edit(Data storage self, uint256 valuesInElement, uint256 bitsInValue, uint256 index, uint256 value) private {
        unchecked {
            uint256 arrIndex = index / valuesInElement;
            uint256 internalIndex = index % valuesInElement;
            uint256 number = self._values[arrIndex];
            uint256 shift = internalIndex * bitsInValue;

            if (internalIndex < valuesInElement - 1) {
                number = number >> shift;
                uint256 oldValue = number - ((number >> bitsInValue) << bitsInValue);

                self._values[arrIndex] = self._values[arrIndex] - (oldValue << shift) + (value << shift);
            }
            else {
                self._values[arrIndex] = self._values[arrIndex] - (number >> shift << shift) + (value << shift);
            }
        }
    }

    function pop(Data storage self, uint256 valuesInElement, uint256 bitsInValue) internal returns(uint256) {
        unchecked
        {
            if (self._len == 0) {
                revert OutOfBounds();
            }

            uint256 arrIndex = self._len - 1;
            uint256 internalIndex = self._nextInternalIndex - 1;
            uint256 number = self._values[arrIndex];
            uint256 shift = internalIndex * bitsInValue;
            uint256 oldValue = number >> shift;

            number -= oldValue << shift;

            if (internalIndex == 0) {
                self._nextInternalIndex = uint64(valuesInElement);
                --self._len;
            }
            else {
                --self._nextInternalIndex;
                self._values[arrIndex] = number;
            }

            return oldValue;
        }
    }

    function popMany(Data storage self, uint256 valuesInElement, uint256 bitsInValue, uint256 amount) internal returns(uint256[] memory) {
        uint256 nextInternalIndex = self._nextInternalIndex;
        uint256 len = self._len;

        unchecked {
            if (len == 0 || amount > (len - 1) * valuesInElement + self._nextInternalIndex) {
                revert OutOfBounds();
            }
        }

        uint256[] memory returnValues = new uint256[](amount);
        unchecked {
            uint256 number = self._values[len - 1];
            for (uint256 i = 0; i < amount; ++i) {
                uint256 shift = (nextInternalIndex - 1) * bitsInValue;
                uint256 oldValue = number >> shift;

                number -= oldValue << shift;

                if (nextInternalIndex == 1) {
                    nextInternalIndex = uint128(valuesInElement);
                    --len;

                    number = self._values[len - 1];
                }
                else {
                    --nextInternalIndex;
                }

                returnValues[i] = oldValue;
            }

            if (len > 0) {
                self._values[len - 1] = number;
            }
        }

        self._nextInternalIndex = uint64(nextInternalIndex);
        self._len = uint64(len);

        return returnValues;
    }

    function pull(Data storage self, uint256 valuesInElement, uint256 bitsInValue, uint256 index) internal returns(uint256) {
        uint256 len = self._len;
        if (len == 0) {
            revert OutOfBounds();
        }
        
        unchecked
        {
            uint256 lastIndex = (len - 1) * valuesInElement + self._nextInternalIndex - 1;

            if (index == lastIndex) {
                return pop(self, valuesInElement, bitsInValue);
            }

            return _pull(self, valuesInElement, bitsInValue, index);
        }
    }

    function pullFront(Data storage self, uint256 valuesInElement, uint256 bitsInValue) internal returns(uint256) {
        uint256 len = self._len;
        if (len == 0) {
            revert OutOfBounds();
        }
        
        unchecked
        {
            uint256 lastIndex = (len - 1) * valuesInElement + self._nextInternalIndex - 1;
            uint256 index = _nextPullFrontIndex(self, uint64(lastIndex));

            if (index == lastIndex) {
                return pop(self, valuesInElement, bitsInValue);
            }

            return _pull(self, valuesInElement, bitsInValue, index);
        }
    }

    function pullFrontMany(Data storage self, uint256 valuesInElement, uint256 bitsInValue, uint256 amount) internal returns(uint256[] memory) {
        uint256 len = self._len;
        if (len == 0) {
            revert OutOfBounds();
        }
        
        uint256[] memory returnValues = new uint256[](amount);
        unchecked
        {
            uint256 lastIndex = (len - 1) * valuesInElement + self._nextInternalIndex - 1;

            if (amount > lastIndex + 1) {
                revert OutOfBounds();
            }

            for (uint256 i = 0; i < amount; ++i) {
                uint256 index = _nextPullFrontIndex(self, uint64(lastIndex));

                if (index == lastIndex) {
                    returnValues[i] = pop(self, valuesInElement, bitsInValue);
                    --lastIndex;
                    continue;
                }

                returnValues[i] = _pull(self, valuesInElement, bitsInValue, index);
                --lastIndex;
            }

            return returnValues;
        }
    }

    function _nextPullFrontIndex(Data storage self, uint64 lastIndex) private returns(uint256) {
        unchecked {
            uint64 index = self._popFrontIndex;
            if (self._popFrontSign == 1) {
                if (index < lastIndex) {
                    ++index;
                }
                else {
                    self._popFrontSign = 0;
                    index = lastIndex;
                }
            }
            else {
                if (index > 0) {
                    --index;
                }
                else {
                    self._popFrontSign = 1;
                    index = 0;
                }
            }

            self._popFrontIndex = index;

            return index;
        }
    }

    function _pull(Data storage self, uint256 valuesInElement, uint256 bitsInValue, uint256 index) private returns(uint256) {
        unchecked {
            uint256 arrIndex = index / valuesInElement;
            uint256 internalIndex = index % valuesInElement;

            uint256 number = self._values[arrIndex];
            uint256 shift = internalIndex * bitsInValue;
            uint256 lastValue = pop(self, valuesInElement, bitsInValue);

            uint256 oldValue;
            if (internalIndex < valuesInElement - 1) {
                number = number >> shift;
                oldValue = number - ((number >> bitsInValue) << bitsInValue);
            }
            else {
                oldValue = number >> shift;
            }

            self._values[arrIndex] = self._values[arrIndex] - (oldValue << shift) + (lastValue << shift);

            return oldValue;
        }
    }

    function length(Data storage self, uint256 valuesInElement) internal view returns(uint256) {
        unchecked {
            if (self._len == 0) {
                return 0;
            }

            return (self._len - 1) * valuesInElement + self._nextInternalIndex;
        }
    }
    
    function getBulk(Data storage self, uint256 valuesInElement, uint256 bitsInValue, uint256 indexFrom, uint256 indexTo) internal view returns(uint256[] memory) {
        if (indexFrom > indexTo || indexFrom > 2 ** 32 || indexTo > 2 ** 32) {
            revert InsaneBulk();
        }

        unchecked
        {
            uint256 len = indexTo - indexFrom + 1;

            if (self._len == 0 || indexFrom + len - 1 >= (self._len - 1) * valuesInElement + self._nextInternalIndex) {
                revert OutOfBounds();
            }

            uint256[] memory result = new uint256[](len);

            uint256 arrIndex = indexFrom / valuesInElement;
            uint256 internalIndex = indexFrom % valuesInElement;
            uint256 number = self._values[arrIndex];

            uint256 counterIndex;
            while (counterIndex < len) {
                if (internalIndex < valuesInElement - 1) {
                    uint256 temp = number >> internalIndex * bitsInValue;
                    result[counterIndex] = temp - ((temp >> bitsInValue) << bitsInValue);

                    ++internalIndex;
                }
                else {
                    result[counterIndex] = number >> internalIndex * bitsInValue;

                    ++arrIndex;
                    internalIndex = 0;
                    number = self._values[arrIndex];
                }

                ++counterIndex;
            }

            return result;
        }
    }

    function getWhole(Data storage self, uint256 index) internal view returns(uint256) {
        return self._values[index];
    }
}

abstract contract ERC404XStorage {
    using Packer for Packer.Data;

    uint256 public immutable bIV;
    uint256 public immutable vIE;

    /// @dev Array of owned ids in native representation
    mapping(address => Packer.Data) public _owned;

    /// @dev Tracks indices for the _owned mapping
    Packer.Data internal _ownedIndex;

    Packer.Data public _burned;

    /// @dev Addresses whitelisted from minting / burning for gas savings (pairs, routers, etc)
    mapping(address => uint256) internal _erc721TransferExempt;

    constructor(uint256 _max) {
        uint256 _bitsInValue = Math.log2(_max + 1);
        if (2 ** _bitsInValue < _max + 1) {
            ++_bitsInValue;
        }

        require(_bitsInValue > 0 && _bitsInValue <= 18, "ERC404X: 18 bits is a hard maximum, 15 bits is a recommended maximum");

        bIV = _bitsInValue;
        vIE = 256 / _bitsInValue;

        _ownedIndex.push(vIE, bIV, 0);
    }

    function getOwned(address account, uint256 indexFrom, uint256 indexTo) external view returns(uint256[] memory) {
        uint256 len = _owned[account].length(vIE);
        if (len == 0) {
            return new uint256[](1);
        }

        if (_erc721TransferExempt[account] == 1) {
            if (indexFrom >= len) {
                return new uint256[](1);
            }
            
            unchecked {
                if (indexTo >= len) {
                    indexTo = len - 1;
                }
            }
        }

        return _owned[account].getBulk(vIE, bIV, indexFrom, indexTo);
    }

    function getAllOwned(address account) external view returns(uint256[] memory) {
        uint256 len = _owned[account].length(vIE);
        if (len == 0) {
            return new uint256[](1);
        }

        unchecked {
            return _owned[account].getBulk(vIE, bIV, 0, len - 1);
        }
    }

    function getBurned(uint256 indexFrom, uint256 indexTo) external view returns(uint256[] memory) {
        uint256 len = _burned.length(vIE);
        if (len == 0) {
            return new uint256[](1);
        }

        if (indexFrom >= len) {
            return new uint256[](1);
        }
        
        unchecked {
            if (indexTo >= len) {
                indexTo = len - 1;
            }
        }

        return _burned.getBulk(vIE, bIV, indexFrom, indexTo);
    }

    function getAllBurned() external view returns(uint256[] memory) {
        uint256 len = _burned.length(vIE);
        if (len == 0) {
            return new uint256[](1);
        }
        
        unchecked {
            return _burned.getBulk(vIE, bIV, 0, len - 1);
        }
    }
}


/// @notice ERC404X
///         A gas-efficient, mixed ERC20 / ERC721 implementation
///         with native liquidity and fractionalization.
///
///         An upgraded iteration of ERC404 for increased gas efficiency and built-in reshuffler.
///
/// @dev    In order to support full functionality of ERC20 and ERC721
///         supply assumptions are made that slightly constraint usage.
///         Ensure decimals are sufficiently large (standard 18 recommended)
///         as ids are effectively encoded in the lowest range of amounts.
///
///         NFTs are spent on ERC20 functions in a FILO queue, this is by
///         design.
///
abstract contract ERC404X is ERC165, IERC721, IERC721Metadata, IERC721Enumerable, Ownable, ERC404XStorage {
    using Packer for Packer.Data;

    // Events
    event ERC20Transfer(
        address indexed from,
        address indexed to,
        uint256 amount
    );
    event ERC721Approval(
        address indexed owner,
        address indexed spender,
        uint256 indexed id
    );

    // Errors
    error NotFound();
    error AlreadyExists();
    error InvalidRecipient();
    error InvalidSender();
    error UnsafeRecipient();

    // Metadata
    /// @dev Token name
    string public name;

    /// @dev Token symbol
    string public symbol;

    /// @dev Decimals for fractional representation
    uint8 public immutable decimals;

    /// @dev Total supply in fractionalized representation
    uint256 public immutable totalSupply;

    /// @dev Current mint counter, monotonically increasing to ensure accurate ownership
    uint256 public minted;

    // Mappings
    /// @dev Balance of user in fractional representation
    mapping(address => uint256) public balanceOf;

    /// @dev Allowance of user in fractional representation
    mapping(address => mapping(address => uint256)) public allowance;

    /// @dev Approval in native representaion
    mapping(uint256 => address) public getApproved;

    /// @dev Approval for all in native representation
    mapping(address => mapping(address => bool)) public isApprovedForAll;

    /// @dev Owner of id in native representation
    mapping(uint256 => address) internal _ownerOf;

    mapping(uint256 => uint256) private _reshuffleTempAlreadyEdited;
    mapping(uint256 => uint256) private _reshuffleTempNotEditedYet;

    uint256 immutable unit;

    // Constructor
    constructor(
        string memory _name,
        string memory _symbol,
        uint8 _decimals,
        uint256 _totalNativeSupply,
        address _owner
    ) Ownable(_owner) ERC404XStorage(_totalNativeSupply) {
        name = _name;
        symbol = _symbol;
        decimals = _decimals;
        totalSupply = _totalNativeSupply * (10 ** decimals);

        balanceOf[_owner] = totalSupply;

        _erc721TransferExempt[_owner] = 1;

        unit = 10 ** decimals;
    }

    /// @notice Initialization function to set pairs / etc
    ///         saving gas by avoiding mint / burn on unnecessary targets
    function setERC721TransferExempt(address target, bool state) public onlyOwner {
        _erc721TransferExempt[target] = state ? 1 : 0;
    }

    function erc721TransferExempt(address target) public view returns(bool) {
        return _erc721TransferExempt[target] == 1 ? true : false;
    }

    /// @notice Function to find owner of a given native token
    function ownerOf(uint256 id) public view virtual returns (address owner) {
        owner = _ownerOf[id];

        if (owner == address(0x0) || owner == address(0x1)) {
            revert NotFound();
        }
    }

    /// @notice tokenURI must be implemented by child contract
    function tokenURI(uint256 id) public view virtual returns (string memory);

    /// @notice Function for token approvals
    /// @dev This function assumes id / native if amount less than or equal to current max id
    function approve(
        address spender,
        uint256 amountOrId
    ) public virtual {
        if (amountOrId <= minted && amountOrId > 0) {
            address owner = _ownerOf[amountOrId];

            if (msg.sender != owner && !isApprovedForAll[owner][msg.sender]) {
                revert Unauthorized();
            }

            getApproved[amountOrId] = spender;

            emit Approval(owner, spender, amountOrId);
        } else {
            allowance[msg.sender][spender] = amountOrId;

            emit Approval(msg.sender, spender, amountOrId);
        }
    }

    /// @notice Function native approvals
    function setApprovalForAll(address operator, bool approved) public virtual {
        isApprovedForAll[msg.sender][operator] = approved;

        emit ApprovalForAll(msg.sender, operator, approved);
    }

    /// @notice Function for mixed transfers
    /// @dev This function assumes id / native if amount less than or equal to current max id
    function transferFrom(
        address from,
        address to,
        uint256 amountOrId
    ) public virtual {
        if (amountOrId <= minted) {
            if (from != _ownerOf[amountOrId]) {
                revert InvalidSender();
            }

            if (to == address(0x0) || to == address(0x1)) {
                revert InvalidRecipient();
            }

            if (
                msg.sender != from &&
                !isApprovedForAll[from][msg.sender] &&
                msg.sender != getApproved[amountOrId]
            ) {
                revert Unauthorized();
            }

            balanceOf[from] -= unit;

            unchecked {
                balanceOf[to] += unit;
            }

            _ownerOf[amountOrId] = to;
            delete getApproved[amountOrId];

            uint256 originalOwnedIndex = _ownedIndex.get(vIE, bIV, amountOrId);

            uint256 updatedId = _owned[from].pull(vIE, bIV, originalOwnedIndex);
            uint256 pushedIndex = _owned[to].push(vIE, bIV, amountOrId);

            _ownedIndex.edit(vIE, bIV, updatedId, originalOwnedIndex);
            _ownedIndex.edit(vIE, bIV, amountOrId, pushedIndex);

            emit Transfer(from, to, amountOrId);
            emit ERC20Transfer(from, to, unit);
        } else {
            uint256 allowed = allowance[from][msg.sender];

            if (allowed != type(uint256).max)
                allowance[from][msg.sender] = allowed - amountOrId;

            _transfer(from, to, amountOrId);
        }
    }

    /// @notice Function for fractional transfers
    function transfer(
        address to,
        uint256 amount
    ) public virtual returns (bool) {
        return _transfer(msg.sender, to, amount);
    }

    /// @notice Function for native transfers with contract support
    function safeTransferFrom(
        address from,
        address to,
        uint256 id
    ) public virtual {
        transferFrom(from, to, id);

        if (
            to.code.length != 0 &&
            ERC721Receiver(to).onERC721Received(msg.sender, from, id, "") !=
            ERC721Receiver.onERC721Received.selector
        ) {
            revert UnsafeRecipient();
        }
    }

    /// @notice Function for native transfers with contract support and callback data
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        bytes calldata data
    ) public virtual {
        transferFrom(from, to, id);

        if (
            to.code.length != 0 &&
            ERC721Receiver(to).onERC721Received(msg.sender, from, id, data) !=
            ERC721Receiver.onERC721Received.selector
        ) {
            revert UnsafeRecipient();
        }
    }

    /// @notice Internal function for fractional transfers
    function _transfer(
        address from,
        address to,
        uint256 amount
    ) internal returns (bool) {
        if (to == address(0x0) || to == address(0x1)) {
            revert InvalidRecipient();
        }

        uint256 balanceBeforeSender = balanceOf[from];
        uint256 balanceBeforeReceiver = balanceOf[to];

        balanceOf[from] -= amount;

        unchecked {
            balanceOf[to] += amount;
        }

        uint256 toBurn = (balanceBeforeSender / unit) - (balanceOf[from] / unit);
        uint256 toMint = (balanceOf[to] / unit) - (balanceBeforeReceiver / unit);

        // if the address was unwhitelisted and has less NFTs to burn than its floored ERC-20 balance
        if (_erc721TransferExempt[from] == 0) {
            uint256 fromLen = _owned[from].length(vIE);
            if (fromLen < toBurn) {
                bulkMint(fromLen - toBurn, to);              
            }
        }

        if (_erc721TransferExempt[from] == 0 && _erc721TransferExempt[to] == 0) {
            uint256 toTransfer = Math.min(toBurn, toMint);
            bulkTransfer(toTransfer, from, to);

            if (toBurn > toMint) {
                _burn(from);
            }
            else if (toMint > toBurn) {
                _mint(to);
            }
        }
        else if (_erc721TransferExempt[from] == 1 && _erc721TransferExempt[to] == 0) {
            // if the address is whitelisted but has tokens, treat it as a regular transfer
            uint256 fromLen = _owned[from].length(vIE);
            if (fromLen > 0) {
                toBurn = Math.min(toBurn, fromLen);
                uint256 toTransfer = Math.min(toBurn, toMint);
                bulkTransfer(toTransfer, from, to);
                
                if (toMint >= toTransfer) {
                    toMint -= toTransfer;
                }
                else {
                    toMint = 0;
                }

                if (toBurn > toTransfer) {
                    _burn(from);
                }
            }

            bulkMint(toMint, to);
        }
        else if (_erc721TransferExempt[from] == 0 && _erc721TransferExempt[to] == 1) {
            bulkBurn(toBurn, from);
        }

        emit ERC20Transfer(from, to, amount);
        return true;
    }

    function bulkTransfer(uint256 toTransfer, address from, address to) internal virtual {
        if (toTransfer == 1) {
            uint256 id = _owned[from].pop(vIE, bIV);
            uint256 pushedIndex = _owned[to].push(vIE, bIV, id);

            _ownerOf[id] = to;
            _ownedIndex.edit(vIE, bIV, id, pushedIndex);
            delete getApproved[id];

            emit Transfer(from, to, id);
        }
        else if (toTransfer > 0) {
            uint256[] memory ids = _owned[from].popMany(vIE, bIV, toTransfer);
            uint256[] memory indexes = _owned[to].pushMany(vIE, bIV, ids);

            _ownedIndex.editMany(vIE, bIV, ids, indexes);

            unchecked {
                for (uint256 i = 0; i < toTransfer; ++i) {
                    uint256 id = ids[i];

                    _ownerOf[id] = to;
                    delete getApproved[id];

                    emit Transfer(from, to, id);
                }
            }
        }
    }

    function bulkMint(uint256 toMint, address to) internal virtual {
        if (toMint == 1) {
            _mint(to);
        }
        else if (toMint > 0) {
            unchecked {
                if (minted < totalSupply / unit) {
                    for (uint256 i = 0; i < toMint; ++i) {
                        _mint(to);
                    }
                }
                else {
                    uint256[] memory ids = _burned.pullFrontMany(vIE, bIV, toMint);
                    uint256[] memory indexes = _owned[to].pushMany(vIE, bIV, ids);

                    _ownedIndex.editMany(vIE, bIV, ids, indexes);

                    for (uint256 i = 0; i < toMint; ++i) {
                        uint256 id = ids[i];

                        _ownerOf[id] = to;

                        emit Transfer(address(0x1), to, id);
                    }
                }
            }
        }
    }

    function _mint(address to) internal virtual {
        uint256 id;
        if (minted < totalSupply / unit) {
            id = ++minted;
            _ownedIndex.push(vIE, bIV, _owned[to].push(vIE, bIV, id));

             emit Transfer(_ownerOf[id], to, id);
        }
        else {
            id = _burned.pullFront(vIE, bIV);
            _ownedIndex.edit(vIE, bIV, id, _owned[to].push(vIE, bIV, id));

            emit Transfer(address(0x1), to, id);
        }

        _ownerOf[id] = to;
    }

    function bulkBurn(uint256 toBurn, address from) internal virtual {
        if (toBurn == 1) {
            _burn(from);
        }
        else if (toBurn > 0) {
            uint256[] memory ids = _owned[from].popMany(vIE, bIV, toBurn);
            _burned.pushMany(vIE, bIV, ids);

            unchecked {
                for (uint256 i = 0; i < toBurn; ++i) {
                    uint256 id = ids[i];

                    _ownerOf[id] = address(0x1);
                    delete getApproved[id];

                    emit Transfer(from, address(0x1), id);
                }
            }
        }
    }

    function _burn(address from) internal virtual {
        uint256 id = _owned[from].pop(vIE, bIV);

        _burned.push(vIE, bIV, id);

        _ownerOf[id] = address(0x1);
        delete getApproved[id];

        emit Transfer(from, address(0x1), id);
    }

    function reshuffle(uint256[] memory indexesToEdit, uint256[] memory valuesToPlace, uint256[] memory currentIndexes) public virtual {
        uint256 len = indexesToEdit.length;
        require(len == valuesToPlace.length && len == currentIndexes.length, "ERC404X: reshuffle input length mismatch");

        Packer.Data storage data = _owned[msg.sender];

        unchecked {
            for (uint256 i = 0; i < len; ++i) {
                require(data.get(vIE, bIV, currentIndexes[i]) == valuesToPlace[i], "ERC404X: reshuffle input contains wrong value");
            }
        }

        uint256 editedLen;
        uint256 notEditedLen;
        unchecked {
            for (uint256 i = 0; i < len; ++i) {
                uint256 indexToEdit = indexesToEdit[i];
                uint256 currentIndex = currentIndexes[i];

                if (_reshuffleTempNotEditedYet[indexToEdit] == 0) {
                    _reshuffleTempAlreadyEdited[indexToEdit] = 1;
                    ++editedLen;
                }
                else {
                    _reshuffleTempNotEditedYet[indexToEdit] = 0;
                    --notEditedLen;
                }

                if (_reshuffleTempAlreadyEdited[currentIndex] == 0) {
                    _reshuffleTempNotEditedYet[currentIndex] = 1;
                    ++notEditedLen;
                }
                else {
                    _reshuffleTempAlreadyEdited[currentIndex] = 0;
                    --editedLen;
                }
            }
        }

        data.editMany(vIE, bIV, indexesToEdit, valuesToPlace);
        _ownedIndex.editMany(vIE, bIV, currentIndexes, indexesToEdit);

        require(editedLen == 0 && notEditedLen == 0, "ERC404X: reshuffle input incorrect");
    }

    function _setNameSymbol(
        string memory _name,
        string memory _symbol
    ) internal {
        name = _name;
        symbol = _symbol;
    }
    
    function tokenOfOwnerByIndex(address owner, uint256 index) external view override returns (uint256) {
        if (_erc721TransferExempt[owner] == 1) {
            if (index >= _owned[owner].length(vIE)) {
                return 0;
            }
        }

        return _owned[owner].get(vIE, bIV, index);
    }

    function tokenByIndex(uint256 index) external pure override returns (uint256) {
        index;
        return 0;
    }

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

contract MEMECITY is ERC404X {
    string public dataURI;
    string public baseTokenURI;
    
    string[] colors = ["Blue", "Pink", "Black", "Grey", "Yellow", "Orange"];
    string[] shapes = ["Short", "Medium", "Tall"];
    string[] tags = ["Benance", "Bonk", "TwitterX", "Hodl", "Nvidia", "Wif", "Wagmi", "Bobo", "WallStreetBets", "BTC"];
    string[] coins = ["Bitcoin", "Ethereum", "Tesla", "McDonalds", "DogeCoin", "ShibaInu", "Uniswap", "FTX", "Terra", "Solana"];
    string[] ids = ["Cybertruck", "Wojak", "ElonMusk", "ATM", "Shiba", "Pepe", "Ape", "Bogdanoff", "Vitalik", "Optimus", "Squid", "SmurfCat"];

    constructor() ERC404X("Meme City", "MEMECITY", 18, 1000, msg.sender) {
        dataURI = "https://memecity404.io/nft/";
    }

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

    function setDataURI(string memory _dataURI) public onlyOwner {
        dataURI = _dataURI;
    }

    function setTokenURI(string memory _tokenURI) public onlyOwner {
        baseTokenURI = _tokenURI;
    }

    function setNameSymbol(
        string memory _name,
        string memory _symbol
    ) public onlyOwner {
        _setNameSymbol(_name, _symbol);
    }

    function tokenURI(uint256 id) public view override returns (string memory) {
        if (bytes(baseTokenURI).length > 0) {
            return string.concat(baseTokenURI, Strings.toString(id));
        } else {
            uint256 seed = uint256(keccak256(abi.encodePacked(id + 1))) % 100;
            string memory image;
            string memory _type;
            string memory _color;
            string memory _shape;
            string memory _coin;
            string memory _tag;
            string memory _id;

            if (seed < 60) {
                _type = "Building";
                _color = colors[(seed + id) % colors.length];
                _shape = shapes[(seed + id) % shapes.length];
            } else if (seed < 75) {
                _type = "Sticker";
                _tag = tags[(seed + id) % tags.length];
            } else if (seed < 90) {
                _type = "Logo";
                _coin = coins[(seed + id) % coins.length];
            } else {
                _type = "Character";
                _id = ids[(seed + id) % ids.length];
            }

            image = generateImageURI(_type, _color, _shape, _tag, _coin, _id);

            // Construct the JSON metadata
            string memory jsonPreImage = string.concat(
                string.concat(
                    string.concat('{"name": "Meme City #', Strings.toString(id)),
                    '","description":"A collection of 1,000 buildings, coins, stickers, and characters that reside on the blockchain.","external_url":"https://memecity404.io","image":"'
                ),
                string.concat(dataURI, image)
            );
            string memory jsonPostImage = '';
            if (keccak256(bytes(_type)) == keccak256(bytes("Building"))) {
                jsonPostImage = string.concat(
                    '","attributes":[{"trait_type":"Type","value":"',_type
                );
                jsonPostImage = string.concat(jsonPostImage, '"},{"trait_type":"Color","value":"',_color);
                jsonPostImage = string.concat(jsonPostImage, '"},{"trait_type":"Shape","value":"',_shape);
            } else if (keccak256(bytes(_type)) == keccak256(bytes("Sticker"))) {
                jsonPostImage = string.concat(
                    '","attributes":[{"trait_type":"Type","value":"',_type
                );
                jsonPostImage = string.concat(jsonPostImage, '"},{"trait_type":"Tag","value":"',_tag);
            } else if (keccak256(bytes(_type)) == keccak256(bytes("Logo"))) {
                jsonPostImage = string.concat(
                    '","attributes":[{"trait_type":"Type","value":"',_type
                );
                jsonPostImage = string.concat(jsonPostImage, '"},{"trait_type":"Coin","value":"',_coin);
            } else {
                jsonPostImage = string.concat(
                    '","attributes":[{"trait_type":"Type","value":"',_type
                );
                jsonPostImage = string.concat(jsonPostImage, '"},{"trait_type":"ID","value":"',_id);
            }
            string memory jsonPostTraits = '"}]}';

            // Return the complete token URI
            return string.concat(
                "data:application/json;utf8,",
                string.concat(
                    string.concat(jsonPreImage, jsonPostImage),
                    jsonPostTraits
                )
            );
        }
    }

    function generateImageURI(
        string memory _type,
        string memory _color,
        string memory _shape,
        string memory _tag,
        string memory _coin,
        string memory _id
    ) internal pure returns (string memory) {
        if (keccak256(bytes(_type)) == keccak256(bytes("Building"))) {
            return string.concat(string.concat(string.concat("Building_", _color), "_"), _shape, ".jpg");
        } else if (keccak256(bytes(_type)) == keccak256(bytes("Sticker"))) {
            return string.concat("Sticker_", _tag, ".jpg");
        } else if (keccak256(bytes(_type)) == keccak256(bytes("Logo"))) {
            return string.concat("Logo_", _coin, ".jpg");
        } else {
            return string.concat("Character_", _id, ".jpg");
        }
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"AlreadyExists","type":"error"},{"inputs":[],"name":"InsaneBulk","type":"error"},{"inputs":[],"name":"InvalidOwner","type":"error"},{"inputs":[],"name":"InvalidRecipient","type":"error"},{"inputs":[],"name":"InvalidSender","type":"error"},{"inputs":[],"name":"NotFound","type":"error"},{"inputs":[],"name":"OutOfBounds","type":"error"},{"inputs":[],"name":"Unauthorized","type":"error"},{"inputs":[],"name":"UnevenEdit","type":"error"},{"inputs":[],"name":"UnsafeRecipient","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"ERC20Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"spender","type":"address"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"ERC721Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"user","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"_burned","outputs":[{"internalType":"uint64","name":"_popFrontIndex","type":"uint64"},{"internalType":"uint64","name":"_popFrontSign","type":"uint64"},{"internalType":"uint64","name":"_nextInternalIndex","type":"uint64"},{"internalType":"uint64","name":"_len","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"_owned","outputs":[{"internalType":"uint64","name":"_popFrontIndex","type":"uint64"},{"internalType":"uint64","name":"_popFrontSign","type":"uint64"},{"internalType":"uint64","name":"_nextInternalIndex","type":"uint64"},{"internalType":"uint64","name":"_len","type":"uint64"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"allowance","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"spender","type":"address"},{"internalType":"uint256","name":"amountOrId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"bIV","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"dataURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"decimals","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"}],"name":"erc721TransferExempt","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getAllBurned","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"getAllOwned","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"indexFrom","type":"uint256"},{"internalType":"uint256","name":"indexTo","type":"uint256"}],"name":"getBurned","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"indexFrom","type":"uint256"},{"internalType":"uint256","name":"indexTo","type":"uint256"}],"name":"getOwned","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minted","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"owner","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"indexesToEdit","type":"uint256[]"},{"internalType":"uint256[]","name":"valuesToPlace","type":"uint256[]"},{"internalType":"uint256[]","name":"currentIndexes","type":"uint256[]"}],"name":"reshuffle","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revokeOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_dataURI","type":"string"}],"name":"setDataURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"target","type":"address"},{"internalType":"bool","name":"state","type":"bool"}],"name":"setERC721TransferExempt","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_name","type":"string"},{"internalType":"string","name":"_symbol","type":"string"}],"name":"setNameSymbol","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_tokenURI","type":"string"}],"name":"setTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","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":"to","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"transfer","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"amountOrId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"vIE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"}]

60046101e081815263426c756560e01b610200526101209081526102208281526350696e6b60e01b6102405261014052600561026090815264426c61636b60d81b61028052610160526102a0918252634772657960e01b6102c0526101809190915260066102e08181526559656c6c6f7760d01b610300526101a052610360604052610320818152654f72616e676560d01b610340526101c052620000a791601391620009db565b5060405180606001604052806040518060400160405280600581526020016414da1bdc9d60da1b8152508152602001604051806040016040528060068152602001654d656469756d60d01b81525081526020016040518060400160405280600481526020016315185b1b60e21b81525081525060149060036200012c92919062000a36565b506040805161018081018252600761014082019081526642656e616e636560c81b610160830152815281518083018352600480825263426f6e6b60e01b602083810191909152808401929092528351808501855260088152670a8eed2e8e8cae4b60c31b81840152838501528351808501855281815263121bd91b60e21b8184015260608401528351808501855260068152654e766964696160d01b818401526080840152835180850185526003808252622bb4b360e91b8285015260a08501919091528451808601865260058152645761676d6960d81b8185015260c08501528451808601865291825263426f626f60e01b8284015260e084019190915283518085018552600e81526d57616c6c5374726565744265747360901b81840152610100840152835180850190945283526242544360e81b908301526101208101919091526200028090601590600a62000a7f565b50604080516101808101825260076101408201818152662134ba31b7b4b760c91b610160840152825282518084018452600880825267457468657265756d60c01b60208381019190915280850192909252845180860186526005808252645465736c6160d81b82850152858701919091528551808701875260098152684d63446f6e616c647360b81b81850152606086015285518087018752828152672237b3b2a1b7b4b760c11b81850152608086015285518087018752918252675368696261496e7560c01b8284015260a085019190915284518086018652928352660556e69737761760cc1b8383015260c084019290925283518085018552600381526208ca8b60eb1b8183015260e08401528351808501855291825264546572726160d81b8282015261010083019190915282518084019093526006835265536f6c616e6160d01b90830152610120810191909152620003e290601690600a62000a7f565b50604080516101c081018252600a6101808201908152694379626572747275636b60b01b6101a0830152815281518083018352600580825264576f6a616b60d81b6020838101919091528084019290925283518085018552600880825267456c6f6e4d75736b60c01b82850152848601919091528451808601865260038082526241544d60e81b8286015260608601919091528551808701875283815264536869626160d81b8186015260808601528551808701875260048152635065706560e01b8186015260a0860152855180870187529081526241706560e81b8185015260c08501528451808601865260098152682137b3b230b737b33360b91b8185015260e085015284518086018652600780825266566974616c696b60c81b8286015261010086019190915285518087018752908152664f7074696d757360c81b81850152610120850152845180860186529182526414dc5d5a5960da1b82840152610140840191909152835180850190945283526714db5d5c9990d85d60c21b908301526101608101919091526200057e90601790600c62000ac8565b503480156200058b575f80fd5b5060408051808201825260098152684d656d65204369747960b81b602080830191909152825180840190935260088352674d454d454349545960c01b908301529060126103e833818180620005f3576040516349e27cff60e01b815260040160405180910390fd5b5f80546001600160a01b0319166001600160a01b03831690811782556040519091907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908290a3505f620006536200064d83600162000b9a565b62000819565b90506200066282600162000b9a565b6200066f82600262000ca9565b10156200068457620006818162000cbd565b90505b5f8111801562000695575060128111155b6200071a5760405162461bcd60e51b8152602060048201526044602482018190527f455243343034583a203138206269747320697320612068617264206d6178696d908201527f756d2c20313520626974732069732061207265636f6d6d656e646564206d6178606482015263696d756d60e01b608482015260a40160405180910390fd5b60808190526200072d8161010062000cd8565b60a081905260805162000744916002915f620008b5565b5060079150620007579050868262000d96565b50600862000766858262000d96565b5060ff831660c08190526200077d90600a62000e62565b62000789908362000e72565b60e08190526001600160a01b0382165f908152600a6020818152604080842094909455600690529190206001905560c051620007c59162000e62565b61010052505060408051808201909152601b81527f68747470733a2f2f6d656d65636974793430342e696f2f6e66742f000000000060208201526011935062000812925090508262000d96565b5062000e8c565b5f80608083901c156200082e57608092831c92015b604083901c156200084157604092831c92015b602083901c156200085457602092831c92015b601083901c156200086757601092831c92015b600883901c156200087a57600892831c92015b600483901c156200088d57600492831c92015b600283901c15620008a057600292831c92015b600183901c15620008af576001015b92915050565b83545f90600160801b90046001600160401b0316841480620008e657508454600160801b90046001600160401b0316155b15620009495784546001600160401b03600160c01b808304821660018181019093169091026001600160c01b039093169290921787555f9182528601602052604090208290558454600160801b600160c01b031916600160801b178555620009a8565b845460016001600160401b03600160801b80840482168381018316909102600160801b600160c01b0319909416939093178089555f19600160c01b909104821601165f90815290870160205260409020805491850284901b9190910190555b5083545f19600160c01b82046001600160401b03908116820181168602600160801b909304169190910101949350505050565b828054828255905f5260205f2090810192821562000a24579160200282015b8281111562000a24578251829062000a13908262000d96565b5091602001919060010190620009fa565b5062000a3292915062000b11565b5090565b828054828255905f5260205f2090810192821562000a24579160200282015b8281111562000a24578251829062000a6e908262000d96565b509160200191906001019062000a55565b828054828255905f5260205f2090810192821562000a24579160200282015b8281111562000a24578251829062000ab7908262000d96565b509160200191906001019062000a9e565b828054828255905f5260205f2090810192821562000a24579160200282015b8281111562000a24578251829062000b00908262000d96565b509160200191906001019062000ae7565b8082111562000a32575f62000b27828262000b31565b5060010162000b11565b50805462000b3f9062000d0c565b5f825580601f1062000b4f575050565b601f0160209004905f5260205f209081019062000b6d919062000b70565b50565b5b8082111562000a32575f815560010162000b71565b634e487b7160e01b5f52601160045260245ffd5b80820180821115620008af57620008af62000b86565b600181815b8085111562000bf057815f190482111562000bd45762000bd462000b86565b8085161562000be257918102915b93841c939080029062000bb5565b509250929050565b5f8262000c0857506001620008af565b8162000c1657505f620008af565b816001811462000c2f576002811462000c3a5762000c5a565b6001915050620008af565b60ff84111562000c4e5762000c4e62000b86565b50506001821b620008af565b5060208310610133831016604e8410600b841016171562000c7f575081810a620008af565b62000c8b838362000bb0565b805f190482111562000ca15762000ca162000b86565b029392505050565b5f62000cb6838362000bf8565b9392505050565b5f6001820162000cd15762000cd162000b86565b5060010190565b5f8262000cf357634e487b7160e01b5f52601260045260245ffd5b500490565b634e487b7160e01b5f52604160045260245ffd5b600181811c9082168062000d2157607f821691505b60208210810362000d4057634e487b7160e01b5f52602260045260245ffd5b50919050565b601f82111562000d9157805f5260205f20601f840160051c8101602085101562000d6d5750805b601f840160051c820191505b8181101562000d8e575f815560010162000d79565b50505b505050565b81516001600160401b0381111562000db25762000db262000cf8565b62000dca8162000dc3845462000d0c565b8462000d46565b602080601f83116001811462000e00575f841562000de85750858301515b5f19600386901b1c1916600185901b17855562000e5a565b5f85815260208120601f198616915b8281101562000e305788860151825594840194600190910190840162000e0f565b508582101562000e4e57878501515f19600388901b60f8161c191681555b505060018460011b0185555b505050505050565b5f62000cb660ff84168362000bf8565b8082028115828204841417620008af57620008af62000b86565b60805160a05160c05160e05161010051614de3620010d75f395f818161099f015281816109ee01528181610c5a0152818161251a015281816125440152818161257b015281816125be01528181613039015261368b01525f81816103170152818161305a01526136ac01525f61037f01525f81816102ba01528181610a4301528181610aaa01528181610b1101528181610b6001528181610bae01528181610da401528181610df201528181610f4d01528181610fa501528181611066015281816110d50152818161112a015281816111af015281816112b601528181611474015281816114c201528181611f56015281816120100152818161262a0152818161274f015281816130b30152818161311a0152818161316901528181613262015281816132c80152818161333d015281816133ed01528181613454015281816134a301528181613598015281816135e60152818161370c015281816137a301528181613808015281816138ea015261393901525f818161062401528181610a6401528181610acb01528181610b3201528181610b8101528181610bcf01528181610e1301528181610fc6015281816110f7015281816111d0015281816112d701528181611495015281816114e301528181612031015281816130d40152818161313b0152818161318a01528181613283015281816132e90152818161335e0152818161340e01528181613475015281816134c4015281816135b9015281816136070152818161372e015281816137c40152818161382a0152818161390b015261395a0152614de35ff3fe608060405234801561000f575f80fd5b5060043610610234575f3560e01c806370a0823111610135578063c6e672b9116100b4578063e0df5b6f11610079578063e0df5b6f146105df578063e985e9c5146105f2578063eac9c9751461061f578063f28ca1dd14610646578063f2fde38b1461064e575f80fd5b8063c6e672b914610574578063c87b56dd14610587578063d547cfb71461059a578063db6ac3a4146105a2578063dd62ed3e146105b5575f80fd5b806395d89b41116100fa57806395d89b41146105205780639c05266814610528578063a22cb4651461053b578063a9059cbb1461054e578063b88d4fde14610561575f80fd5b806370a08231146104825780637717228a146104a15780638413b03a146104b45780638bd4e9fd146104c75780638da5cb5b1461050e575f80fd5b80632b968958116101c15780634f02c420116101865780634f02c4201461042b5780634f6ccce714610434578063504334c2146104475780635c8855811461045a5780636352211e1461046f575f80fd5b80632b9689581461035f5780632f745c5914610367578063313ce5671461037a578063405e3cc1146103b357806342842e0e14610418575f80fd5b8063095ea7b311610207578063095ea7b3146102ea57806309f0ef65146102ff57806318160ddd1461031257806318d217c31461033957806323b872dd1461034c575f80fd5b806301ffc9a71461023857806306fdde0314610260578063081812fc1461027557806308245fac146102b5575b5f80fd5b61024b6102463660046140f2565b610661565b60405190151581526020015b60405180910390f35b610268610671565b604051610257919061412f565b61029d610283366004614161565b600c6020525f90815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610257565b6102dc7f000000000000000000000000000000000000000000000000000000000000000081565b604051908152602001610257565b6102fd6102f836600461418e565b6106fd565b005b61024b61030d3660046141b6565b610828565b6102dc7f000000000000000000000000000000000000000000000000000000000000000081565b6102fd61034736600461427e565b610855565b6102fd61035a3660046142af565b61088a565b6102fd610d04565b6102dc61037536600461418e565b610d68565b6103a17f000000000000000000000000000000000000000000000000000000000000000081565b60405160ff9091168152602001610257565b6004546103e5906001600160401b0380821691600160401b8104821691600160801b8204811691600160c01b90041684565b604080516001600160401b0395861681529385166020850152918416918301919091529091166060820152608001610257565b6102fd6104263660046142af565b610e3f565b6102dc60095481565b6102dc610442366004614161565b505f90565b6102fd6104553660046142e8565b610f10565b610462610f43565b6040516102579190614347565b61029d61047d366004614161565b610ff5565b6102dc6104903660046141b6565b600a6020525f908152604090205481565b6104626104af3660046141b6565b611045565b6104626104c236600461438a565b611120565b6103e56104d53660046141b6565b60016020525f90815260409020546001600160401b0380821691600160401b8104821691600160801b8204811691600160c01b90041684565b5f5461029d906001600160a01b031681565b6102686111fe565b6102fd61053636600461441b565b61120b565b6102fd61054936600461449c565b611575565b61024b61055c36600461418e565b6115e0565b6102fd61056f3660046144d5565b6115ec565b6102fd61058236600461449c565b6116ac565b610268610595366004614161565b611707565b610268611f28565b6104626105b0366004614567565b611f35565b6102dc6105c3366004614597565b600b60209081525f928352604080842090915290825290205481565b6102fd6105ed36600461427e565b612060565b61024b610600366004614597565b600d60209081525f928352604080842090915290825290205460ff1681565b6102dc7f000000000000000000000000000000000000000000000000000000000000000081565b610268612095565b6102fd61065c3660046141b6565b6120a2565b5f61066b8261213c565b92915050565b6007805461067e906145c8565b80601f01602080910402602001604051908101604052809291908181526020018280546106aa906145c8565b80156106f55780601f106106cc576101008083540402835291602001916106f5565b820191905f5260205f20905b8154815290600101906020018083116106d857829003601f168201915b505050505081565b600954811115801561070e57505f81115b156107d5575f818152600e60205260409020546001600160a01b031633811480159061075d57506001600160a01b0381165f908152600d6020908152604080832033845290915290205460ff16155b1561077a576040516282b42960e81b815260040160405180910390fd5b5f828152600c602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b335f818152600b602090815260408083206001600160a01b038716808552925280832085905551849391927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a45b5050565b6001600160a01b0381165f9081526006602052604081205460011461084d575f61066b565b600192915050565b5f546001600160a01b0316331461087e576040516282b42960e81b815260040160405180910390fd5b60116108248282614644565b6009548111610c98575f818152600e60205260409020546001600160a01b038481169116146108cc57604051636edaef2f60e11b815260040160405180910390fd5b6001600160a01b03821615806108eb57506001600160a01b0382166001145b1561090957604051634e46966960e11b815260040160405180910390fd5b336001600160a01b0384161480159061094557506001600160a01b0383165f908152600d6020908152604080832033845290915290205460ff16155b801561096757505f818152600c60205260409020546001600160a01b03163314155b15610984576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0383165f908152600a6020526040812080547f000000000000000000000000000000000000000000000000000000000000000092906109cb908490614713565b90915550506001600160a01b0382165f818152600a6020908152604080832080547f0000000000000000000000000000000000000000000000000000000000000000019055848352600e825280832080546001600160a01b03199081169095179055600c90915281208054909216909155610a8960027f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008561218b565b6001600160a01b0385165f90815260016020526040812091925090610af0907f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000085612251565b6001600160a01b0385165f90815260016020526040812091925090610b57907f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000876122e4565b9050610ba760027f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008587612409565b610bf560027f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008785612409565b83856001600160a01b0316876001600160a01b03165f80516020614d8e83398151915260405160405180910390a4846001600160a01b0316866001600160a01b03167fe59fdd36d0d223c0c7d996db7ad796880f45e1936cb0bb7ac102e7082e0314877f0000000000000000000000000000000000000000000000000000000000000000604051610c8891815260200190565b60405180910390a3505050505050565b6001600160a01b0383165f908152600b602090815260408083203384529091529020545f198114610cf157610ccd8282614713565b6001600160a01b0385165f908152600b602090815260408083203384529091529020555b610cfc848484612476565b50505b505050565b5f546001600160a01b03163314610d2d576040516282b42960e81b815260040160405180910390fd5b5f80546001600160a01b031916815560405133907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3565b6001600160a01b0382165f90815260066020526040812054600103610dd5576001600160a01b0383165f908152600160205260409020610dc8907f000000000000000000000000000000000000000000000000000000000000000061287e565b8210610dd557505f61066b565b6001600160a01b0383165f908152600160205260409020610e38907f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008561218b565b9392505050565b610e4a83838361088a565b6001600160a01b0382163b15801590610ef25750604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401525f608484015290919084169063150b7a029060a4016020604051808303815f875af1158015610ec1573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ee59190614726565b6001600160e01b03191614155b15610cff57604051633da6393160e01b815260040160405180910390fd5b5f546001600160a01b03163314610f39576040516282b42960e81b815260040160405180910390fd5b61082482826128ca565b60605f610f7160047f000000000000000000000000000000000000000000000000000000000000000061287e565b9050805f03610f9e5760408051600180825281830190925290602080830190803683370190505091505090565b610fef60047f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000005f5f1986016128e3565b91505090565b5f818152600e60205260409020546001600160a01b031680158061102257506001600160a01b0381166001145b156110405760405163c5723b5160e01b815260040160405180910390fd5b919050565b6001600160a01b0381165f9081526001602052604081206060919061108a907f000000000000000000000000000000000000000000000000000000000000000061287e565b9050805f036110b8576040805160018082528183019092529060208083019080368337019050509392505050565b6001600160a01b0383165f908152600160205260408120610e38917f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000905f1986016128e3565b60605f61114e60047f000000000000000000000000000000000000000000000000000000000000000061287e565b9050805f0361118c5760015b604051908082528060200260200182016040528015611183578160200160208202803683370190505b5091505061066b565b80841061119a57600161115a565b8083106111a8576001810392505b6111f660047f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000087876128e3565b949350505050565b6008805461067e906145c8565b825182518114801561121d5750815181145b61127f5760405162461bcd60e51b815260206004820152602860248201527f455243343034583a20726573687566666c6520696e707574206c656e677468206044820152670dad2e6dac2e8c6d60c31b60648201526084015b60405180910390fd5b335f908152600160205260408120905b8281101561138c578481815181106112a9576112a9614741565b60200260200101516113217f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000087858151811061130857611308614741565b60200260200101518661218b909392919063ffffffff16565b146113845760405162461bcd60e51b815260206004820152602d60248201527f455243343034583a20726573687566666c6520696e70757420636f6e7461696e60448201526c732077726f6e672076616c756560981b6064820152608401611276565b60010161128f565b505f805f5b8481101561146d575f8882815181106113ac576113ac614741565b602002602001015190505f8783815181106113c9576113c9614741565b6020026020010151905060105f8381526020019081526020015f20545f03611408575f828152600f60205260409020600190819055949094019361141d565b5f828152601060205260408120555f19909301925b5f818152600f6020526040812054900361144e575f8181526010602052604090206001908190559390930192611463565b5f818152600f60205260408120555f19909401935b5050600101611391565b506114bb837f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008a8a612abd565b61150960027f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000888b612abd565b81158015611515575080155b61156c5760405162461bcd60e51b815260206004820152602260248201527f455243343034583a20726573687566666c6520696e70757420696e636f72726560448201526118dd60f21b6064820152608401611276565b50505050505050565b335f818152600d602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b5f610e38338484612476565b6115f785858561088a565b6001600160a01b0384163b1580159061168e5750604051630a85bd0160e11b808252906001600160a01b0386169063150b7a02906116419033908a90899089908990600401614755565b6020604051808303815f875af115801561165d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116819190614726565b6001600160e01b03191614155b15610cfc57604051633da6393160e01b815260040160405180910390fd5b5f546001600160a01b031633146116d5576040516282b42960e81b815260040160405180910390fd5b806116e0575f6116e3565b60015b6001600160a01b039092165f90815260066020526040902060ff9290921690915550565b60605f60128054611717906145c8565b9050111561175157601261172a83612bb3565b60405160200161173b9291906147a7565b6040516020818303038152906040529050919050565b5f606461175f84600161482a565b60405160200161177191815260200190565b604051602081830303815290604052805190602001205f1c6117939190614851565b90506060806060806060806060603c881015611948576040805180820190915260088152674275696c64696e6760c01b602082015260138054919750906117da8c8b61482a565b6117e49190614851565b815481106117f4576117f4614741565b905f5260205f20018054611807906145c8565b80601f0160208091040260200160405190810160405280929190818152602001828054611833906145c8565b801561187e5780601f106118555761010080835404028352916020019161187e565b820191905f5260205f20905b81548152906001019060200180831161186157829003601f168201915b50505050509450601480805490508b8a611898919061482a565b6118a29190614851565b815481106118b2576118b2614741565b905f5260205f200180546118c5906145c8565b80601f01602080910402602001604051908101604052809291908181526020018280546118f1906145c8565b801561193c5780601f106119135761010080835404028352916020019161193c565b820191905f5260205f20905b81548152906001019060200180831161191f57829003601f168201915b50505050509350611bf5565b604b881015611a315760408051808201909152600781526629ba34b1b5b2b960c91b602082015260158054919750906119818c8b61482a565b61198b9190614851565b8154811061199b5761199b614741565b905f5260205f200180546119ae906145c8565b80601f01602080910402602001604051908101604052809291908181526020018280546119da906145c8565b8015611a255780601f106119fc57610100808354040283529160200191611a25565b820191905f5260205f20905b815481529060010190602001808311611a0857829003601f168201915b50505050509150611bf5565b605a881015611b17576040805180820190915260048152634c6f676f60e01b60208201526016805491975090611a678c8b61482a565b611a719190614851565b81548110611a8157611a81614741565b905f5260205f20018054611a94906145c8565b80601f0160208091040260200160405190810160405280929190818152602001828054611ac0906145c8565b8015611b0b5780601f10611ae257610100808354040283529160200191611b0b565b820191905f5260205f20905b815481529060010190602001808311611aee57829003601f168201915b50505050509250611bf5565b60408051808201909152600981526821b430b930b1ba32b960b91b60208201526017805491975090611b498c8b61482a565b611b539190614851565b81548110611b6357611b63614741565b905f5260205f20018054611b76906145c8565b80601f0160208091040260200160405190810160405280929190818152602001828054611ba2906145c8565b8015611bed5780601f10611bc457610100808354040283529160200191611bed565b820191905f5260205f20905b815481529060010190602001808311611bd057829003601f168201915b505050505090505b611c03868686858786612c42565b96505f611c0f8b612bb3565b604051602001611c1f9190614864565b60408051601f1981840301815290829052611c3c916020016148a8565b604051602081830303815290604052601189604051602001611c5f9291906147a7565b60408051601f1981840301815290829052611c7d929160200161498c565b60408051601f19818403018152602083810183525f8452825180840190935260088352674275696c64696e6760c01b928101929092528951918a01919091209092507f7a254e3b6d7043f05172f0bfae1c54492680f217da417830c8e1bad77fe4777801611d545787604051602001611cf691906149b1565b60405160208183030381529060405290508087604051602001611d1a929190614a0c565b60405160208183030381529060405290508086604051602001611d3e929190614a6f565b6040516020818303038152906040529050611e98565b60408051808201909152600781526629ba34b1b5b2b960c91b6020918201528851908901207f9bc406424f6d588cd366501a231e55786e6fc074b0d4db0d9aebbc94fcd7463b01611dd45787604051602001611db091906149b1565b60405160208183030381529060405290508084604051602001611d3e929190614ac6565b6040805180820190915260048152634c6f676f60e01b6020918201528851908901207f8223dbd323bca9041f93b278b5f4c77daf60ba0482f645af1d0f4b2188d300a601611e515787604051602001611e2d91906149b1565b60405160208183030381529060405290508085604051602001611d3e929190614b1e565b87604051602001611e6291906149b1565b60405160208183030381529060405290508083604051602001611e86929190614b80565b60405160208183030381529060405290505b5f60405180604001604052806004815260200163227d5d7d60e01b81525090508282604051602001611ecb92919061498c565b60408051601f1981840301815290829052611eea91839060200161498c565b60408051601f1981840301815290829052611f0791602001614bd7565b6040516020818303038152906040529b505050505050505050505050919050565b6012805461067e906145c8565b6001600160a01b0383165f90815260016020526040812060609190611f7a907f000000000000000000000000000000000000000000000000000000000000000061287e565b9050805f03611fb85760015b604051908082528060200260200182016040528015611faf578160200160208202803683370190505b50915050610e38565b6001600160a01b0385165f90815260066020526040902054600103611ff357808410611fe5576001611f86565b808310611ff3576001810392505b6001600160a01b0385165f908152600160205260409020612057907f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000087876128e3565b95945050505050565b5f546001600160a01b03163314612089576040516282b42960e81b815260040160405180910390fd5b60126108248282614644565b6011805461067e906145c8565b5f546001600160a01b031633146120cb576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0381166120f2576040516349e27cff60e01b815260040160405180910390fd5b5f80546001600160a01b0319166001600160a01b0383169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b5f6001600160e01b031982166380ac58cd60e01b148061216c57506001600160e01b03198216635b5e139f60e01b145b8061066b57506301ffc9a760e01b6001600160e01b031983161461066b565b83545f90600160c01b90046001600160401b031615806121cf57508454600160801b81046001600160401b03908116600160c01b90920481165f1901168502018210155b156121ed57604051632d0483c560e21b815260040160405180910390fd5b5f8483816121fd576121fd61483d565b0490505f8584816122105761221061483d565b5f84815260018a01602052604090205491900691505f198701821015612244579085021c80851c851b900391506111f69050565b9085021c91506111f69050565b83545f90600160c01b90046001600160401b031680820361228557604051632d0483c560e21b815260040160405180910390fd5b5f6001875f0160109054906101000a90046001600160401b03166001600160401b0316876001850302010390508084036122cd576122c4878787612dc4565b925050506111f6565b6122d987878787612eee565b979650505050505050565b83545f90600160801b90046001600160401b031684148061231457508454600160801b90046001600160401b0316155b156123765784546001600160401b03600160c01b808304821660018181019093169091026001600160c01b039093169290921787555f918252860160205260409020829055845467ffffffffffffffff60801b1916600160801b1785556123d6565b845460016001600160401b03600160801b8084048216838101831690910267ffffffffffffffff60801b19909416939093178089555f19600160c01b909104821601165f90815290870160205260409020805491850284901b9190910190555b5083545f19600160c01b82046001600160401b03908116820181168602600160801b909304169190910101949350505050565b8454600160c01b90046001600160401b0316158061244b57508454600160801b81046001600160401b03908116600160c01b90920481165f1901168502018210155b1561246957604051632d0483c560e21b815260040160405180910390fd5b610cfc8585858585612f86565b5f6001600160a01b038316158061249657506001600160a01b0383166001145b156124b457604051634e46966960e11b815260040160405180910390fd5b6001600160a01b038085165f818152600a6020526040808220805494881683529082205492825285916124e78386614713565b90915550506001600160a01b038086165f908152600a602052604080822080548801905591881681529081205461253f907f000000000000000000000000000000000000000000000000000000000000000090614c1b565b6125697f000000000000000000000000000000000000000000000000000000000000000085614c1b565b6125739190614713565b90505f6125a07f000000000000000000000000000000000000000000000000000000000000000084614c1b565b6001600160a01b0388165f908152600a60205260409020546125e3907f000000000000000000000000000000000000000000000000000000000000000090614c1b565b6125ed9190614713565b6001600160a01b0389165f908152600660205260408120549192500361266d576001600160a01b0388165f90815260016020526040812061264e907f000000000000000000000000000000000000000000000000000000000000000061287e565b90508281101561266b5761266b6126658483614713565b89613020565b505b6001600160a01b0388165f908152600660205260409020541580156126a757506001600160a01b0387165f90815260066020526040902054155b156126f1575f6126b78383613228565b90506126c4818a8a61323d565b818311156126da576126d58961357b565b6126eb565b828211156126eb576126eb88613685565b50612823565b6001600160a01b0388165f90815260066020526040902054600114801561272d57506001600160a01b0387165f90815260066020526040902054155b156127d8576001600160a01b0388165f908152600160205260408120612773907f000000000000000000000000000000000000000000000000000000000000000061287e565b905080156127ce576127858382613228565b92505f6127928484613228565b905061279f818b8b61323d565b8083106127b7576127b08184614713565b92506127bb565b5f92505b808411156127cc576127cc8a61357b565b505b6126eb8289613020565b6001600160a01b0388165f9081526006602052604090205415801561281457506001600160a01b0387165f908152600660205260409020546001145b156128235761282382896138b6565b866001600160a01b0316886001600160a01b03167fe59fdd36d0d223c0c7d996db7ad796880f45e1936cb0bb7ac102e7082e0314878860405161286891815260200190565b60405180910390a3506001979650505050505050565b81545f90600160c01b90046001600160401b0316810361289f57505f61066b565b509054600160801b81046001600160401b03908116600160c01b90920481165f190116919091020190565b60076128d68382614644565b506008610cff8282614644565b6060818311806128f7575064010000000083115b80612906575064010000000082115b156129245760405163079c3cff60e11b815260040160405180910390fd5b855483830360010190600160c01b90046001600160401b03161580612976575086545f19600160c01b82046001600160401b03908116820181168902600160801b909304169190910185830190910110155b1561299457604051632d0483c560e21b815260040160405180910390fd5b5f816001600160401b038111156129ad576129ad6141cf565b6040519080825280602002602001820160405280156129d6578160200160208202803683370190505b5090505f8786816129e9576129e961483d565b0490505f8887816129fc576129fc61483d565b5f84815260018d0160205260408120549290910692505b85811015612aad5760018b03831015612a61578451838b0283901c90818c1c8c1b820390879084908110612a4957612a49614741565b60200260200101818152505083600101935050612aa5565b89830282901c858281518110612a7957612a79614741565b6020026020010181815250508360010193505f92508b6001015f8581526020019081526020015f205491505b600101612a13565b50929a9950505050505050505050565b845482518251600160c01b9092046001600160401b0316918114612af457604051636176207d60e11b815260040160405180910390fd5b815f03612b1457604051632d0483c560e21b815260040160405180910390fd5b8654600160801b90046001600160401b03165f1983018702015f5b82811015612ba8575f868281518110612b4a57612b4a614741565b602002602001015190505f868381518110612b6757612b67614741565b60200260200101519050838210612b9157604051632d0483c560e21b815260040160405180910390fd5b612b9e8b8b8b8585612f86565b5050600101612b2f565b505050505050505050565b60605f612bbf83613a0c565b60010190505f816001600160401b03811115612bdd57612bdd6141cf565b6040519080825280601f01601f191660200182016040528015612c07576020820181803683370190505b5090508181016020015b5f19016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084612c1157509392505050565b6040805180820190915260088152674275696c64696e6760c01b6020918201528651908701206060907f7a254e3b6d7043f05172f0bfae1c54492680f217da417830c8e1bad77fe4777801612cf45785604051602001612ca29190614c2e565b60408051601f1981840301815290829052612cbf91602001614c5e565b60408051601f1981840301815290829052612cde918790602001614c82565b6040516020818303038152906040529050612dba565b60408051808201909152600781526629ba34b1b5b2b960c91b6020918201528751908801207f9bc406424f6d588cd366501a231e55786e6fc074b0d4db0d9aebbc94fcd7463b01612d505783604051602001612cde9190614cbf565b6040805180820190915260048152634c6f676f60e01b6020918201528751908801207f8223dbd323bca9041f93b278b5f4c77daf60ba0482f645af1d0f4b2188d300a601612da95782604051602001612cde9190614cfc565b81604051602001612cde9190614d36565b9695505050505050565b82545f90600160c01b90046001600160401b03168103612df757604051632d0483c560e21b815260040160405180910390fd5b83545f196001600160401b03600160c01b83048116820181165f8181526001890160205260408120549194600160801b900483169093019091169185830282811c80821b909303929091849003612ea05788545f19600160c01b6001600160401b03808c16600160801b0267ffffffffffffffff60801b198516811783900482169390930116026001600160c01b039091166001600160801b0390921691909117178955612ee2565b88545f196001600160401b03600160801b808404821692909201160267ffffffffffffffff60801b199091161789555f85815260018a01602052604090208390555b98975050505050505050565b5f80848381612eff57612eff61483d565b0490505f858481612f1257612f1261483d565b5f84815260018a01602052604081205492909106925086830290612f378a8a8a612dc4565b90505f60018a03851015612f56575091811c9182881c881b8303612f5b565b5082821c5b5f95865260018b016020526040909520805486841b90039190921b0190555090915050949350505050565b5f848381612f9657612f9661483d565b0490505f858481612fa957612fa961483d565b5f84815260018a01602052604090205491900691508582025f198801831015612ff7575f84815260018a0160205260409020805492821c80891c891b8103831b90930386831b019055612ba8565b5f84815260018a0160205260409020805483831c831b900386831b019055505050505050505050565b816001036130315761082481613685565b8115610824577f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000816130865761308661483d565b0460095410156130ab575f5b82811015610cff576130a382613685565b600101613092565b5f6130f960047f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000086613aed565b6001600160a01b0383165f90815260016020526040812091925090613160907f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000085613c42565b90506131b060027f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008585612abd565b5f5b84811015610cfc575f8382815181106131cd576131cd614741565b6020908102919091018101515f818152600e909252604080832080546001600160a01b0319166001600160a01b038a169081179091559051919350839290916001915f80516020614d8e83398151915291a4506001016131b2565b5f8183106132365781610e38565b5090919050565b826001036133ca576001600160a01b0382165f9081526001602052604081206132a7907f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000612dc4565b6001600160a01b0383165f9081526001602052604081209192509061330e907f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000856122e4565b5f838152600e6020526040902080546001600160a01b0319166001600160a01b038616179055905061338460027f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008585612409565b5f828152600c602052604080822080546001600160a01b03191690555183916001600160a01b0386811692908816915f80516020614d8e83398151915291a45050505050565b8215610cff576001600160a01b0382165f908152600160205260408120613433907f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000087613dfb565b6001600160a01b0383165f9081526001602052604081209192509061349a907f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000085613c42565b90506134ea60027f00000000000000000000000000000000000000000000000000000000000000007f00000000000000000000000000000000000000000000000000000000000000008585612abd565b5f5b85811015613573575f83828151811061350757613507614741565b6020908102919091018101515f818152600e8352604080822080546001600160a01b03808c166001600160a01b03199283168117909355600c90965282842080549091169055905192945084939092908a16915f80516020614d8e83398151915291a4506001016134ec565b505050505050565b6001600160a01b0381165f9081526001602052604081206135dd907f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000612dc4565b905061362c60047f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000846122e4565b505f818152600e60209081526040808320805460016001600160a01b03199182168117909255600c90935281842080549093169092555183926001600160a01b038616915f80516020614d8e8339815191529190a45050565b5f6136d07f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000614c1b565b600954101561379c5760095f81546136e790614d75565b91829055506001600160a01b0383165f908152600160205260409020909150613764907f0000000000000000000000000000000000000000000000000000000000000000907f00000000000000000000000000000000000000000000000000000000000000009061375a908383876122e4565b60029291906122e4565b505f818152600e602052604080822054905183926001600160a01b038087169316915f80516020614d8e8339815191529190a4613889565b6137e860047f00000000000000000000000000000000000000000000000000000000000000007f0000000000000000000000000000000000000000000000000000000000000000613f97565b6001600160a01b0383165f908152600160205260409020909150613863907f0000000000000000000000000000000000000000000000000000000000000000907f0000000000000000000000000000000000000000000000000000000000000000908490613858908484846122e4565b600293929190612409565b60405181906001600160a01b038416906001905f80516020614d8e833981519152905f90a45b5f908152600e6020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b816001036138c7576108248161357b565b8115610824576001600160a01b0381165f908152600160205260408120613930907f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000086613dfb565b905061397f60047f00000000000000000000000000000000000000000000000000000000000000007f000000000000000000000000000000000000000000000000000000000000000084613c42565b505f5b83811015613a06575f82828151811061399d5761399d614741565b6020908102919091018101515f818152600e83526040808220805460016001600160a01b03199182168117909255600c9095528183208054909516909455519193508392916001600160a01b038816915f80516020614d8e83398151915291a450600101613982565b50505050565b5f807a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310613a54577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000830492506040015b6d04ee2d6d415b85acef81000000008310613a80576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310613a9e57662386f26fc10000830492506010015b6305f5e1008310613ab6576305f5e100830492506008015b6127108310613aca57612710830492506004015b60648310613adc576064830492506002015b600a831061066b5760010192915050565b8354606090600160c01b90046001600160401b03165f819003613b2357604051632d0483c560e21b815260040160405180910390fd5b5f836001600160401b03811115613b3c57613b3c6141cf565b604051908082528060200260200182016040528015613b65578160200160208202803683370190505b508754909150600160801b90046001600160401b03165f1983810188029190910190810190851115613baa57604051632d0483c560e21b815260040160405180910390fd5b5f5b85811015613c35575f613bbf8a8461401e565b9050828103613bfc57613bd38a8a8a612dc4565b848381518110613be557613be5614741565b6020908102919091010152505f1990910190613c2d565b613c088a8a8a84612eee565b848381518110613c1a57613c1a614741565b6020908102919091010152505f19909101905b600101613bac565b5090979650505050505050565b835481516060916001600160401b03600160801b8204811692600160c01b909204811691905f908290811115613c7a57613c7a6141cf565b604051908082528060200260200182016040528015613ca3578160200160208202803683370190505b505f1984015f90815260018b0160205260408120549192505b83811015613da35789861480613cd0575085155b15613d49575f1985015f90815260018c01602052604090208290558751889082908110613cff57613cff614741565b60200260200101518b6001015f8780600101985081526020019081526020015f208190555060019550878181518110613d3a57613d3a614741565b60200260200101519150613d73565b888680600101975002888281518110613d6457613d64614741565b6020026020010151901b820191505b6001868b60018803020103838281518110613d9057613d90614741565b6020908102919091010152600101613cbc565b505f1984015f90815260018b01602052604090205588546001600160801b0316600160801b6001600160401b03958616026001600160c01b031617600160c01b94909316939093029190911790965595945050505050565b83546060906001600160401b03600160801b8204811691600160c01b900416801580613e3e57508654600160801b90046001600160401b03165f19820187020184115b15613e5c57604051632d0483c560e21b815260040160405180910390fd5b5f846001600160401b03811115613e7557613e756141cf565b604051908082528060200260200182016040528015613e9e578160200160208202803683370190505b505f1983015f90815260018a0160205260408120549192505b86811015613f35575f198501880282811c80821b909303926001879003613f065760011986015f90815260018d0160205260409020546001600160801b038c1697505f19909601959350613f0d565b5f19909601955b80858481518110613f2057613f20614741565b60209081029190910101525050600101613eb7565b508215613f53575f1983015f90815260018a01602052604090208190555b5087546001600160801b0316600160801b6001600160401b03948516026001600160c01b031617600160c01b92909316919091029190911790955550929392505050565b82545f90600160c01b90046001600160401b0316808203613fcb57604051632d0483c560e21b815260040160405180910390fd5b8454600160801b90046001600160401b03165f19828101860291909101015f613ff4878361401e565b905081810361401257614008878787612dc4565b9350505050610e38565b6122d987878784612eee565b81545f906001600160401b0380821691600160401b90041660010361407d57826001600160401b0316816001600160401b0316101561405f576001016140b4565b5082546fffffffffffffffff000000000000000019168355816140b4565b6001600160401b03811615614094575f19016140b4565b5082546fffffffffffffffff00000000000000001916600160401b1783555f5b83546001600160401b0390911667ffffffffffffffff1990911681178455905092915050565b6001600160e01b0319811681146140ef575f80fd5b50565b5f60208284031215614102575f80fd5b8135610e38816140da565b5f5b8381101561412757818101518382015260200161410f565b50505f910152565b602081525f825180602084015261414d81604085016020870161410d565b601f01601f19169190910160400192915050565b5f60208284031215614171575f80fd5b5035919050565b80356001600160a01b0381168114611040575f80fd5b5f806040838503121561419f575f80fd5b6141a883614178565b946020939093013593505050565b5f602082840312156141c6575f80fd5b610e3882614178565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b038111828210171561420b5761420b6141cf565b604052919050565b5f82601f830112614222575f80fd5b81356001600160401b0381111561423b5761423b6141cf565b61424e601f8201601f19166020016141e3565b818152846020838601011115614262575f80fd5b816020850160208301375f918101602001919091529392505050565b5f6020828403121561428e575f80fd5b81356001600160401b038111156142a3575f80fd5b6111f684828501614213565b5f805f606084860312156142c1575f80fd5b6142ca84614178565b92506142d860208501614178565b9150604084013590509250925092565b5f80604083850312156142f9575f80fd5b82356001600160401b038082111561430f575f80fd5b61431b86838701614213565b93506020850135915080821115614330575f80fd5b5061433d85828601614213565b9150509250929050565b602080825282518282018190525f9190848201906040850190845b8181101561437e57835183529284019291840191600101614362565b50909695505050505050565b5f806040838503121561439b575f80fd5b50508035926020909101359150565b5f82601f8301126143b9575f80fd5b813560206001600160401b038211156143d4576143d46141cf565b8160051b6143e38282016141e3565b92835284810182019282810190878511156143fc575f80fd5b83870192505b848310156122d957823582529183019190830190614402565b5f805f6060848603121561442d575f80fd5b83356001600160401b0380821115614443575f80fd5b61444f878388016143aa565b94506020860135915080821115614464575f80fd5b614470878388016143aa565b93506040860135915080821115614485575f80fd5b50614492868287016143aa565b9150509250925092565b5f80604083850312156144ad575f80fd5b6144b683614178565b9150602083013580151581146144ca575f80fd5b809150509250929050565b5f805f805f608086880312156144e9575f80fd5b6144f286614178565b945061450060208701614178565b93506040860135925060608601356001600160401b0380821115614522575f80fd5b818801915088601f830112614535575f80fd5b813581811115614543575f80fd5b896020828501011115614554575f80fd5b9699959850939650602001949392505050565b5f805f60608486031215614579575f80fd5b61458284614178565b95602085013595506040909401359392505050565b5f80604083850312156145a8575f80fd5b6145b183614178565b91506145bf60208401614178565b90509250929050565b600181811c908216806145dc57607f821691505b6020821081036145fa57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f821115610cff57805f5260205f20601f840160051c810160208510156146255750805b601f840160051c820191505b81811015610cfc575f8155600101614631565b81516001600160401b0381111561465d5761465d6141cf565b6146718161466b84546145c8565b84614600565b602080601f8311600181146146a4575f841561468d5750858301515b5f19600386901b1c1916600185901b178555613573565b5f85815260208120601f198616915b828110156146d2578886015182559484019460019091019084016146b3565b50858210156146ef57878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561066b5761066b6146ff565b5f60208284031215614736575f80fd5b8151610e38816140da565b634e487b7160e01b5f52603260045260245ffd5b5f6001600160a01b03808816835280871660208401525084604083015260806060830152826080830152828460a08401375f60a0848401015260a0601f19601f85011683010190509695505050505050565b5f8084546147b4816145c8565b600182811680156147cc57600181146147e15761480d565b60ff198416875282151583028701945061480d565b885f526020805f205f5b858110156148045781548a8201529084019082016147eb565b50505082870194505b50505050835161482181836020880161410d565b01949350505050565b8082018082111561066b5761066b6146ff565b634e487b7160e01b5f52601260045260245ffd5b5f8261485f5761485f61483d565b500690565b7f7b226e616d65223a20224d656d6520436974792023000000000000000000000081525f825161489b81601585016020870161410d565b9190910160150192915050565b5f82516148b981846020870161410d565b7f222c226465736372697074696f6e223a224120636f6c6c656374696f6e206f669201918252507f20312c303030206275696c64696e67732c20636f696e732c20737469636b657260208201527f732c20616e642063686172616374657273207468617420726573696465206f6e60408201527f2074686520626c6f636b636861696e2e222c2265787465726e616c5f75726c2260608201527f3a2268747470733a2f2f6d656d65636974793430342e696f222c22696d616765608082015262111d1160e91b60a082015260a301919050565b5f835161499d81846020880161410d565b83519083019061482181836020880161410d565b7f222c2261747472696275746573223a5b7b2274726169745f74797065223a225481526d3cb8329116113b30b63ab2911d1160911b60208201525f82516149ff81602e85016020870161410d565b91909101602e0192915050565b5f8351614a1d81846020880161410d565b80830190507f227d2c7b2274726169745f74797065223a22436f6c6f72222c2276616c7565228152611d1160f11b60208201528351614a6381602284016020880161410d565b01602201949350505050565b5f8351614a8081846020880161410d565b80830190507f227d2c7b2274726169745f74797065223a225368617065222c2276616c7565228152611d1160f11b60208201528351614a6381602284016020880161410d565b5f8351614ad781846020880161410d565b80830190507f227d2c7b2274726169745f74797065223a22546167222c2276616c7565223a2281528351614b1281602084016020880161410d565b01602001949350505050565b5f8351614b2f81846020880161410d565b80830190507f227d2c7b2274726169745f74797065223a22436f696e222c2276616c7565223a8152601160f91b60208201528351614b7481602184016020880161410d565b01602101949350505050565b5f8351614b9181846020880161410d565b7f227d2c7b2274726169745f74797065223a224944222c2276616c7565223a22009083019081528351614bcb81601f84016020880161410d565b01601f01949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b757466382c000000000081525f8251614c0e81601b85016020870161410d565b91909101601b0192915050565b5f82614c2957614c2961483d565b500490565b684275696c64696e675f60b81b81525f8251614c5181600985016020870161410d565b9190910160090192915050565b5f8251614c6f81846020870161410d565b605f60f81b920191825250600101919050565b5f8351614c9381846020880161410d565b835190830190614ca781836020880161410d565b632e6a706760e01b9101908152600401949350505050565b67537469636b65725f60c01b81525f8251614ce181600885016020870161410d565b632e6a706760e01b6008939091019283015250600c01919050565b644c6f676f5f60d81b81525f8251614d1b81600585016020870161410d565b632e6a706760e01b6005939091019283015250600901919050565b694368617261637465725f60b01b81525f8251614d5a81600a85016020870161410d565b632e6a706760e01b600a939091019283015250600e01919050565b5f60018201614d8657614d866146ff565b506001019056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220c5ea2f38836cd51c3cee7ee055bb1aa13dbf68c19624e418fd63ed244c8bb2f464736f6c63430008180033

Deployed Bytecode

0x608060405234801561000f575f80fd5b5060043610610234575f3560e01c806370a0823111610135578063c6e672b9116100b4578063e0df5b6f11610079578063e0df5b6f146105df578063e985e9c5146105f2578063eac9c9751461061f578063f28ca1dd14610646578063f2fde38b1461064e575f80fd5b8063c6e672b914610574578063c87b56dd14610587578063d547cfb71461059a578063db6ac3a4146105a2578063dd62ed3e146105b5575f80fd5b806395d89b41116100fa57806395d89b41146105205780639c05266814610528578063a22cb4651461053b578063a9059cbb1461054e578063b88d4fde14610561575f80fd5b806370a08231146104825780637717228a146104a15780638413b03a146104b45780638bd4e9fd146104c75780638da5cb5b1461050e575f80fd5b80632b968958116101c15780634f02c420116101865780634f02c4201461042b5780634f6ccce714610434578063504334c2146104475780635c8855811461045a5780636352211e1461046f575f80fd5b80632b9689581461035f5780632f745c5914610367578063313ce5671461037a578063405e3cc1146103b357806342842e0e14610418575f80fd5b8063095ea7b311610207578063095ea7b3146102ea57806309f0ef65146102ff57806318160ddd1461031257806318d217c31461033957806323b872dd1461034c575f80fd5b806301ffc9a71461023857806306fdde0314610260578063081812fc1461027557806308245fac146102b5575b5f80fd5b61024b6102463660046140f2565b610661565b60405190151581526020015b60405180910390f35b610268610671565b604051610257919061412f565b61029d610283366004614161565b600c6020525f90815260409020546001600160a01b031681565b6040516001600160a01b039091168152602001610257565b6102dc7f000000000000000000000000000000000000000000000000000000000000001981565b604051908152602001610257565b6102fd6102f836600461418e565b6106fd565b005b61024b61030d3660046141b6565b610828565b6102dc7f00000000000000000000000000000000000000000000003635c9adc5dea0000081565b6102fd61034736600461427e565b610855565b6102fd61035a3660046142af565b61088a565b6102fd610d04565b6102dc61037536600461418e565b610d68565b6103a17f000000000000000000000000000000000000000000000000000000000000001281565b60405160ff9091168152602001610257565b6004546103e5906001600160401b0380821691600160401b8104821691600160801b8204811691600160c01b90041684565b604080516001600160401b0395861681529385166020850152918416918301919091529091166060820152608001610257565b6102fd6104263660046142af565b610e3f565b6102dc60095481565b6102dc610442366004614161565b505f90565b6102fd6104553660046142e8565b610f10565b610462610f43565b6040516102579190614347565b61029d61047d366004614161565b610ff5565b6102dc6104903660046141b6565b600a6020525f908152604090205481565b6104626104af3660046141b6565b611045565b6104626104c236600461438a565b611120565b6103e56104d53660046141b6565b60016020525f90815260409020546001600160401b0380821691600160401b8104821691600160801b8204811691600160c01b90041684565b5f5461029d906001600160a01b031681565b6102686111fe565b6102fd61053636600461441b565b61120b565b6102fd61054936600461449c565b611575565b61024b61055c36600461418e565b6115e0565b6102fd61056f3660046144d5565b6115ec565b6102fd61058236600461449c565b6116ac565b610268610595366004614161565b611707565b610268611f28565b6104626105b0366004614567565b611f35565b6102dc6105c3366004614597565b600b60209081525f928352604080842090915290825290205481565b6102fd6105ed36600461427e565b612060565b61024b610600366004614597565b600d60209081525f928352604080842090915290825290205460ff1681565b6102dc7f000000000000000000000000000000000000000000000000000000000000000a81565b610268612095565b6102fd61065c3660046141b6565b6120a2565b5f61066b8261213c565b92915050565b6007805461067e906145c8565b80601f01602080910402602001604051908101604052809291908181526020018280546106aa906145c8565b80156106f55780601f106106cc576101008083540402835291602001916106f5565b820191905f5260205f20905b8154815290600101906020018083116106d857829003601f168201915b505050505081565b600954811115801561070e57505f81115b156107d5575f818152600e60205260409020546001600160a01b031633811480159061075d57506001600160a01b0381165f908152600d6020908152604080832033845290915290205460ff16155b1561077a576040516282b42960e81b815260040160405180910390fd5b5f828152600c602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b335f818152600b602090815260408083206001600160a01b038716808552925280832085905551849391927f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a45b5050565b6001600160a01b0381165f9081526006602052604081205460011461084d575f61066b565b600192915050565b5f546001600160a01b0316331461087e576040516282b42960e81b815260040160405180910390fd5b60116108248282614644565b6009548111610c98575f818152600e60205260409020546001600160a01b038481169116146108cc57604051636edaef2f60e11b815260040160405180910390fd5b6001600160a01b03821615806108eb57506001600160a01b0382166001145b1561090957604051634e46966960e11b815260040160405180910390fd5b336001600160a01b0384161480159061094557506001600160a01b0383165f908152600d6020908152604080832033845290915290205460ff16155b801561096757505f818152600c60205260409020546001600160a01b03163314155b15610984576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0383165f908152600a6020526040812080547f0000000000000000000000000000000000000000000000000de0b6b3a764000092906109cb908490614713565b90915550506001600160a01b0382165f818152600a6020908152604080832080547f0000000000000000000000000000000000000000000000000de0b6b3a7640000019055848352600e825280832080546001600160a01b03199081169095179055600c90915281208054909216909155610a8960027f00000000000000000000000000000000000000000000000000000000000000197f000000000000000000000000000000000000000000000000000000000000000a8561218b565b6001600160a01b0385165f90815260016020526040812091925090610af0907f00000000000000000000000000000000000000000000000000000000000000197f000000000000000000000000000000000000000000000000000000000000000a85612251565b6001600160a01b0385165f90815260016020526040812091925090610b57907f00000000000000000000000000000000000000000000000000000000000000197f000000000000000000000000000000000000000000000000000000000000000a876122e4565b9050610ba760027f00000000000000000000000000000000000000000000000000000000000000197f000000000000000000000000000000000000000000000000000000000000000a8587612409565b610bf560027f00000000000000000000000000000000000000000000000000000000000000197f000000000000000000000000000000000000000000000000000000000000000a8785612409565b83856001600160a01b0316876001600160a01b03165f80516020614d8e83398151915260405160405180910390a4846001600160a01b0316866001600160a01b03167fe59fdd36d0d223c0c7d996db7ad796880f45e1936cb0bb7ac102e7082e0314877f0000000000000000000000000000000000000000000000000de0b6b3a7640000604051610c8891815260200190565b60405180910390a3505050505050565b6001600160a01b0383165f908152600b602090815260408083203384529091529020545f198114610cf157610ccd8282614713565b6001600160a01b0385165f908152600b602090815260408083203384529091529020555b610cfc848484612476565b50505b505050565b5f546001600160a01b03163314610d2d576040516282b42960e81b815260040160405180910390fd5b5f80546001600160a01b031916815560405133907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e0908390a3565b6001600160a01b0382165f90815260066020526040812054600103610dd5576001600160a01b0383165f908152600160205260409020610dc8907f000000000000000000000000000000000000000000000000000000000000001961287e565b8210610dd557505f61066b565b6001600160a01b0383165f908152600160205260409020610e38907f00000000000000000000000000000000000000000000000000000000000000197f000000000000000000000000000000000000000000000000000000000000000a8561218b565b9392505050565b610e4a83838361088a565b6001600160a01b0382163b15801590610ef25750604051630a85bd0160e11b8082523360048301526001600160a01b03858116602484015260448301849052608060648401525f608484015290919084169063150b7a029060a4016020604051808303815f875af1158015610ec1573d5f803e3d5ffd5b505050506040513d601f19601f82011682018060405250810190610ee59190614726565b6001600160e01b03191614155b15610cff57604051633da6393160e01b815260040160405180910390fd5b5f546001600160a01b03163314610f39576040516282b42960e81b815260040160405180910390fd5b61082482826128ca565b60605f610f7160047f000000000000000000000000000000000000000000000000000000000000001961287e565b9050805f03610f9e5760408051600180825281830190925290602080830190803683370190505091505090565b610fef60047f00000000000000000000000000000000000000000000000000000000000000197f000000000000000000000000000000000000000000000000000000000000000a5f5f1986016128e3565b91505090565b5f818152600e60205260409020546001600160a01b031680158061102257506001600160a01b0381166001145b156110405760405163c5723b5160e01b815260040160405180910390fd5b919050565b6001600160a01b0381165f9081526001602052604081206060919061108a907f000000000000000000000000000000000000000000000000000000000000001961287e565b9050805f036110b8576040805160018082528183019092529060208083019080368337019050509392505050565b6001600160a01b0383165f908152600160205260408120610e38917f0000000000000000000000000000000000000000000000000000000000000019907f000000000000000000000000000000000000000000000000000000000000000a905f1986016128e3565b60605f61114e60047f000000000000000000000000000000000000000000000000000000000000001961287e565b9050805f0361118c5760015b604051908082528060200260200182016040528015611183578160200160208202803683370190505b5091505061066b565b80841061119a57600161115a565b8083106111a8576001810392505b6111f660047f00000000000000000000000000000000000000000000000000000000000000197f000000000000000000000000000000000000000000000000000000000000000a87876128e3565b949350505050565b6008805461067e906145c8565b825182518114801561121d5750815181145b61127f5760405162461bcd60e51b815260206004820152602860248201527f455243343034583a20726573687566666c6520696e707574206c656e677468206044820152670dad2e6dac2e8c6d60c31b60648201526084015b60405180910390fd5b335f908152600160205260408120905b8281101561138c578481815181106112a9576112a9614741565b60200260200101516113217f00000000000000000000000000000000000000000000000000000000000000197f000000000000000000000000000000000000000000000000000000000000000a87858151811061130857611308614741565b60200260200101518661218b909392919063ffffffff16565b146113845760405162461bcd60e51b815260206004820152602d60248201527f455243343034583a20726573687566666c6520696e70757420636f6e7461696e60448201526c732077726f6e672076616c756560981b6064820152608401611276565b60010161128f565b505f805f5b8481101561146d575f8882815181106113ac576113ac614741565b602002602001015190505f8783815181106113c9576113c9614741565b6020026020010151905060105f8381526020019081526020015f20545f03611408575f828152600f60205260409020600190819055949094019361141d565b5f828152601060205260408120555f19909301925b5f818152600f6020526040812054900361144e575f8181526010602052604090206001908190559390930192611463565b5f818152600f60205260408120555f19909401935b5050600101611391565b506114bb837f00000000000000000000000000000000000000000000000000000000000000197f000000000000000000000000000000000000000000000000000000000000000a8a8a612abd565b61150960027f00000000000000000000000000000000000000000000000000000000000000197f000000000000000000000000000000000000000000000000000000000000000a888b612abd565b81158015611515575080155b61156c5760405162461bcd60e51b815260206004820152602260248201527f455243343034583a20726573687566666c6520696e70757420696e636f72726560448201526118dd60f21b6064820152608401611276565b50505050505050565b335f818152600d602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b5f610e38338484612476565b6115f785858561088a565b6001600160a01b0384163b1580159061168e5750604051630a85bd0160e11b808252906001600160a01b0386169063150b7a02906116419033908a90899089908990600401614755565b6020604051808303815f875af115801561165d573d5f803e3d5ffd5b505050506040513d601f19601f820116820180604052508101906116819190614726565b6001600160e01b03191614155b15610cfc57604051633da6393160e01b815260040160405180910390fd5b5f546001600160a01b031633146116d5576040516282b42960e81b815260040160405180910390fd5b806116e0575f6116e3565b60015b6001600160a01b039092165f90815260066020526040902060ff9290921690915550565b60605f60128054611717906145c8565b9050111561175157601261172a83612bb3565b60405160200161173b9291906147a7565b6040516020818303038152906040529050919050565b5f606461175f84600161482a565b60405160200161177191815260200190565b604051602081830303815290604052805190602001205f1c6117939190614851565b90506060806060806060806060603c881015611948576040805180820190915260088152674275696c64696e6760c01b602082015260138054919750906117da8c8b61482a565b6117e49190614851565b815481106117f4576117f4614741565b905f5260205f20018054611807906145c8565b80601f0160208091040260200160405190810160405280929190818152602001828054611833906145c8565b801561187e5780601f106118555761010080835404028352916020019161187e565b820191905f5260205f20905b81548152906001019060200180831161186157829003601f168201915b50505050509450601480805490508b8a611898919061482a565b6118a29190614851565b815481106118b2576118b2614741565b905f5260205f200180546118c5906145c8565b80601f01602080910402602001604051908101604052809291908181526020018280546118f1906145c8565b801561193c5780601f106119135761010080835404028352916020019161193c565b820191905f5260205f20905b81548152906001019060200180831161191f57829003601f168201915b50505050509350611bf5565b604b881015611a315760408051808201909152600781526629ba34b1b5b2b960c91b602082015260158054919750906119818c8b61482a565b61198b9190614851565b8154811061199b5761199b614741565b905f5260205f200180546119ae906145c8565b80601f01602080910402602001604051908101604052809291908181526020018280546119da906145c8565b8015611a255780601f106119fc57610100808354040283529160200191611a25565b820191905f5260205f20905b815481529060010190602001808311611a0857829003601f168201915b50505050509150611bf5565b605a881015611b17576040805180820190915260048152634c6f676f60e01b60208201526016805491975090611a678c8b61482a565b611a719190614851565b81548110611a8157611a81614741565b905f5260205f20018054611a94906145c8565b80601f0160208091040260200160405190810160405280929190818152602001828054611ac0906145c8565b8015611b0b5780601f10611ae257610100808354040283529160200191611b0b565b820191905f5260205f20905b815481529060010190602001808311611aee57829003601f168201915b50505050509250611bf5565b60408051808201909152600981526821b430b930b1ba32b960b91b60208201526017805491975090611b498c8b61482a565b611b539190614851565b81548110611b6357611b63614741565b905f5260205f20018054611b76906145c8565b80601f0160208091040260200160405190810160405280929190818152602001828054611ba2906145c8565b8015611bed5780601f10611bc457610100808354040283529160200191611bed565b820191905f5260205f20905b815481529060010190602001808311611bd057829003601f168201915b505050505090505b611c03868686858786612c42565b96505f611c0f8b612bb3565b604051602001611c1f9190614864565b60408051601f1981840301815290829052611c3c916020016148a8565b604051602081830303815290604052601189604051602001611c5f9291906147a7565b60408051601f1981840301815290829052611c7d929160200161498c565b60408051601f19818403018152602083810183525f8452825180840190935260088352674275696c64696e6760c01b928101929092528951918a01919091209092507f7a254e3b6d7043f05172f0bfae1c54492680f217da417830c8e1bad77fe4777801611d545787604051602001611cf691906149b1565b60405160208183030381529060405290508087604051602001611d1a929190614a0c565b60405160208183030381529060405290508086604051602001611d3e929190614a6f565b6040516020818303038152906040529050611e98565b60408051808201909152600781526629ba34b1b5b2b960c91b6020918201528851908901207f9bc406424f6d588cd366501a231e55786e6fc074b0d4db0d9aebbc94fcd7463b01611dd45787604051602001611db091906149b1565b60405160208183030381529060405290508084604051602001611d3e929190614ac6565b6040805180820190915260048152634c6f676f60e01b6020918201528851908901207f8223dbd323bca9041f93b278b5f4c77daf60ba0482f645af1d0f4b2188d300a601611e515787604051602001611e2d91906149b1565b60405160208183030381529060405290508085604051602001611d3e929190614b1e565b87604051602001611e6291906149b1565b60405160208183030381529060405290508083604051602001611e86929190614b80565b60405160208183030381529060405290505b5f60405180604001604052806004815260200163227d5d7d60e01b81525090508282604051602001611ecb92919061498c565b60408051601f1981840301815290829052611eea91839060200161498c565b60408051601f1981840301815290829052611f0791602001614bd7565b6040516020818303038152906040529b505050505050505050505050919050565b6012805461067e906145c8565b6001600160a01b0383165f90815260016020526040812060609190611f7a907f000000000000000000000000000000000000000000000000000000000000001961287e565b9050805f03611fb85760015b604051908082528060200260200182016040528015611faf578160200160208202803683370190505b50915050610e38565b6001600160a01b0385165f90815260066020526040902054600103611ff357808410611fe5576001611f86565b808310611ff3576001810392505b6001600160a01b0385165f908152600160205260409020612057907f00000000000000000000000000000000000000000000000000000000000000197f000000000000000000000000000000000000000000000000000000000000000a87876128e3565b95945050505050565b5f546001600160a01b03163314612089576040516282b42960e81b815260040160405180910390fd5b60126108248282614644565b6011805461067e906145c8565b5f546001600160a01b031633146120cb576040516282b42960e81b815260040160405180910390fd5b6001600160a01b0381166120f2576040516349e27cff60e01b815260040160405180910390fd5b5f80546001600160a01b0319166001600160a01b0383169081178255604051909133917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a350565b5f6001600160e01b031982166380ac58cd60e01b148061216c57506001600160e01b03198216635b5e139f60e01b145b8061066b57506301ffc9a760e01b6001600160e01b031983161461066b565b83545f90600160c01b90046001600160401b031615806121cf57508454600160801b81046001600160401b03908116600160c01b90920481165f1901168502018210155b156121ed57604051632d0483c560e21b815260040160405180910390fd5b5f8483816121fd576121fd61483d565b0490505f8584816122105761221061483d565b5f84815260018a01602052604090205491900691505f198701821015612244579085021c80851c851b900391506111f69050565b9085021c91506111f69050565b83545f90600160c01b90046001600160401b031680820361228557604051632d0483c560e21b815260040160405180910390fd5b5f6001875f0160109054906101000a90046001600160401b03166001600160401b0316876001850302010390508084036122cd576122c4878787612dc4565b925050506111f6565b6122d987878787612eee565b979650505050505050565b83545f90600160801b90046001600160401b031684148061231457508454600160801b90046001600160401b0316155b156123765784546001600160401b03600160c01b808304821660018181019093169091026001600160c01b039093169290921787555f918252860160205260409020829055845467ffffffffffffffff60801b1916600160801b1785556123d6565b845460016001600160401b03600160801b8084048216838101831690910267ffffffffffffffff60801b19909416939093178089555f19600160c01b909104821601165f90815290870160205260409020805491850284901b9190910190555b5083545f19600160c01b82046001600160401b03908116820181168602600160801b909304169190910101949350505050565b8454600160c01b90046001600160401b0316158061244b57508454600160801b81046001600160401b03908116600160c01b90920481165f1901168502018210155b1561246957604051632d0483c560e21b815260040160405180910390fd5b610cfc8585858585612f86565b5f6001600160a01b038316158061249657506001600160a01b0383166001145b156124b457604051634e46966960e11b815260040160405180910390fd5b6001600160a01b038085165f818152600a6020526040808220805494881683529082205492825285916124e78386614713565b90915550506001600160a01b038086165f908152600a602052604080822080548801905591881681529081205461253f907f0000000000000000000000000000000000000000000000000de0b6b3a764000090614c1b565b6125697f0000000000000000000000000000000000000000000000000de0b6b3a764000085614c1b565b6125739190614713565b90505f6125a07f0000000000000000000000000000000000000000000000000de0b6b3a764000084614c1b565b6001600160a01b0388165f908152600a60205260409020546125e3907f0000000000000000000000000000000000000000000000000de0b6b3a764000090614c1b565b6125ed9190614713565b6001600160a01b0389165f908152600660205260408120549192500361266d576001600160a01b0388165f90815260016020526040812061264e907f000000000000000000000000000000000000000000000000000000000000001961287e565b90508281101561266b5761266b6126658483614713565b89613020565b505b6001600160a01b0388165f908152600660205260409020541580156126a757506001600160a01b0387165f90815260066020526040902054155b156126f1575f6126b78383613228565b90506126c4818a8a61323d565b818311156126da576126d58961357b565b6126eb565b828211156126eb576126eb88613685565b50612823565b6001600160a01b0388165f90815260066020526040902054600114801561272d57506001600160a01b0387165f90815260066020526040902054155b156127d8576001600160a01b0388165f908152600160205260408120612773907f000000000000000000000000000000000000000000000000000000000000001961287e565b905080156127ce576127858382613228565b92505f6127928484613228565b905061279f818b8b61323d565b8083106127b7576127b08184614713565b92506127bb565b5f92505b808411156127cc576127cc8a61357b565b505b6126eb8289613020565b6001600160a01b0388165f9081526006602052604090205415801561281457506001600160a01b0387165f908152600660205260409020546001145b156128235761282382896138b6565b866001600160a01b0316886001600160a01b03167fe59fdd36d0d223c0c7d996db7ad796880f45e1936cb0bb7ac102e7082e0314878860405161286891815260200190565b60405180910390a3506001979650505050505050565b81545f90600160c01b90046001600160401b0316810361289f57505f61066b565b509054600160801b81046001600160401b03908116600160c01b90920481165f190116919091020190565b60076128d68382614644565b506008610cff8282614644565b6060818311806128f7575064010000000083115b80612906575064010000000082115b156129245760405163079c3cff60e11b815260040160405180910390fd5b855483830360010190600160c01b90046001600160401b03161580612976575086545f19600160c01b82046001600160401b03908116820181168902600160801b909304169190910185830190910110155b1561299457604051632d0483c560e21b815260040160405180910390fd5b5f816001600160401b038111156129ad576129ad6141cf565b6040519080825280602002602001820160405280156129d6578160200160208202803683370190505b5090505f8786816129e9576129e961483d565b0490505f8887816129fc576129fc61483d565b5f84815260018d0160205260408120549290910692505b85811015612aad5760018b03831015612a61578451838b0283901c90818c1c8c1b820390879084908110612a4957612a49614741565b60200260200101818152505083600101935050612aa5565b89830282901c858281518110612a7957612a79614741565b6020026020010181815250508360010193505f92508b6001015f8581526020019081526020015f205491505b600101612a13565b50929a9950505050505050505050565b845482518251600160c01b9092046001600160401b0316918114612af457604051636176207d60e11b815260040160405180910390fd5b815f03612b1457604051632d0483c560e21b815260040160405180910390fd5b8654600160801b90046001600160401b03165f1983018702015f5b82811015612ba8575f868281518110612b4a57612b4a614741565b602002602001015190505f868381518110612b6757612b67614741565b60200260200101519050838210612b9157604051632d0483c560e21b815260040160405180910390fd5b612b9e8b8b8b8585612f86565b5050600101612b2f565b505050505050505050565b60605f612bbf83613a0c565b60010190505f816001600160401b03811115612bdd57612bdd6141cf565b6040519080825280601f01601f191660200182016040528015612c07576020820181803683370190505b5090508181016020015b5f19016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a8504945084612c1157509392505050565b6040805180820190915260088152674275696c64696e6760c01b6020918201528651908701206060907f7a254e3b6d7043f05172f0bfae1c54492680f217da417830c8e1bad77fe4777801612cf45785604051602001612ca29190614c2e565b60408051601f1981840301815290829052612cbf91602001614c5e565b60408051601f1981840301815290829052612cde918790602001614c82565b6040516020818303038152906040529050612dba565b60408051808201909152600781526629ba34b1b5b2b960c91b6020918201528751908801207f9bc406424f6d588cd366501a231e55786e6fc074b0d4db0d9aebbc94fcd7463b01612d505783604051602001612cde9190614cbf565b6040805180820190915260048152634c6f676f60e01b6020918201528751908801207f8223dbd323bca9041f93b278b5f4c77daf60ba0482f645af1d0f4b2188d300a601612da95782604051602001612cde9190614cfc565b81604051602001612cde9190614d36565b9695505050505050565b82545f90600160c01b90046001600160401b03168103612df757604051632d0483c560e21b815260040160405180910390fd5b83545f196001600160401b03600160c01b83048116820181165f8181526001890160205260408120549194600160801b900483169093019091169185830282811c80821b909303929091849003612ea05788545f19600160c01b6001600160401b03808c16600160801b0267ffffffffffffffff60801b198516811783900482169390930116026001600160c01b039091166001600160801b0390921691909117178955612ee2565b88545f196001600160401b03600160801b808404821692909201160267ffffffffffffffff60801b199091161789555f85815260018a01602052604090208390555b98975050505050505050565b5f80848381612eff57612eff61483d565b0490505f858481612f1257612f1261483d565b5f84815260018a01602052604081205492909106925086830290612f378a8a8a612dc4565b90505f60018a03851015612f56575091811c9182881c881b8303612f5b565b5082821c5b5f95865260018b016020526040909520805486841b90039190921b0190555090915050949350505050565b5f848381612f9657612f9661483d565b0490505f858481612fa957612fa961483d565b5f84815260018a01602052604090205491900691508582025f198801831015612ff7575f84815260018a0160205260409020805492821c80891c891b8103831b90930386831b019055612ba8565b5f84815260018a0160205260409020805483831c831b900386831b019055505050505050505050565b816001036130315761082481613685565b8115610824577f0000000000000000000000000000000000000000000000000de0b6b3a76400007f00000000000000000000000000000000000000000000003635c9adc5dea00000816130865761308661483d565b0460095410156130ab575f5b82811015610cff576130a382613685565b600101613092565b5f6130f960047f00000000000000000000000000000000000000000000000000000000000000197f000000000000000000000000000000000000000000000000000000000000000a86613aed565b6001600160a01b0383165f90815260016020526040812091925090613160907f00000000000000000000000000000000000000000000000000000000000000197f000000000000000000000000000000000000000000000000000000000000000a85613c42565b90506131b060027f00000000000000000000000000000000000000000000000000000000000000197f000000000000000000000000000000000000000000000000000000000000000a8585612abd565b5f5b84811015610cfc575f8382815181106131cd576131cd614741565b6020908102919091018101515f818152600e909252604080832080546001600160a01b0319166001600160a01b038a169081179091559051919350839290916001915f80516020614d8e83398151915291a4506001016131b2565b5f8183106132365781610e38565b5090919050565b826001036133ca576001600160a01b0382165f9081526001602052604081206132a7907f00000000000000000000000000000000000000000000000000000000000000197f000000000000000000000000000000000000000000000000000000000000000a612dc4565b6001600160a01b0383165f9081526001602052604081209192509061330e907f00000000000000000000000000000000000000000000000000000000000000197f000000000000000000000000000000000000000000000000000000000000000a856122e4565b5f838152600e6020526040902080546001600160a01b0319166001600160a01b038616179055905061338460027f00000000000000000000000000000000000000000000000000000000000000197f000000000000000000000000000000000000000000000000000000000000000a8585612409565b5f828152600c602052604080822080546001600160a01b03191690555183916001600160a01b0386811692908816915f80516020614d8e83398151915291a45050505050565b8215610cff576001600160a01b0382165f908152600160205260408120613433907f00000000000000000000000000000000000000000000000000000000000000197f000000000000000000000000000000000000000000000000000000000000000a87613dfb565b6001600160a01b0383165f9081526001602052604081209192509061349a907f00000000000000000000000000000000000000000000000000000000000000197f000000000000000000000000000000000000000000000000000000000000000a85613c42565b90506134ea60027f00000000000000000000000000000000000000000000000000000000000000197f000000000000000000000000000000000000000000000000000000000000000a8585612abd565b5f5b85811015613573575f83828151811061350757613507614741565b6020908102919091018101515f818152600e8352604080822080546001600160a01b03808c166001600160a01b03199283168117909355600c90965282842080549091169055905192945084939092908a16915f80516020614d8e83398151915291a4506001016134ec565b505050505050565b6001600160a01b0381165f9081526001602052604081206135dd907f00000000000000000000000000000000000000000000000000000000000000197f000000000000000000000000000000000000000000000000000000000000000a612dc4565b905061362c60047f00000000000000000000000000000000000000000000000000000000000000197f000000000000000000000000000000000000000000000000000000000000000a846122e4565b505f818152600e60209081526040808320805460016001600160a01b03199182168117909255600c90935281842080549093169092555183926001600160a01b038616915f80516020614d8e8339815191529190a45050565b5f6136d07f0000000000000000000000000000000000000000000000000de0b6b3a76400007f00000000000000000000000000000000000000000000003635c9adc5dea00000614c1b565b600954101561379c5760095f81546136e790614d75565b91829055506001600160a01b0383165f908152600160205260409020909150613764907f0000000000000000000000000000000000000000000000000000000000000019907f000000000000000000000000000000000000000000000000000000000000000a9061375a908383876122e4565b60029291906122e4565b505f818152600e602052604080822054905183926001600160a01b038087169316915f80516020614d8e8339815191529190a4613889565b6137e860047f00000000000000000000000000000000000000000000000000000000000000197f000000000000000000000000000000000000000000000000000000000000000a613f97565b6001600160a01b0383165f908152600160205260409020909150613863907f0000000000000000000000000000000000000000000000000000000000000019907f000000000000000000000000000000000000000000000000000000000000000a908490613858908484846122e4565b600293929190612409565b60405181906001600160a01b038416906001905f80516020614d8e833981519152905f90a45b5f908152600e6020526040902080546001600160a01b0319166001600160a01b0392909216919091179055565b816001036138c7576108248161357b565b8115610824576001600160a01b0381165f908152600160205260408120613930907f00000000000000000000000000000000000000000000000000000000000000197f000000000000000000000000000000000000000000000000000000000000000a86613dfb565b905061397f60047f00000000000000000000000000000000000000000000000000000000000000197f000000000000000000000000000000000000000000000000000000000000000a84613c42565b505f5b83811015613a06575f82828151811061399d5761399d614741565b6020908102919091018101515f818152600e83526040808220805460016001600160a01b03199182168117909255600c9095528183208054909516909455519193508392916001600160a01b038816915f80516020614d8e83398151915291a450600101613982565b50505050565b5f807a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310613a54577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000830492506040015b6d04ee2d6d415b85acef81000000008310613a80576d04ee2d6d415b85acef8100000000830492506020015b662386f26fc100008310613a9e57662386f26fc10000830492506010015b6305f5e1008310613ab6576305f5e100830492506008015b6127108310613aca57612710830492506004015b60648310613adc576064830492506002015b600a831061066b5760010192915050565b8354606090600160c01b90046001600160401b03165f819003613b2357604051632d0483c560e21b815260040160405180910390fd5b5f836001600160401b03811115613b3c57613b3c6141cf565b604051908082528060200260200182016040528015613b65578160200160208202803683370190505b508754909150600160801b90046001600160401b03165f1983810188029190910190810190851115613baa57604051632d0483c560e21b815260040160405180910390fd5b5f5b85811015613c35575f613bbf8a8461401e565b9050828103613bfc57613bd38a8a8a612dc4565b848381518110613be557613be5614741565b6020908102919091010152505f1990910190613c2d565b613c088a8a8a84612eee565b848381518110613c1a57613c1a614741565b6020908102919091010152505f19909101905b600101613bac565b5090979650505050505050565b835481516060916001600160401b03600160801b8204811692600160c01b909204811691905f908290811115613c7a57613c7a6141cf565b604051908082528060200260200182016040528015613ca3578160200160208202803683370190505b505f1984015f90815260018b0160205260408120549192505b83811015613da35789861480613cd0575085155b15613d49575f1985015f90815260018c01602052604090208290558751889082908110613cff57613cff614741565b60200260200101518b6001015f8780600101985081526020019081526020015f208190555060019550878181518110613d3a57613d3a614741565b60200260200101519150613d73565b888680600101975002888281518110613d6457613d64614741565b6020026020010151901b820191505b6001868b60018803020103838281518110613d9057613d90614741565b6020908102919091010152600101613cbc565b505f1984015f90815260018b01602052604090205588546001600160801b0316600160801b6001600160401b03958616026001600160c01b031617600160c01b94909316939093029190911790965595945050505050565b83546060906001600160401b03600160801b8204811691600160c01b900416801580613e3e57508654600160801b90046001600160401b03165f19820187020184115b15613e5c57604051632d0483c560e21b815260040160405180910390fd5b5f846001600160401b03811115613e7557613e756141cf565b604051908082528060200260200182016040528015613e9e578160200160208202803683370190505b505f1983015f90815260018a0160205260408120549192505b86811015613f35575f198501880282811c80821b909303926001879003613f065760011986015f90815260018d0160205260409020546001600160801b038c1697505f19909601959350613f0d565b5f19909601955b80858481518110613f2057613f20614741565b60209081029190910101525050600101613eb7565b508215613f53575f1983015f90815260018a01602052604090208190555b5087546001600160801b0316600160801b6001600160401b03948516026001600160c01b031617600160c01b92909316919091029190911790955550929392505050565b82545f90600160c01b90046001600160401b0316808203613fcb57604051632d0483c560e21b815260040160405180910390fd5b8454600160801b90046001600160401b03165f19828101860291909101015f613ff4878361401e565b905081810361401257614008878787612dc4565b9350505050610e38565b6122d987878784612eee565b81545f906001600160401b0380821691600160401b90041660010361407d57826001600160401b0316816001600160401b0316101561405f576001016140b4565b5082546fffffffffffffffff000000000000000019168355816140b4565b6001600160401b03811615614094575f19016140b4565b5082546fffffffffffffffff00000000000000001916600160401b1783555f5b83546001600160401b0390911667ffffffffffffffff1990911681178455905092915050565b6001600160e01b0319811681146140ef575f80fd5b50565b5f60208284031215614102575f80fd5b8135610e38816140da565b5f5b8381101561412757818101518382015260200161410f565b50505f910152565b602081525f825180602084015261414d81604085016020870161410d565b601f01601f19169190910160400192915050565b5f60208284031215614171575f80fd5b5035919050565b80356001600160a01b0381168114611040575f80fd5b5f806040838503121561419f575f80fd5b6141a883614178565b946020939093013593505050565b5f602082840312156141c6575f80fd5b610e3882614178565b634e487b7160e01b5f52604160045260245ffd5b604051601f8201601f191681016001600160401b038111828210171561420b5761420b6141cf565b604052919050565b5f82601f830112614222575f80fd5b81356001600160401b0381111561423b5761423b6141cf565b61424e601f8201601f19166020016141e3565b818152846020838601011115614262575f80fd5b816020850160208301375f918101602001919091529392505050565b5f6020828403121561428e575f80fd5b81356001600160401b038111156142a3575f80fd5b6111f684828501614213565b5f805f606084860312156142c1575f80fd5b6142ca84614178565b92506142d860208501614178565b9150604084013590509250925092565b5f80604083850312156142f9575f80fd5b82356001600160401b038082111561430f575f80fd5b61431b86838701614213565b93506020850135915080821115614330575f80fd5b5061433d85828601614213565b9150509250929050565b602080825282518282018190525f9190848201906040850190845b8181101561437e57835183529284019291840191600101614362565b50909695505050505050565b5f806040838503121561439b575f80fd5b50508035926020909101359150565b5f82601f8301126143b9575f80fd5b813560206001600160401b038211156143d4576143d46141cf565b8160051b6143e38282016141e3565b92835284810182019282810190878511156143fc575f80fd5b83870192505b848310156122d957823582529183019190830190614402565b5f805f6060848603121561442d575f80fd5b83356001600160401b0380821115614443575f80fd5b61444f878388016143aa565b94506020860135915080821115614464575f80fd5b614470878388016143aa565b93506040860135915080821115614485575f80fd5b50614492868287016143aa565b9150509250925092565b5f80604083850312156144ad575f80fd5b6144b683614178565b9150602083013580151581146144ca575f80fd5b809150509250929050565b5f805f805f608086880312156144e9575f80fd5b6144f286614178565b945061450060208701614178565b93506040860135925060608601356001600160401b0380821115614522575f80fd5b818801915088601f830112614535575f80fd5b813581811115614543575f80fd5b896020828501011115614554575f80fd5b9699959850939650602001949392505050565b5f805f60608486031215614579575f80fd5b61458284614178565b95602085013595506040909401359392505050565b5f80604083850312156145a8575f80fd5b6145b183614178565b91506145bf60208401614178565b90509250929050565b600181811c908216806145dc57607f821691505b6020821081036145fa57634e487b7160e01b5f52602260045260245ffd5b50919050565b601f821115610cff57805f5260205f20601f840160051c810160208510156146255750805b601f840160051c820191505b81811015610cfc575f8155600101614631565b81516001600160401b0381111561465d5761465d6141cf565b6146718161466b84546145c8565b84614600565b602080601f8311600181146146a4575f841561468d5750858301515b5f19600386901b1c1916600185901b178555613573565b5f85815260208120601f198616915b828110156146d2578886015182559484019460019091019084016146b3565b50858210156146ef57878501515f19600388901b60f8161c191681555b5050505050600190811b01905550565b634e487b7160e01b5f52601160045260245ffd5b8181038181111561066b5761066b6146ff565b5f60208284031215614736575f80fd5b8151610e38816140da565b634e487b7160e01b5f52603260045260245ffd5b5f6001600160a01b03808816835280871660208401525084604083015260806060830152826080830152828460a08401375f60a0848401015260a0601f19601f85011683010190509695505050505050565b5f8084546147b4816145c8565b600182811680156147cc57600181146147e15761480d565b60ff198416875282151583028701945061480d565b885f526020805f205f5b858110156148045781548a8201529084019082016147eb565b50505082870194505b50505050835161482181836020880161410d565b01949350505050565b8082018082111561066b5761066b6146ff565b634e487b7160e01b5f52601260045260245ffd5b5f8261485f5761485f61483d565b500690565b7f7b226e616d65223a20224d656d6520436974792023000000000000000000000081525f825161489b81601585016020870161410d565b9190910160150192915050565b5f82516148b981846020870161410d565b7f222c226465736372697074696f6e223a224120636f6c6c656374696f6e206f669201918252507f20312c303030206275696c64696e67732c20636f696e732c20737469636b657260208201527f732c20616e642063686172616374657273207468617420726573696465206f6e60408201527f2074686520626c6f636b636861696e2e222c2265787465726e616c5f75726c2260608201527f3a2268747470733a2f2f6d656d65636974793430342e696f222c22696d616765608082015262111d1160e91b60a082015260a301919050565b5f835161499d81846020880161410d565b83519083019061482181836020880161410d565b7f222c2261747472696275746573223a5b7b2274726169745f74797065223a225481526d3cb8329116113b30b63ab2911d1160911b60208201525f82516149ff81602e85016020870161410d565b91909101602e0192915050565b5f8351614a1d81846020880161410d565b80830190507f227d2c7b2274726169745f74797065223a22436f6c6f72222c2276616c7565228152611d1160f11b60208201528351614a6381602284016020880161410d565b01602201949350505050565b5f8351614a8081846020880161410d565b80830190507f227d2c7b2274726169745f74797065223a225368617065222c2276616c7565228152611d1160f11b60208201528351614a6381602284016020880161410d565b5f8351614ad781846020880161410d565b80830190507f227d2c7b2274726169745f74797065223a22546167222c2276616c7565223a2281528351614b1281602084016020880161410d565b01602001949350505050565b5f8351614b2f81846020880161410d565b80830190507f227d2c7b2274726169745f74797065223a22436f696e222c2276616c7565223a8152601160f91b60208201528351614b7481602184016020880161410d565b01602101949350505050565b5f8351614b9181846020880161410d565b7f227d2c7b2274726169745f74797065223a224944222c2276616c7565223a22009083019081528351614bcb81601f84016020880161410d565b01601f01949350505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b757466382c000000000081525f8251614c0e81601b85016020870161410d565b91909101601b0192915050565b5f82614c2957614c2961483d565b500490565b684275696c64696e675f60b81b81525f8251614c5181600985016020870161410d565b9190910160090192915050565b5f8251614c6f81846020870161410d565b605f60f81b920191825250600101919050565b5f8351614c9381846020880161410d565b835190830190614ca781836020880161410d565b632e6a706760e01b9101908152600401949350505050565b67537469636b65725f60c01b81525f8251614ce181600885016020870161410d565b632e6a706760e01b6008939091019283015250600c01919050565b644c6f676f5f60d81b81525f8251614d1b81600585016020870161410d565b632e6a706760e01b6005939091019283015250600901919050565b694368617261637465725f60b01b81525f8251614d5a81600a85016020870161410d565b632e6a706760e01b600a939091019283015250600e01919050565b5f60018201614d8657614d866146ff565b506001019056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa2646970667358221220c5ea2f38836cd51c3cee7ee055bb1aa13dbf68c19624e418fd63ed244c8bb2f464736f6c63430008180033

Deployed Bytecode Sourcemap

60897:5601:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61662:153;;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;61662:153:0;;;;;;;;45843:18;;;:::i;:::-;;;;;;;:::i;46554:46::-;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;46554:46:0;;;;;;-1:-1:-1;;;;;1597:55:1;;;1579:74;;1567:2;1552:18;46554:46:0;1433:226:1;41946:28:0;;;;;;;;1810:25:1;;;1798:2;1783:18;41946:28:0;1664:177:1;48561:603:0;;;;;;:::i;:::-;;:::i;:::-;;47827:147;;;;;;:::i;:::-;;:::i;46079:36::-;;;;;61823:98;;;;;;:::i;:::-;;:::i;49571:1577::-;;;;;;:::i;:::-;;:::i;28021:155::-;;;:::i;60128:320::-;;;;;;:::i;:::-;;:::i;45979:31::-;;;;;;;;4277:4:1;4265:17;;;4247:36;;4235:2;4220:18;45979:31:0;4105:184:1;42188:26:0;;;;;-1:-1:-1;;;;;42188:26:0;;;;-1:-1:-1;;;42188:26:0;;;;;-1:-1:-1;;;42188:26:0;;;;;-1:-1:-1;;;42188:26:0;;;;;;;;;-1:-1:-1;;;;;4572:15:1;;;4554:34;;4624:15;;;4619:2;4604:18;;4597:43;4676:15;;;4656:18;;;4649:43;;;;4728:15;;;4723:2;4708:18;;4701:43;4504:3;4489:19;42188:26:0;4294:456:1;51444:405:0;;;;;;:::i;:::-;;:::i;46214:21::-;;;;;;60456:121;;;;;;:::i;:::-;-1:-1:-1;60525:7:0;;60456:121;62043:158;;;;;;:::i;:::-;;:::i;44271:291::-;;;:::i;:::-;;;;;;;:::i;48046:220::-;;;;;;:::i;:::-;;:::i;46320:44::-;;;;;;:::i;:::-;;;;;;;;;;;;;;43444:313;;;;;;:::i;:::-;;:::i;43765:498::-;;;;;;:::i;:::-;;:::i;42041:45::-;;;;;;:::i;:::-;;;;;;;;;;;;-1:-1:-1;;;;;42041:45:0;;;;-1:-1:-1;;;42041:45:0;;;;;-1:-1:-1;;;42041:45:0;;;;;-1:-1:-1;;;42041:45:0;;;;;27456:20;;;;;-1:-1:-1;;;;;27456:20:0;;;45897;;;:::i;58167:1781::-;;;;;;:::i;:::-;;:::i;49215:207::-;;;;;;:::i;:::-;;:::i;51207:160::-;;;;;;:::i;:::-;;:::i;51944:437::-;;;;;;:::i;:::-;;:::i;47677:142::-;;;;;;:::i;:::-;;:::i;62209:3477::-;;;;;;:::i;:::-;;:::i;60961:26::-;;;:::i;42807:629::-;;;;;;:::i;:::-;;:::i;46434:64::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;61929:106;;;;;;:::i;:::-;;:::i;46665:68::-;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;41911:28;;;;;60933:21;;;:::i;27792:221::-;;;;;;:::i;:::-;;:::i;61662:153::-;61747:4;61771:36;61795:11;61771:23;:36::i;:::-;61764:43;61662:153;-1:-1:-1;;61662:153:0:o;45843:18::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;48561:603::-;48684:6;;48670:10;:20;;:38;;;;;48707:1;48694:10;:14;48670:38;48666:491;;;48725:13;48741:20;;;:8;:20;;;;;;-1:-1:-1;;;;;48741:20:0;48782:10;:19;;;;;:59;;-1:-1:-1;;;;;;48806:23:0;;;;;;:16;:23;;;;;;;;48830:10;48806:35;;;;;;;;;;48805:36;48782:59;48778:121;;;48869:14;;-1:-1:-1;;;48869:14:0;;;;;;;;;;;48778:121;48915:23;;;;:11;:23;;;;;;:33;;-1:-1:-1;;;;;;48915:33:0;-1:-1:-1;;;;;48915:33:0;;;;;;;;;48970:36;;48915:23;;48970:36;;;;;;;48710:308;48561:603;;:::o;48666:491::-;49049:10;49039:21;;;;:9;:21;;;;;;;;-1:-1:-1;;;;;49039:30:0;;;;;;;;;;:43;;;49104:41;49072:10;;49039:30;;49104:41;;;48666:491;48561:603;;:::o;47827:147::-;-1:-1:-1;;;;;47917:29:0;;47893:4;47917:29;;;:21;:29;;;;;;47950:1;47917:34;:49;;47961:5;47917:49;;;47954:4;47910:56;47827:147;-1:-1:-1;;47827:147:0:o;61823:98::-;27543:5;;-1:-1:-1;;;;;27543:5:0;27529:10;:19;27525:46;;27557:14;;-1:-1:-1;;;27557:14:0;;;;;;;;;;;27525:46;61895:7:::1;:18;61905:8:::0;61895:7;:18:::1;:::i;49571:1577::-:0;49717:6;;49703:10;:20;49699:1442;;49752:20;;;;:8;:20;;;;;;-1:-1:-1;;;;;49744:28:0;;;49752:20;;49744:28;49740:91;;49800:15;;-1:-1:-1;;;49800:15:0;;;;;;;;;;;49740:91;-1:-1:-1;;;;;49851:18:0;;;;:40;;-1:-1:-1;;;;;;49873:18:0;;49887:3;49873:18;49851:40;49847:106;;;49919:18;;-1:-1:-1;;;49919:18:0;;;;;;;;;;;49847:106;49991:10;-1:-1:-1;;;;;49991:18:0;;;;;;:74;;-1:-1:-1;;;;;;50031:22:0;;;;;;:16;:22;;;;;;;;50054:10;50031:34;;;;;;;;;;50030:35;49991:74;:132;;;;-1:-1:-1;50100:23:0;;;;:11;:23;;;;;;-1:-1:-1;;;;;50100:23:0;50086:10;:37;;49991:132;49969:226;;;50165:14;;-1:-1:-1;;;50165:14:0;;;;;;;;;;;49969:226;-1:-1:-1;;;;;50211:15:0;;;;;;:9;:15;;;;;:23;;50230:4;;50211:15;:23;;50230:4;;50211:23;:::i;:::-;;;;-1:-1:-1;;;;;;;50280:13:0;;;;;;:9;:13;;;;;;;;:21;;50297:4;50280:21;;;50333:20;;;:8;:20;;;;;:25;;-1:-1:-1;;;;;;50333:25:0;;;;;;;;50380:11;:23;;;;;50373:30;;;;;;;;50449:37;:11;50465:3;50470;50342:10;50449:15;:37::i;:::-;-1:-1:-1;;;;;50523:12:0;;50503:17;50523:12;;;:6;:12;;;;;50420:66;;-1:-1:-1;50503:17:0;50523:47;;50541:3;50546;50420:66;50523:17;:47::i;:::-;-1:-1:-1;;;;;50607:10:0;;50585:19;50607:10;;;:6;:10;;;;;50503:67;;-1:-1:-1;50585:19:0;50607:37;;50623:3;50628;50633:10;50607:15;:37::i;:::-;50585:59;-1:-1:-1;50661:57:0;:11;50678:3;50683;50688:9;50699:18;50661:16;:57::i;:::-;50733:51;:11;50750:3;50755;50760:10;50772:11;50733:16;:51::i;:::-;50825:10;50821:2;-1:-1:-1;;;;;50806:30:0;50815:4;-1:-1:-1;;;;;50806:30:0;-1:-1:-1;;;;;;;;;;;50806:30:0;;;;;;;;;50876:2;-1:-1:-1;;;;;50856:29:0;50870:4;-1:-1:-1;;;;;50856:29:0;;50880:4;50856:29;;;;1810:25:1;;1798:2;1783:18;;1664:177;50856:29:0;;;;;;;;49725:1172;;;49571:1577;;;:::o;49699:1442::-;-1:-1:-1;;;;;50936:15:0;;50918;50936;;;:9;:15;;;;;;;;50952:10;50936:27;;;;;;;;-1:-1:-1;;50984:28:0;;50980:101;;51061:20;51071:10;51061:7;:20;:::i;:::-;-1:-1:-1;;;;;51031:15:0;;;;;;:9;:15;;;;;;;;51047:10;51031:27;;;;;;;:50;50980:101;51098:31;51108:4;51114:2;51118:10;51098:9;:31::i;:::-;;50903:238;49699:1442;49571:1577;;;:::o;28021:155::-;27543:5;;-1:-1:-1;;;;;27543:5:0;27529:10;:19;27525:46;;27557:14;;-1:-1:-1;;;27557:14:0;;;;;;;;;;;27525:46;28100:3:::1;28084:20:::0;;-1:-1:-1;;;;;;28084:20:0::1;::::0;;28122:46:::1;::::0;28143:10:::1;::::0;28122:46:::1;::::0;28100:3;;28122:46:::1;28021:155::o:0;60128:320::-;-1:-1:-1;;;;;60243:28:0;;60219:7;60243:28;;;:21;:28;;;;;;60275:1;60243:33;60239:148;;-1:-1:-1;;;;;60306:13:0;;;;;;:6;:13;;;;;:25;;60327:3;60306:20;:25::i;:::-;60297:5;:34;60293:83;;-1:-1:-1;60359:1:0;60352:8;;60293:83;-1:-1:-1;;;;;60406:13:0;;;;;;:6;:13;;;;;:34;;60424:3;60429;60434:5;60406:17;:34::i;:::-;60399:41;60128:320;-1:-1:-1;;;60128:320:0:o;51444:405::-;51568:26;51581:4;51587:2;51591;51568:12;:26::i;:::-;-1:-1:-1;;;;;51625:14:0;;;:19;;;;:154;;-1:-1:-1;51661:61:0;;-1:-1:-1;;;51661:61:0;;;51697:10;51661:61;;;12641:34:1;-1:-1:-1;;;;;12711:15:1;;;12691:18;;;12684:43;12743:18;;;12736:34;;;12806:3;12786:18;;;12779:31;-1:-1:-1;12826:19:1;;;12819:30;51739:40:0;;51661:35;;;;51739:40;;12866:19:1;;51661:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;51661:118:0;;;51625:154;51607:235;;;51813:17;;-1:-1:-1;;;51813:17:0;;;;;;;;;;;62043:158;27543:5;;-1:-1:-1;;;;;27543:5:0;27529:10;:19;27525:46;;27557:14;;-1:-1:-1;;;27557:14:0;;;;;;;;;;;27525:46;62163:30:::1;62178:5;62185:7;62163:14;:30::i;44271:291::-:0;44317:16;44346:11;44360:19;:7;44375:3;44360:14;:19::i;:::-;44346:33;;44394:3;44401:1;44394:8;44390:64;;44426:16;;;44440:1;44426:16;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;44426:16:0;44419:23;;;44271:291;:::o;44390:64::-;44506:37;:7;44522:3;44527;44532:1;-1:-1:-1;;44535:7:0;;44506:15;:37::i;:::-;44499:44;;;44271:291;:::o;48046:220::-;48104:13;48138:12;;;:8;:12;;;;;;-1:-1:-1;;;;;48138:12:0;48167:21;;;:46;;-1:-1:-1;;;;;;48192:21:0;;48209:3;48192:21;48167:46;48163:96;;;48237:10;;-1:-1:-1;;;48237:10:0;;;;;;;;;;;48163:96;48046:220;;;:::o;43444:313::-;-1:-1:-1;;;;;43547:15:0;;43533:11;43547:15;;;:6;:15;;;;;43504:16;;43533:11;43547:27;;43570:3;43547:22;:27::i;:::-;43533:41;;43589:3;43596:1;43589:8;43585:64;;43621:16;;;43635:1;43621:16;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;43614:23:0;43444:313;-1:-1:-1;;;43444:313:0:o;43585:64::-;-1:-1:-1;;;;;43693:15:0;;43727:1;43693:15;;;43736:1;43693:15;;;;;:45;;43717:3;;43722;;-1:-1:-1;;43730:7:0;;43693:23;:45::i;43765:498::-;43842:16;43871:11;43885:19;:7;43900:3;43885:14;:19::i;:::-;43871:33;;43919:3;43926:1;43919:8;43915:64;;43965:1;43951:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43951:16:0;;43944:23;;;;;43915:64;44008:3;43995:9;:16;43991:72;;44049:1;44035:16;;43991:72;44123:3;44112:7;:14;44108:72;;44163:1;44157:3;:7;44147:17;;44108:72;44210:45;:7;44226:3;44231;44236:9;44247:7;44210:15;:45::i;:::-;44203:52;43765:498;-1:-1:-1;;;;43765:498:0:o;45897:20::-;;;;;;;:::i;58167:1781::-;58323:20;;58369;;58362:27;;:59;;;;;58400:14;:21;58393:3;:28;58362:59;58354:112;;;;-1:-1:-1;;;58354:112:0;;13352:2:1;58354:112:0;;;13334:21:1;13391:2;13371:18;;;13364:30;13430:34;13410:18;;;13403:62;-1:-1:-1;;;13481:18:1;;;13474:38;13529:19;;58354:112:0;;;;;;;;;58513:10;58479:24;58506:18;;;:6;:18;;;;;;58562:184;58586:3;58582:1;:7;58562:184;;;58664:13;58678:1;58664:16;;;;;;;;:::i;:::-;;;;;;;58623:37;58632:3;58637;58642:14;58657:1;58642:17;;;;;;;;:::i;:::-;;;;;;;58623:4;:8;;:37;;;;;;:::i;:::-;:57;58615:115;;;;-1:-1:-1;;;58615:115:0;;13893:2:1;58615:115:0;;;13875:21:1;13932:2;13912:18;;;13905:30;13971:34;13951:18;;;13944:62;-1:-1:-1;;;14022:18:1;;;14015:43;14075:19;;58615:115:0;13691:409:1;58615:115:0;58591:3;;58562:184;;;;58769:17;58797:20;58858:9;58853:844;58877:3;58873:1;:7;58853:844;;;58906:19;58928:13;58942:1;58928:16;;;;;;;;:::i;:::-;;;;;;;58906:38;;58963:20;58986:14;59001:1;58986:17;;;;;;;;:::i;:::-;;;;;;;58963:40;;59028:26;:39;59055:11;59028:39;;;;;;;;;;;;59071:1;59028:44;59024:317;;59097:40;;;;:27;:40;;;;;59140:1;59097:44;;;;59164:11;;;;;59024:317;;;59283:1;59241:39;;;:26;:39;;;;;:43;-1:-1:-1;;59307:14:0;;;;59024:317;59365:41;;;;:27;:41;;;;;;:46;;59361:321;;59436:40;;;;:26;:40;;;;;59479:1;59436:44;;;;59503:14;;;;;59361:321;;;59627:1;59583:41;;;:27;:41;;;;;:45;-1:-1:-1;;59651:11:0;;;;59361:321;-1:-1:-1;;58882:3:0;;58853:844;;;-1:-1:-1;59720:53:0;:4;59734:3;59739;59744:13;59759;59720;:53::i;:::-;59784:61;:11;59805:3;59810;59815:14;59831:13;59784:20;:61::i;:::-;59866:14;;:35;;;;-1:-1:-1;59884:17:0;;59866:35;59858:82;;;;-1:-1:-1;;;59858:82:0;;14307:2:1;59858:82:0;;;14289:21:1;14346:2;14326:18;;;14319:30;14385:34;14365:18;;;14358:62;-1:-1:-1;;;14436:18:1;;;14429:32;14478:19;;59858:82:0;14105:398:1;59858:82:0;58298:1650;;;;58167:1781;;;:::o;49215:207::-;49318:10;49301:28;;;;:16;:28;;;;;;;;-1:-1:-1;;;;;49301:38:0;;;;;;;;;;;;:49;;-1:-1:-1;;49301:49:0;;;;;;;;;;49368:46;;540:41:1;;;49301:38:0;;49318:10;49368:46;;513:18:1;49368:46:0;;;;;;;49215:207;;:::o;51207:160::-;51302:4;51326:33;51336:10;51348:2;51352:6;51326:9;:33::i;51944:437::-;52098:26;52111:4;52117:2;52121;52098:12;:26::i;:::-;-1:-1:-1;;;;;52155:14:0;;;:19;;;;:156;;-1:-1:-1;52191:63:0;;-1:-1:-1;;;52191:63:0;;;52271:40;-1:-1:-1;;;;;52191:35:0;;;52271:40;;52191:63;;52227:10;;52239:4;;52245:2;;52249:4;;;;52191:63;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;;52191:120:0;;;52155:156;52137:237;;;52345:17;;-1:-1:-1;;;52345:17:0;;;;;;;;;;;47677:142;27543:5;;-1:-1:-1;;;;;27543:5:0;27529:10;:19;27525:46;;27557:14;;-1:-1:-1;;;27557:14:0;;;;;;;;;;;27525:46;47798:5:::1;:13;;47810:1;47798:13;;;47806:1;47798:13;-1:-1:-1::0;;;;;47766:29:0;;::::1;;::::0;;;:21:::1;:29;::::0;;;;:45:::1;::::0;;;::::1;::::0;;;-1:-1:-1;47677:142:0:o;62209:3477::-;62269:13;62328:1;62305:12;62299:26;;;;;:::i;:::-;;;:30;62295:3384;;;62367:12;62381:20;62398:2;62381:16;:20::i;:::-;62353:49;;;;;;;;;:::i;:::-;;;;;;;;;;;;;62346:56;;62209:3477;;;:::o;62295:3384::-;62435:12;62497:3;62485:6;:2;62490:1;62485:6;:::i;:::-;62468:24;;;;;;16483:19:1;;16527:2;16518:12;;16354:182;62468:24:0;;;;;;;;;;;;;62458:35;;;;;;62450:44;;:50;;;;:::i;:::-;62435:65;;62515:19;62549;62583:20;62618;62653:19;62687:18;62720:17;62765:2;62758:4;:9;62754:568;;;62788:18;;;;;;;;;;;;-1:-1:-1;;;62788:18:0;;;;62834:6;62855:13;;62788:18;;-1:-1:-1;62834:6:0;62842:9;62849:2;62842:4;:9;:::i;:::-;62841:27;;;;:::i;:::-;62834:35;;;;;;;;:::i;:::-;;;;;;;;62825:44;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62897:6;62918;:13;;;;62912:2;62905:4;:9;;;;:::i;:::-;62904:27;;;;:::i;:::-;62897:35;;;;;;;;:::i;:::-;;;;;;;;62888:44;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62754:568;;;62965:2;62958:4;:9;62954:368;;;62988:17;;;;;;;;;;;;-1:-1:-1;;;62988:17:0;;;;63031:4;63050:11;;62988:17;;-1:-1:-1;63031:4:0;63037:9;63044:2;63037:4;:9;:::i;:::-;63036:25;;;;:::i;:::-;63031:31;;;;;;;;:::i;:::-;;;;;;;;63024:38;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62954:368;;;63095:2;63088:4;:9;63084:238;;;63118:14;;;;;;;;;;;;-1:-1:-1;;;63118:14:0;;;;63159:5;63179:12;;63118:14;;-1:-1:-1;63159:5:0;63166:9;63173:2;63166:4;:9;:::i;:::-;63165:26;;;;:::i;:::-;63159:33;;;;;;;;:::i;:::-;;;;;;;;63151:41;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63084:238;;;63233:19;;;;;;;;;;;;-1:-1:-1;;;63233:19:0;;;;63277:3;63295:10;;63233:19;;-1:-1:-1;63277:3:0;63282:9;63289:2;63282:4;:9;:::i;:::-;63281:24;;;;:::i;:::-;63277:29;;;;;;;;:::i;:::-;;;;;;;;63271:35;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;63084:238;63346:57;63363:5;63370:6;63378;63386:4;63392:5;63399:3;63346:16;:57::i;:::-;63338:65;;63464:26;63600:20;63617:2;63600:16;:20::i;:::-;63561:60;;;;;;;;:::i;:::-;;;;-1:-1:-1;;63561:60:0;;;;;;;;;;63525:303;;63561:60;63525:303;;:::i;:::-;;;;;;;;;;;;;63861:7;63870:5;63847:29;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;63847:29:0;;;;;;;;;;63493:398;;;63847:29;63493:398;;:::i;:::-;;;;-1:-1:-1;;63493:398:0;;;;;;;63906:32;;;;;:27;:32;;63994:17;;;;;;;;;;;-1:-1:-1;;;63994:17:0;;;;;;;63957:23;;;;;;;;;63493:398;;-1:-1:-1;63957:55:0;;63953:1364;;64134:5;64049:109;;;;;;;;:::i;:::-;;;;;;;;;;;;;64033:125;;64207:13;64259:6;64193:73;;;;;;;;;:::i;:::-;;;;;;;;;;;;;64177:89;;64315:13;64367:6;64301:73;;;;;;;;;:::i;:::-;;;;;;;;;;;;;64285:89;;63953:1364;;;64437:16;;;;;;;;;;;;-1:-1:-1;;;64437:16:0;;;;;64400:23;;;;;;:54;;64396:921;;64576:5;64491:109;;;;;;;;:::i;:::-;;;;;;;;;;;;;64475:125;;64649:13;64699:4;64635:69;;;;;;;;;:::i;64396:921::-;64767:13;;;;;;;;;;;;-1:-1:-1;;;64767:13:0;;;;;64730:23;;;;;;:51;;64726:591;;64903:5;64818:109;;;;;;;;:::i;:::-;;;;;;;;;;;;;64802:125;;64976:13;65027:5;64962:71;;;;;;;;;:::i;64726:591::-;65175:5;65090:109;;;;;;;;:::i;:::-;;;;;;;;;;;;;65074:125;;65248:13;65297:3;65234:67;;;;;;;;;:::i;:::-;;;;;;;;;;;;;65218:83;;64726:591;65331:28;:37;;;;;;;;;;;;;-1:-1:-1;;;65331:37:0;;;;;65568:12;65582:13;65554:42;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;65554:42:0;;;;;;;;;;65518:134;;65619:14;;65554:42;65518:134;;:::i;:::-;;;;-1:-1:-1;;65518:134:0;;;;;;;;;;65438:229;;65518:134;65438:229;;:::i;:::-;;;;;;;;;;;;;65431:236;;;;;;;;;;;;;62209:3477;;;:::o;60961:26::-;;;;;;;:::i;42807:629::-;-1:-1:-1;;;;;42943:15:0;;42929:11;42943:15;;;:6;:15;;;;;42900:16;;42929:11;42943:27;;42966:3;42943:22;:27::i;:::-;42929:41;;42985:3;42992:1;42985:8;42981:64;;43031:1;43017:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;43017:16:0;;43010:23;;;;;42981:64;-1:-1:-1;;;;;43061:30:0;;;;;;:21;:30;;;;;;43095:1;43061:35;43057:299;;43130:3;43117:9;:16;43113:80;;43175:1;43161:16;;43113:80;43265:3;43254:7;:14;43250:80;;43309:1;43303:3;:7;43293:17;;43250:80;-1:-1:-1;;;;;43375:15:0;;;;;;:6;:15;;;;;:53;;43399:3;43404;43409:9;43420:7;43375:23;:53::i;:::-;43368:60;42807:629;-1:-1:-1;;;;;42807:629:0:o;61929:106::-;27543:5;;-1:-1:-1;;;;;27543:5:0;27529:10;:19;27525:46;;27557:14;;-1:-1:-1;;;27557:14:0;;;;;;;;;;;27525:46;62003:12:::1;:24;62018:9:::0;62003:12;:24:::1;:::i;60933:21::-:0;;;;;;;:::i;27792:221::-;27543:5;;-1:-1:-1;;;;;27543:5:0;27529:10;:19;27525:46;;27557:14;;-1:-1:-1;;;27557:14:0;;;;;;;;;;;27525:46;-1:-1:-1;;;;;27875:22:0;::::1;27871:49;;27906:14;;-1:-1:-1::0;;;27906:14:0::1;;;;;;;;;;;27871:49;27933:5;:14:::0;;-1:-1:-1;;;;;;27933:14:0::1;-1:-1:-1::0;;;;;27933:14:0;::::1;::::0;;::::1;::::0;;27965:40:::1;::::0;27933:14;;27986:10:::1;::::0;27965:40:::1;::::0;27933:5;27965:40:::1;27792:221:::0;:::o;60585:305::-;60687:4;-1:-1:-1;;;;;;60724:40:0;;-1:-1:-1;;;60724:40:0;;:105;;-1:-1:-1;;;;;;;60781:48:0;;-1:-1:-1;;;60781:48:0;60724:105;:158;;;-1:-1:-1;;;;;;;;;;1835:40:0;;;60846:36;1726:157;30639:820;30812:9;;30754:7;;-1:-1:-1;;;30812:9:0;;-1:-1:-1;;;;;30812:9:0;:14;;:86;;-1:-1:-1;30875:23:0;;-1:-1:-1;;;30875:23:0;;-1:-1:-1;;;;;30875:23:0;;;-1:-1:-1;;;30840:9:0;;;;;-1:-1:-1;;30840:13:0;30839:33;;;:59;30830:68;;;30812:86;30808:147;;;30926:13;;-1:-1:-1;;;30926:13:0;;;;;;;;;;;30808:147;30971:16;30998:15;30990:5;:23;;;;;:::i;:::-;;30971:42;;31028:21;31060:15;31052:5;:23;;;;;:::i;:::-;31090:14;31107:22;;;:12;;;:22;;;;;;31052:23;;;;-1:-1:-1;;;31166:19:0;;31150:35;;31146:295;;;31225:27;;;31215:37;31289:21;;;31288:38;;31278:49;;;-1:-1:-1;31271:56:0;;-1:-1:-1;31271:56:0;31146:295;31398:27;;;31388:37;;-1:-1:-1;31381:44:0;;-1:-1:-1;31381:44:0;35888:569;36033:9;;35999:7;;-1:-1:-1;;;36033:9:0;;-1:-1:-1;;;;;36033:9:0;36057:8;;;36053:61;;36089:13;;-1:-1:-1;;;36089:13:0;;;;;;;;;;;36053:61;36168:17;36244:1;36218:4;:23;;;;;;;;;;-1:-1:-1;;;;;36218:23:0;-1:-1:-1;;;;;36188:53:0;36200:15;36195:1;36189:3;:7;36188:27;:53;:57;36168:77;;36275:9;36266:5;:18;36262:105;;36312:39;36316:4;36322:15;36339:11;36312:3;:39::i;:::-;36305:46;;;;;;36262:105;36390:48;36396:4;36402:15;36419:11;36432:5;36390;:48::i;:::-;36383:55;35888:569;-1:-1:-1;;;;;;;35888:569:0:o;28743:616::-;28903:23;;28854:7;;-1:-1:-1;;;28903:23:0;;-1:-1:-1;;;;;28903:23:0;:42;;;:74;;-1:-1:-1;28949:23:0;;-1:-1:-1;;;28949:23:0;;-1:-1:-1;;;;;28949:23:0;:28;28903:74;28899:355;;;29024:11;;-1:-1:-1;;;;;;;;29024:11:0;;;;;29011:12;29024:11;;;;;;;;;-1:-1:-1;;;;;29024:11:0;;;;;;;;;29011:25;;;;:12;;:25;;;;;:33;;;29063:27;;-1:-1:-1;;;;29063:27:0;-1:-1:-1;;;29063:27:0;;;28899:355;;;29198:25;;;-1:-1:-1;;;;;;;;29198:25:0;;;;;;;;;;;;;-1:-1:-1;;;;29198:25:0;;;;;;;;;;-1:-1:-1;;;;;29170:9:0;;;;;:13;29157:27;29198:23;29157:27;;;:12;;;:27;;;;;:81;;29198:39;;;29188:50;;;29157:81;;;;;;28899:355;-1:-1:-1;29313:23:0;;-1:-1:-1;;;;;29278:9:0;;-1:-1:-1;;;;;29278:9:0;;;:13;;29277:33;;;;-1:-1:-1;;;29313:23:0;;;;29277:59;;;;:63;28743:616;;;;;;:::o;31467:400::-;31634:9;;-1:-1:-1;;;31634:9:0;;-1:-1:-1;;;;;31634:9:0;:14;;:86;;-1:-1:-1;31697:23:0;;-1:-1:-1;;;31697:23:0;;-1:-1:-1;;;;;31697:23:0;;;-1:-1:-1;;;31662:9:0;;;;;-1:-1:-1;;31662:13:0;31661:33;;;:59;31652:68;;;31634:86;31630:147;;;31748:13;;-1:-1:-1;;;31748:13:0;;;;;;;;;;;31630:147;31793:55;31799:4;31805:15;31822:11;31835:5;31842;31793;:55::i;52449:2346::-;52562:4;-1:-1:-1;;;;;52583:18:0;;;;:40;;-1:-1:-1;;;;;;52605:18:0;;52619:3;52605:18;52583:40;52579:98;;;52647:18;;-1:-1:-1;;;52647:18:0;;;;;;;;;;;52579:98;-1:-1:-1;;;;;52719:15:0;;;52689:27;52719:15;;;:9;:15;;;;;;;;52777:13;;;;;;;;;52803:15;;;52822:6;;52803:25;52822:6;52719:15;52803:25;:::i;:::-;;;;-1:-1:-1;;;;;;;52866:13:0;;;;;;;:9;:13;;;;;;:23;;;;;;52962:15;;;;;;;;;:22;;52980:4;;52962:22;:::i;:::-;52931:26;52953:4;52931:19;:26;:::i;:::-;52930:55;;;;:::i;:::-;52913:72;-1:-1:-1;52996:14:0;53039:28;53063:4;53039:21;:28;:::i;:::-;-1:-1:-1;;;;;53014:13:0;;;;;;:9;:13;;;;;;:20;;53030:4;;53014:20;:::i;:::-;53013:55;;;;:::i;:::-;-1:-1:-1;;;;;53188:27:0;;;;;;:21;:27;;;;;;52996:72;;-1:-1:-1;53188:32:0;53184:222;;-1:-1:-1;;;;;53255:12:0;;53237:15;53255:12;;;:6;:12;;;;;:24;;53275:3;53255:19;:24::i;:::-;53237:42;;53308:6;53298:7;:16;53294:101;;;53335:30;53344:16;53354:6;53344:7;:16;:::i;:::-;53362:2;53335:8;:30::i;:::-;53222:184;53184:222;-1:-1:-1;;;;;53422:27:0;;;;;;:21;:27;;;;;;:32;:66;;;;-1:-1:-1;;;;;;53458:25:0;;;;;;:21;:25;;;;;;:30;53422:66;53418:1299;;;53505:18;53526:24;53535:6;53543;53526:8;:24::i;:::-;53505:45;;53565:34;53578:10;53590:4;53596:2;53565:12;:34::i;:::-;53629:6;53620;:15;53616:151;;;53656:11;53662:4;53656:5;:11::i;:::-;53616:151;;;53715:6;53706;:15;53702:65;;;53742:9;53748:2;53742:5;:9::i;:::-;53490:288;53418:1299;;;-1:-1:-1;;;;;53797:27:0;;;;;;:21;:27;;;;;;53828:1;53797:32;:66;;;;-1:-1:-1;;;;;;53833:25:0;;;;;;:21;:25;;;;;;:30;53797:66;53793:924;;;-1:-1:-1;;;;;53991:12:0;;53973:15;53991:12;;;:6;:12;;;;;:24;;54011:3;53991:19;:24::i;:::-;53973:42;-1:-1:-1;54034:11:0;;54030:503;;54075:25;54084:6;54092:7;54075:8;:25::i;:::-;54066:34;;54119:18;54140:24;54149:6;54157;54140:8;:24::i;:::-;54119:45;;54183:34;54196:10;54208:4;54214:2;54183:12;:34::i;:::-;54268:10;54258:6;:20;54254:165;;54303:20;54313:10;54303:20;;:::i;:::-;;;54254:165;;;54398:1;54389:10;;54254:165;54452:10;54443:6;:19;54439:79;;;54487:11;54493:4;54487:5;:11::i;:::-;54047:486;54030:503;54549:20;54558:6;54566:2;54549:8;:20::i;53793:924::-;-1:-1:-1;;;;;54600:27:0;;;;;;:21;:27;;;;;;:32;:66;;;;-1:-1:-1;;;;;;54636:25:0;;;;;;:21;:25;;;;;;54665:1;54636:30;54600:66;54596:121;;;54683:22;54692:6;54700:4;54683:8;:22::i;:::-;54754:2;-1:-1:-1;;;;;54734:31:0;54748:4;-1:-1:-1;;;;;54734:31:0;;54758:6;54734:31;;;;1810:25:1;;1798:2;1783:18;;1664:177;54734:31:0;;;;;;;;-1:-1:-1;54783:4:0;;52449:2346;-1:-1:-1;;;;;;;52449:2346:0:o;39882:291::-;40013:9;;39964:7;;-1:-1:-1;;;40013:9:0;;-1:-1:-1;;;;;40013:9:0;:14;;40009:63;;-1:-1:-1;40055:1:0;40048:8;;40009:63;-1:-1:-1;40131:23:0;;-1:-1:-1;;;40131:23:0;;-1:-1:-1;;;;;40131:23:0;;;-1:-1:-1;;;40096:9:0;;;;;-1:-1:-1;;40096:13:0;40095:33;;;;;:59;;39882:291::o;59956:160::-;60069:4;:12;60076:5;60069:4;:12;:::i;:::-;-1:-1:-1;60092:6:0;:16;60101:7;60092:6;:16;:::i;40185:1506::-;40325:16;40370:7;40358:9;:19;:42;;;;40393:7;40381:9;:19;40358:42;:63;;;;40414:7;40404;:17;40358:63;40354:115;;;40445:12;;-1:-1:-1;;;40445:12:0;;;;;;;;;;;40354:115;40573:9;;40529:19;;;40551:1;40529:23;;-1:-1:-1;;;40573:9:0;;-1:-1:-1;;;;;40573:9:0;:14;;:100;;-1:-1:-1;40650:23:0;;-1:-1:-1;;;;;40615:9:0;;-1:-1:-1;;;;;40615:9:0;;;:13;;40614:33;;;;-1:-1:-1;;;40650:23:0;;;;40614:59;;;;40591:15;;;:19;;;:82;;40573:100;40569:161;;;40701:13;;-1:-1:-1;;;40701:13:0;;;;;;;;;;;40569:161;40746:23;40786:3;-1:-1:-1;;;;;40772:18:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;40772:18:0;;40746:44;;40807:16;40838:15;40826:9;:27;;;;;:::i;:::-;;40807:46;;40868:21;40904:15;40892:9;:27;;;;;:::i;:::-;40934:14;40951:22;;;:12;;;:22;;;;;;40892:27;;;;;-1:-1:-1;41025:618:0;41047:3;41032:12;:18;41025:618;;;41109:1;41091:15;:19;41075:13;:35;41071:522;;;41210:20;;41160:27;;;41150:37;;;;41242:19;;;41241:36;;41233:45;;;41210:6;;41217:12;;41210:20;;;;;;:::i;:::-;;;;;;:68;;;;;41303:15;;;;;41112:226;41071:522;;;41433:11;41417:13;:27;41407:6;:37;;41384:6;41391:12;41384:20;;;;;;;;:::i;:::-;;;;;;:60;;;;;41469:10;;;;;41518:1;41502:17;;41551:4;:12;;:22;41564:8;41551:22;;;;;;;;;;;;41542:31;;41071:522;41613:14;;41025:618;;;-1:-1:-1;41666:6:0;;40185:1506;-1:-1:-1;;;;;;;;;;40185:1506:0:o;31875:869::-;32043:9;;32081:14;;32123:13;;-1:-1:-1;;;32043:9:0;;;-1:-1:-1;;;;;32043:9:0;;32112:24;;32108:76;;32160:12;;-1:-1:-1;;;32160:12:0;;;;;;;;;;;32108:76;32200:3;32207:1;32200:8;32196:61;;32232:13;;-1:-1:-1;;;32232:13:0;;;;;;;;;;;32196:61;32350:23;;-1:-1:-1;;;32350:23:0;;-1:-1:-1;;;;;32350:23:0;-1:-1:-1;;32321:7:0;;32320:27;;:53;32302:15;32390:336;32414:7;32410:1;:11;32390:336;;;32447:13;32463:7;32471:1;32463:10;;;;;;;;:::i;:::-;;;;;;;32447:26;;32492:13;32508:6;32515:1;32508:9;;;;;;;;:::i;:::-;;;;;;;32492:25;;32563:7;32554:5;:16;32550:85;;32602:13;;-1:-1:-1;;;32602:13:0;;;;;;;;;;;32550:85;32655:55;32661:4;32667:15;32684:11;32697:5;32704;32655;:55::i;:::-;-1:-1:-1;;32423:3:0;;32390:336;;;;32277:460;32018:726;;31875:869;;;;;:::o;24749:718::-;24805:13;24856:14;24873:17;24884:5;24873:10;:17::i;:::-;24893:1;24873:21;24856:38;;24909:20;24943:6;-1:-1:-1;;;;;24932:18:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;24932:18:0;-1:-1:-1;24909:41:0;-1:-1:-1;25074:28:0;;;25090:2;25074:28;25131:290;-1:-1:-1;;25163:5:0;-1:-1:-1;;;25300:2:0;25289:14;;25284:32;25163:5;25271:46;25363:2;25354:11;;;-1:-1:-1;25384:21:0;25131:290;25384:21;-1:-1:-1;25442:6:0;24749:718;-1:-1:-1;;;24749:718:0:o;65694:801::-;65996:17;;;;;;;;;;;;-1:-1:-1;;;65996:17:0;;;;;65959:23;;;;;;65929:13;;65959:55;;65955:533;;66093:6;66066:34;;;;;;;;:::i;:::-;;;;-1:-1:-1;;66066:34:0;;;;;;;;;;66052:54;;66066:34;66052:54;;:::i;:::-;;;;-1:-1:-1;;66052:54:0;;;;;;;;;;66038:85;;66108:6;;66052:54;66038:85;;:::i;:::-;;;;;;;;;;;;;66031:92;;;;65955:533;66182:16;;;;;;;;;;;;-1:-1:-1;;;66182:16:0;;;;;66145:23;;;;;;:54;;66141:347;;66249:4;66223:39;;;;;;;;:::i;66141:347::-;66321:13;;;;;;;;;;;;-1:-1:-1;;;66321:13:0;;;;;66284:23;;;;;;:51;;66280:208;;66382:5;66359:37;;;;;;;;:::i;66280:208::-;66464:3;66436:40;;;;;;;;:::i;66280:208::-;65694:801;;;;;;;;:::o;33610:877::-;33763:9;;33705:7;;-1:-1:-1;;;33763:9:0;;-1:-1:-1;;;;;33763:9:0;:14;;33759:75;;33805:13;;-1:-1:-1;;;33805:13:0;;;;;;;;;;;33759:75;33869:9;;-1:-1:-1;;;;;;;;;;33869:9:0;;;;:13;;33850:32;;:16;33980:22;;;33881:1;33980:12;;:22;;;;;;33850:32;;-1:-1:-1;;;33921:23:0;;;;:27;;;33897:51;;;;34033:27;;;34094:15;;;34136:17;;;34126:27;;;;34033;;34174:18;;;34170:267;;34213:49;;-1:-1:-1;;;;;;;;;;34213:49:0;;;-1:-1:-1;;;34213:49:0;-1:-1:-1;;;;34213:49:0;;;;34281:11;;;;;;;;;;;-1:-1:-1;;;;;34281:11:0;;;-1:-1:-1;;;;;34281:11:0;;;;;;;;;;34170:267;;;34346:25;;-1:-1:-1;;;;;;;;;;34346:25:0;;;;;;;;;;;-1:-1:-1;;;;34346:25:0;;;;;;34348:23;34390:22;;;34346:25;34390:12;;:22;;;;;:31;;;34170:267;34460:8;33610:877;-1:-1:-1;;;;;;;;33610:877:0:o;38960:914::-;39071:7;39116:16;39143:15;39135:5;:23;;;;;:::i;:::-;;39116:42;;39173:21;39205:15;39197:5;:23;;;;;:::i;:::-;39237:14;39254:22;;;:12;;;:22;;;;;;39197:23;;;;;-1:-1:-1;39307:27:0;;;;39369:39;39254:4;39379:15;39323:11;39369:3;:39::i;:::-;39349:59;;39425:16;39494:1;39476:15;:19;39460:13;:35;39456:259;;;-1:-1:-1;39525:15:0;;;;39581:21;;;39580:38;;39570:49;;39456:259;;;-1:-1:-1;39684:15:0;;;39456:259;39756:22;;;;:12;;;:22;;;;;;;;39782:17;;;39756:44;;39804:18;;;;39756:67;39731:92;;-1:-1:-1;39782:8:0;;-1:-1:-1;;38960:914:0;;;;;;:::o;32752:850::-;32906:16;32933:15;32925:5;:23;;;;;:::i;:::-;;32906:42;;32963:21;32995:15;32987:5;:23;;;;;:::i;:::-;33025:14;33042:22;;;:12;;;:22;;;;;;32987:23;;;;-1:-1:-1;33095:27:0;;;-1:-1:-1;;33159:19:0;;33143:35;;33139:445;;;33242:16;33356:22;;;:12;;;:22;;;;;;;33208:15;;;33272:21;;;33271:38;;33261:49;;33382:17;;33356:44;;;33404:14;;;33356:63;33331:88;;33139:445;;;33498:22;;;;:12;;;:22;;;;;;;33524:15;;;:24;;33498:51;;33553:14;;;33498:70;33473:95;;32881:714;;;;32752:850;;;;;:::o;55806:929::-;55884:6;55894:1;55884:11;55880:848;;55912:9;55918:2;55912:5;:9::i;55880:848::-;55952:10;;55948:780;;56035:4;56021:11;:18;;;;;:::i;:::-;;56012:6;;:27;56008:694;;;56069:9;56064:97;56088:6;56084:1;:10;56064:97;;;56128:9;56134:2;56128:5;:9::i;:::-;56096:3;;56064:97;;56008:694;56226:20;56249:39;:7;56271:3;56276;56281:6;56249:21;:39::i;:::-;-1:-1:-1;;;;;56338:10:0;;56311:24;56338:10;;;:6;:10;;;;;56226:62;;-1:-1:-1;56311:24:0;56338:34;;56358:3;56363;56226:62;56338:19;:34::i;:::-;56311:61;-1:-1:-1;56397:44:0;:11;56418:3;56423;56428;56311:61;56397:20;:44::i;:::-;56471:9;56466:217;56490:6;56486:1;:10;56466:217;;;56530:10;56543:3;56547:1;56543:6;;;;;;;;:::i;:::-;;;;;;;;;;;;56578:12;;;;:8;:12;;;;;;;:17;;-1:-1:-1;;;;;;56578:17:0;-1:-1:-1;;;;;56578:17:0;;;;;;;;56629:30;;56543:6;;-1:-1:-1;56543:6:0;;56578:17;;-1:-1:-1;;;;;;;;;;;;;56629:30:0;;-1:-1:-1;56498:3:0;;56466:217;;11422:106;11480:7;11511:1;11507;:5;:13;;11519:1;11507:13;;;-1:-1:-1;11515:1:0;;11422:106;-1:-1:-1;11422:106:0:o;54803:995::-;54903:10;54917:1;54903:15;54899:892;;-1:-1:-1;;;;;54948:12:0;;54935:10;54948:12;;;:6;:12;;;;;:26;;54965:3;54970;54948:16;:26::i;:::-;-1:-1:-1;;;;;55011:10:0;;54989:19;55011:10;;;:6;:10;;;;;54935:39;;-1:-1:-1;54989:19:0;55011:29;;55027:3;55032;54935:39;55011:15;:29::i;:::-;55057:12;;;;:8;:12;;;;;:17;;-1:-1:-1;;;;;;55057:17:0;-1:-1:-1;;;;;55057:17:0;;;;;54989:51;-1:-1:-1;55089:43:0;:11;55106:3;55111;55057:12;54989:51;55089:16;:43::i;:::-;55154:15;;;;:11;:15;;;;;;55147:22;;-1:-1:-1;;;;;;55147:22:0;;;55191;55166:2;;-1:-1:-1;;;;;55191:22:0;;;;;;;;-1:-1:-1;;;;;;;;;;;55191:22:0;;54920:305;;49571:1577;;;:::o;54899:892::-;55244:14;;55240:551;;-1:-1:-1;;;;;55298:12:0;;55275:20;55298:12;;;:6;:12;;;;;:42;;55319:3;55324;55329:10;55298:20;:42::i;:::-;-1:-1:-1;;;;;55382:10:0;;55355:24;55382:10;;;:6;:10;;;;;55275:65;;-1:-1:-1;55355:24:0;55382:34;;55402:3;55407;55275:65;55382:19;:34::i;:::-;55355:61;-1:-1:-1;55433:44:0;:11;55454:3;55459;55464;55355:61;55433:20;:44::i;:::-;55528:9;55523:242;55547:10;55543:1;:14;55523:242;;;55587:10;55600:3;55604:1;55600:6;;;;;;;;:::i;:::-;;;;;;;;;;;;55631:12;;;;:8;:12;;;;;;:17;;-1:-1:-1;;;;;55631:17:0;;;-1:-1:-1;;;;;;55631:17:0;;;;;;;;55678:11;:15;;;;;;55671:22;;;;;;;55723;;55600:6;;-1:-1:-1;55600:6:0;;55631:17;;55723:22;;;;-1:-1:-1;;;;;;;;;;;55723:22:0;;-1:-1:-1;55559:3:0;;55523:242;;;;55260:531;;54803:995;;;:::o;57893:266::-;-1:-1:-1;;;;;57963:12:0;;57950:10;57963:12;;;:6;:12;;;;;:26;;57980:3;57985;57963:16;:26::i;:::-;57950:39;-1:-1:-1;58002:26:0;:7;58015:3;58020;57950:39;58002:12;:26::i;:::-;-1:-1:-1;58041:12:0;;;;:8;:12;;;;;;;;:27;;58064:3;-1:-1:-1;;;;;;58041:27:0;;;;;;;;58086:11;:15;;;;;;58079:22;;;;;;;;58119:32;58041:12;;-1:-1:-1;;;;;58119:32:0;;;-1:-1:-1;;;;;;;;;;;58119:32:0;58041:12;58119:32;57939:220;57893:266;:::o;56743:513::-;56798:10;56832:18;56846:4;56832:11;:18;:::i;:::-;56823:6;;:27;56819:400;;;56874:6;;56872:8;;;;;:::i;:::-;;;;;-1:-1:-1;;;;;;56922:10:0;;;;;;:6;:10;;;;;56872:8;;-1:-1:-1;56895:57:0;;56912:3;;56917;;56922:29;;56912:3;56917;56872:8;56922:15;:29::i;:::-;56895:11;;:57;;:16;:57::i;:::-;-1:-1:-1;56984:12:0;;;;:8;:12;;;;;;;56975:30;;57002:2;;-1:-1:-1;;;;;56975:30:0;;;;56984:12;;-1:-1:-1;;;;;;;;;;;56975:30:0;56984:12;56975:30;56819:400;;;57052:27;:7;57070:3;57075;57052:17;:27::i;:::-;-1:-1:-1;;;;;57125:10:0;;;;;;:6;:10;;;;;57047:32;;-1:-1:-1;57094:61:0;;57111:3;;57116;;57047:32;;57125:29;;57111:3;57116;57047:32;57125:15;:29::i;:::-;57094:11;;:61;;;:16;:61::i;:::-;57177:30;;57204:2;;-1:-1:-1;;;;;57177:30:0;;;57194:3;;-1:-1:-1;;;;;;;;;;;57177:30:0;;;;56819:400;57231:12;;;;:8;:12;;;;;:17;;-1:-1:-1;;;;;;57231:17:0;-1:-1:-1;;;;;57231:17:0;;;;;;;;;;56743:513::o;57264:621::-;57344:6;57354:1;57344:11;57340:538;;57372:11;57378:4;57372:5;:11::i;57340:538::-;57414:10;;57410:468;;-1:-1:-1;;;;;57464:12:0;;57441:20;57464:12;;;:6;:12;;;;;:38;;57485:3;57490;57495:6;57464:20;:38::i;:::-;57441:61;-1:-1:-1;57517:31:0;:7;57534:3;57539;57441:61;57517:16;:31::i;:::-;;57599:9;57594:258;57618:6;57614:1;:10;57594:258;;;57654:10;57667:3;57671:1;57667:6;;;;;;;;:::i;:::-;;;;;;;;;;;;57698:12;;;;:8;:12;;;;;;:27;;57721:3;-1:-1:-1;;;;;;57698:27:0;;;;;;;;57755:11;:15;;;;;;57748:22;;;;;;;;57800:32;57667:6;;-1:-1:-1;57667:6:0;;57721:3;-1:-1:-1;;;;;57800:32:0;;;-1:-1:-1;;;;;;;;;;;57800:32:0;;-1:-1:-1;57626:3:0;;57594:258;;;;57426:452;57264:621;;:::o;21312:948::-;21365:7;;21452:8;21443:17;;21439:106;;21490:8;21481:17;;;-1:-1:-1;21527:2:0;21517:12;21439:106;21572:8;21563:5;:17;21559:106;;21610:8;21601:17;;;-1:-1:-1;21647:2:0;21637:12;21559:106;21692:8;21683:5;:17;21679:106;;21730:8;21721:17;;;-1:-1:-1;21767:2:0;21757:12;21679:106;21812:7;21803:5;:16;21799:103;;21849:7;21840:16;;;-1:-1:-1;21885:1:0;21875:11;21799:103;21929:7;21920:5;:16;21916:103;;21966:7;21957:16;;;-1:-1:-1;22002:1:0;21992:11;21916:103;22046:7;22037:5;:16;22033:103;;22083:7;22074:16;;;-1:-1:-1;22119:1:0;22109:11;22033:103;22163:7;22154:5;:16;22150:68;;22201:1;22191:11;22246:6;21312:948;-1:-1:-1;;21312:948:0:o;37107:1068::-;37271:9;;37228:16;;-1:-1:-1;;;37271:9:0;;-1:-1:-1;;;;;37271:9:0;37257:11;37295:8;;;37291:61;;37327:13;;-1:-1:-1;;;37327:13:0;;;;;;;;;;;37291:61;37372:29;37418:6;-1:-1:-1;;;;;37404:21:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;37404:21:0;-1:-1:-1;37520:23:0;;37372:53;;-1:-1:-1;;;;37520:23:0;;-1:-1:-1;;;;;37520:23:0;-1:-1:-1;;37491:7:0;;;37490:27;;:53;;;;:57;;;;37568:22;;37564:83;;;37618:13;;-1:-1:-1;;;37618:13:0;;;;;;;;;;;37564:83;37668:9;37663:458;37687:6;37683:1;:10;37663:458;;;37719:13;37735:44;37755:4;37768:9;37735:19;:44::i;:::-;37719:60;;37813:9;37804:5;:18;37800:189;;37865:39;37869:4;37875:15;37892:11;37865:3;:39::i;:::-;37847:12;37860:1;37847:15;;;;;;;;:::i;:::-;;;;;;;;;;:57;-1:-1:-1;;;37927:11:0;;;;37961:8;;37800:189;38027:48;38033:4;38039:15;38056:11;38069:5;38027;:48::i;:::-;38009:12;38022:1;38009:15;;;;;;;;:::i;:::-;;;;;;;;;;:66;-1:-1:-1;;;38094:11:0;;;;37663:458;37695:3;;37663:458;;;-1:-1:-1;38144:12:0;;37107:1068;-1:-1:-1;;;;;;;37107:1068:0:o;29367:1264::-;29549:23;;29636:13;;29492:16;;-1:-1:-1;;;;;;;;29549:23:0;;;;;-1:-1:-1;;;29597:9:0;;;;;;29636:13;29521:25;;29636:13;;29693:21;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;29693:21:0;-1:-1:-1;;;29786:7:0;;29750:20;29773:21;;;:12;;;:21;;;;;;29660:54;;-1:-1:-1;29809:620:0;29833:6;29829:1;:10;29809:620;;;29890:15;29869:17;:36;:62;;;-1:-1:-1;29909:22:0;;29869:62;29865:458;;;-1:-1:-1;;29986:7:0;;29973:21;;;;:12;;;:21;;;;;:36;;;30054:9;;:6;;30061:1;;30054:9;;;;;;:::i;:::-;;;;;;;30032:4;:12;;:19;30045:5;;;;;;30032:19;;;;;;;;;;;:31;;;;30106:1;30086:21;;30147:6;30154:1;30147:9;;;;;;;;:::i;:::-;;;;;;;30132:24;;29865:458;;;30291:11;30269:19;;;;;;:33;30255:6;30262:1;30255:9;;;;;;;;:::i;:::-;;;;;;;:48;;30239:64;;;;29865:458;30412:1;30392:17;30374:15;30369:1;30363:3;:7;30362:27;:47;:51;30343:13;30357:1;30343:16;;;;;;;;:::i;:::-;;;;;;;;;;:70;29841:3;;29809:620;;;-1:-1:-1;;;30458:7:0;;30445:21;;;;:12;;;:21;;;;;:36;30505:51;;-1:-1:-1;;;;;30567:23:0;-1:-1:-1;;;;;;;;30505:51:0;;;;-1:-1:-1;;;;;30567:23:0;;-1:-1:-1;;;30567:23:0;;;;;;;;;;;;;;;;29367:1264;-1:-1:-1;;;;;29367:1264:0:o;34495:1385::-;34667:23;;34610:16;;-1:-1:-1;;;;;;;;34667:23:0;;;;;-1:-1:-1;;;34715:9:0;;;34766:8;;;:74;;-1:-1:-1;34817:23:0;;-1:-1:-1;;;34817:23:0;;-1:-1:-1;;;;;34817:23:0;-1:-1:-1;;34788:7:0;;34787:27;;:53;34778:62;;34766:74;34762:135;;;34868:13;;-1:-1:-1;;;34868:13:0;;;;;;;;;;;34762:135;34920:29;34966:6;-1:-1:-1;;;;;34952:21:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;34952:21:0;-1:-1:-1;;;35039:7:0;;35009:14;35026:21;;;:12;;;:21;;;;;;34920:53;;-1:-1:-1;35062:576:0;35086:6;35082:1;:10;35062:576;;;-1:-1:-1;;35135:21:0;;35134:37;;35209:15;;;35255:17;;;35245:27;;;;35155:1;35297:22;;;35293:283;;-1:-1:-1;;35463:7:0;;35450:21;;;;35411:5;35450:12;;:21;;;;;;-1:-1:-1;;;;;35344:44:0;;;-1:-1:-1;;;35411:5:0;;;;35450:21;-1:-1:-1;35293:283:0;;;-1:-1:-1;;35537:19:0;;;;35293:283;35614:8;35596:12;35609:1;35596:15;;;;;;;;:::i;:::-;;;;;;;;;;:26;-1:-1:-1;;35094:3:0;;35062:576;;;-1:-1:-1;35658:7:0;;35654:78;;-1:-1:-1;;35699:7:0;;35686:21;;;;:12;;;:21;;;;;:30;;;35654:78;-1:-1:-1;35755:51:0;;-1:-1:-1;;;;;35817:23:0;-1:-1:-1;;;;;;;;35755:51:0;;;;-1:-1:-1;;;;;35817:23:0;;-1:-1:-1;;;35817:23:0;;;;;;;;;;;;;;;-1:-1:-1;35817:23:0;;34495:1385;-1:-1:-1;;;34495:1385:0:o;36465:634::-;36600:9;;36566:7;;-1:-1:-1;;;36600:9:0;;-1:-1:-1;;;;;36600:9:0;36624:8;;;36620:61;;36656:13;;-1:-1:-1;;;36656:13:0;;;;;;;;;;;36620:61;36785:23;;-1:-1:-1;;;36785:23:0;;-1:-1:-1;;;;;36785:23:0;-1:-1:-1;;36756:7:0;;;36755:27;;:53;;;;:57;36735:17;36843:44;36785:23;36755:57;36843:19;:44::i;:::-;36827:60;;36917:9;36908:5;:18;36904:105;;36954:39;36958:4;36964:15;36981:11;36954:3;:39::i;:::-;36947:46;;;;;;;36904:105;37032:48;37038:4;37044:15;37061:11;37074:5;37032;:48::i;38183:769::-;38325:19;;38265:7;;-1:-1:-1;;;;;38325:19:0;;;;-1:-1:-1;;;38363:18:0;;;38325:19;38363:23;38359:502;;38419:9;-1:-1:-1;;;;;38411:17:0;:5;-1:-1:-1;;;;;38411:17:0;;38407:201;;;38453:7;;38359:502;;38407:201;-1:-1:-1;38526:22:0;;-1:-1:-1;;38526:22:0;;;38579:9;38359:502;;;-1:-1:-1;;;;;38665:9:0;;;38661:185;;-1:-1:-1;;38699:7:0;38661:185;;;-1:-1:-1;38772:22:0;;-1:-1:-1;;38772:22:0;-1:-1:-1;;;38772:22:0;;;:18;38661:185;38877:27;;-1:-1:-1;;;;;38877:27:0;;;-1:-1:-1;;38877:27:0;;;;;;;;-1:-1:-1;38183:769:0;;;;:::o;14:131:1:-;-1:-1:-1;;;;;;88:32:1;;78:43;;68:71;;135:1;132;125:12;68:71;14:131;:::o;150:245::-;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:250::-;677:1;687:113;701:6;698:1;695:13;687:113;;;777:11;;;771:18;758:11;;;751:39;723:2;716:10;687:113;;;-1:-1:-1;;834:1:1;816:16;;809:27;592:250::o;847:396::-;996:2;985:9;978:21;959:4;1028:6;1022:13;1071:6;1066:2;1055:9;1051:18;1044:34;1087:79;1159:6;1154:2;1143:9;1139:18;1134:2;1126:6;1122:15;1087:79;:::i;:::-;1227:2;1206:15;-1:-1:-1;;1202:29:1;1187:45;;;;1234:2;1183:54;;847:396;-1:-1:-1;;847:396:1:o;1248:180::-;1307:6;1360:2;1348:9;1339:7;1335:23;1331:32;1328:52;;;1376:1;1373;1366:12;1328:52;-1:-1:-1;1399:23:1;;1248:180;-1:-1:-1;1248:180:1:o;1846:196::-;1914:20;;-1:-1:-1;;;;;1963:54:1;;1953:65;;1943:93;;2032:1;2029;2022:12;2047:254;2115:6;2123;2176:2;2164:9;2155:7;2151:23;2147:32;2144:52;;;2192:1;2189;2182:12;2144:52;2215:29;2234:9;2215:29;:::i;:::-;2205:39;2291:2;2276:18;;;;2263:32;;-1:-1:-1;;;2047:254:1:o;2306:186::-;2365:6;2418:2;2406:9;2397:7;2393:23;2389:32;2386:52;;;2434:1;2431;2424:12;2386:52;2457:29;2476:9;2457:29;:::i;2497:127::-;2558:10;2553:3;2549:20;2546:1;2539:31;2589:4;2586:1;2579:15;2613:4;2610:1;2603:15;2629:275;2700:2;2694:9;2765:2;2746:13;;-1:-1:-1;;2742:27:1;2730:40;;-1:-1:-1;;;;;2785:34:1;;2821:22;;;2782:62;2779:88;;;2847:18;;:::i;:::-;2883:2;2876:22;2629:275;;-1:-1:-1;2629:275:1:o;2909:531::-;2952:5;3005:3;2998:4;2990:6;2986:17;2982:27;2972:55;;3023:1;3020;3013:12;2972:55;3059:6;3046:20;-1:-1:-1;;;;;3081:2:1;3078:26;3075:52;;;3107:18;;:::i;:::-;3151:55;3194:2;3175:13;;-1:-1:-1;;3171:27:1;3200:4;3167:38;3151:55;:::i;:::-;3231:2;3222:7;3215:19;3277:3;3270:4;3265:2;3257:6;3253:15;3249:26;3246:35;3243:55;;;3294:1;3291;3284:12;3243:55;3359:2;3352:4;3344:6;3340:17;3333:4;3324:7;3320:18;3307:55;3407:1;3382:16;;;3400:4;3378:27;3371:38;;;;3386:7;2909:531;-1:-1:-1;;;2909:531:1:o;3445:322::-;3514:6;3567:2;3555:9;3546:7;3542:23;3538:32;3535:52;;;3583:1;3580;3573:12;3535:52;3623:9;3610:23;-1:-1:-1;;;;;3648:6:1;3645:30;3642:50;;;3688:1;3685;3678:12;3642:50;3711;3753:7;3744:6;3733:9;3729:22;3711:50;:::i;3772:328::-;3849:6;3857;3865;3918:2;3906:9;3897:7;3893:23;3889:32;3886:52;;;3934:1;3931;3924:12;3886:52;3957:29;3976:9;3957:29;:::i;:::-;3947:39;;4005:38;4039:2;4028:9;4024:18;4005:38;:::i;:::-;3995:48;;4090:2;4079:9;4075:18;4062:32;4052:42;;3772:328;;;;;:::o;4755:543::-;4843:6;4851;4904:2;4892:9;4883:7;4879:23;4875:32;4872:52;;;4920:1;4917;4910:12;4872:52;4960:9;4947:23;-1:-1:-1;;;;;5030:2:1;5022:6;5019:14;5016:34;;;5046:1;5043;5036:12;5016:34;5069:50;5111:7;5102:6;5091:9;5087:22;5069:50;:::i;:::-;5059:60;;5172:2;5161:9;5157:18;5144:32;5128:48;;5201:2;5191:8;5188:16;5185:36;;;5217:1;5214;5207:12;5185:36;;5240:52;5284:7;5273:8;5262:9;5258:24;5240:52;:::i;:::-;5230:62;;;4755:543;;;;;:::o;5303:632::-;5474:2;5526:21;;;5596:13;;5499:18;;;5618:22;;;5445:4;;5474:2;5697:15;;;;5671:2;5656:18;;;5445:4;5740:169;5754:6;5751:1;5748:13;5740:169;;;5815:13;;5803:26;;5884:15;;;;5849:12;;;;5776:1;5769:9;5740:169;;;-1:-1:-1;5926:3:1;;5303:632;-1:-1:-1;;;;;;5303:632:1:o;5940:248::-;6008:6;6016;6069:2;6057:9;6048:7;6044:23;6040:32;6037:52;;;6085:1;6082;6075:12;6037:52;-1:-1:-1;;6108:23:1;;;6178:2;6163:18;;;6150:32;;-1:-1:-1;5940:248:1:o;6193:712::-;6247:5;6300:3;6293:4;6285:6;6281:17;6277:27;6267:55;;6318:1;6315;6308:12;6267:55;6354:6;6341:20;6380:4;-1:-1:-1;;;;;6399:2:1;6396:26;6393:52;;;6425:18;;:::i;:::-;6471:2;6468:1;6464:10;6494:28;6518:2;6514;6510:11;6494:28;:::i;:::-;6556:15;;;6626;;;6622:24;;;6587:12;;;;6658:15;;;6655:35;;;6686:1;6683;6676:12;6655:35;6722:2;6714:6;6710:15;6699:26;;6734:142;6750:6;6745:3;6742:15;6734:142;;;6816:17;;6804:30;;6767:12;;;;6854;;;;6734:142;;6910:821;7062:6;7070;7078;7131:2;7119:9;7110:7;7106:23;7102:32;7099:52;;;7147:1;7144;7137:12;7099:52;7187:9;7174:23;-1:-1:-1;;;;;7257:2:1;7249:6;7246:14;7243:34;;;7273:1;7270;7263:12;7243:34;7296:61;7349:7;7340:6;7329:9;7325:22;7296:61;:::i;:::-;7286:71;;7410:2;7399:9;7395:18;7382:32;7366:48;;7439:2;7429:8;7426:16;7423:36;;;7455:1;7452;7445:12;7423:36;7478:63;7533:7;7522:8;7511:9;7507:24;7478:63;:::i;:::-;7468:73;;7594:2;7583:9;7579:18;7566:32;7550:48;;7623:2;7613:8;7610:16;7607:36;;;7639:1;7636;7629:12;7607:36;;7662:63;7717:7;7706:8;7695:9;7691:24;7662:63;:::i;:::-;7652:73;;;6910:821;;;;;:::o;7736:347::-;7801:6;7809;7862:2;7850:9;7841:7;7837:23;7833:32;7830:52;;;7878:1;7875;7868:12;7830:52;7901:29;7920:9;7901:29;:::i;:::-;7891:39;;7980:2;7969:9;7965:18;7952:32;8027:5;8020:13;8013:21;8006:5;8003:32;7993:60;;8049:1;8046;8039:12;7993:60;8072:5;8062:15;;;7736:347;;;;;:::o;8088:808::-;8185:6;8193;8201;8209;8217;8270:3;8258:9;8249:7;8245:23;8241:33;8238:53;;;8287:1;8284;8277:12;8238:53;8310:29;8329:9;8310:29;:::i;:::-;8300:39;;8358:38;8392:2;8381:9;8377:18;8358:38;:::i;:::-;8348:48;;8443:2;8432:9;8428:18;8415:32;8405:42;;8498:2;8487:9;8483:18;8470:32;-1:-1:-1;;;;;8562:2:1;8554:6;8551:14;8548:34;;;8578:1;8575;8568:12;8548:34;8616:6;8605:9;8601:22;8591:32;;8661:7;8654:4;8650:2;8646:13;8642:27;8632:55;;8683:1;8680;8673:12;8632:55;8723:2;8710:16;8749:2;8741:6;8738:14;8735:34;;;8765:1;8762;8755:12;8735:34;8810:7;8805:2;8796:6;8792:2;8788:15;8784:24;8781:37;8778:57;;;8831:1;8828;8821:12;8778:57;8088:808;;;;-1:-1:-1;8088:808:1;;-1:-1:-1;8862:2:1;8854:11;;8884:6;8088:808;-1:-1:-1;;;8088:808:1:o;8901:322::-;8978:6;8986;8994;9047:2;9035:9;9026:7;9022:23;9018:32;9015:52;;;9063:1;9060;9053:12;9015:52;9086:29;9105:9;9086:29;:::i;:::-;9076:39;9162:2;9147:18;;9134:32;;-1:-1:-1;9213:2:1;9198:18;;;9185:32;;8901:322;-1:-1:-1;;;8901:322:1:o;9228:260::-;9296:6;9304;9357:2;9345:9;9336:7;9332:23;9328:32;9325:52;;;9373:1;9370;9363:12;9325:52;9396:29;9415:9;9396:29;:::i;:::-;9386:39;;9444:38;9478:2;9467:9;9463:18;9444:38;:::i;:::-;9434:48;;9228:260;;;;;:::o;9493:380::-;9572:1;9568:12;;;;9615;;;9636:61;;9690:4;9682:6;9678:17;9668:27;;9636:61;9743:2;9735:6;9732:14;9712:18;9709:38;9706:161;;9789:10;9784:3;9780:20;9777:1;9770:31;9824:4;9821:1;9814:15;9852:4;9849:1;9842:15;9706:161;;9493:380;;;:::o;10004:518::-;10106:2;10101:3;10098:11;10095:421;;;10142:5;10139:1;10132:16;10186:4;10183:1;10173:18;10256:2;10244:10;10240:19;10237:1;10233:27;10227:4;10223:38;10292:4;10280:10;10277:20;10274:47;;;-1:-1:-1;10315:4:1;10274:47;10370:2;10365:3;10361:12;10358:1;10354:20;10348:4;10344:31;10334:41;;10425:81;10443:2;10436:5;10433:13;10425:81;;;10502:1;10488:16;;10469:1;10458:13;10425:81;;10698:1345;10824:3;10818:10;-1:-1:-1;;;;;10843:6:1;10840:30;10837:56;;;10873:18;;:::i;:::-;10902:97;10992:6;10952:38;10984:4;10978:11;10952:38;:::i;:::-;10946:4;10902:97;:::i;:::-;11054:4;;11111:2;11100:14;;11128:1;11123:663;;;;11830:1;11847:6;11844:89;;;-1:-1:-1;11899:19:1;;;11893:26;11844:89;-1:-1:-1;;10655:1:1;10651:11;;;10647:24;10643:29;10633:40;10679:1;10675:11;;;10630:57;11946:81;;11093:944;;11123:663;9951:1;9944:14;;;9988:4;9975:18;;-1:-1:-1;;11159:20:1;;;11277:236;11291:7;11288:1;11285:14;11277:236;;;11380:19;;;11374:26;11359:42;;11472:27;;;;11440:1;11428:14;;;;11307:19;;11277:236;;;11281:3;11541:6;11532:7;11529:19;11526:201;;;11602:19;;;11596:26;-1:-1:-1;;11685:1:1;11681:14;;;11697:3;11677:24;11673:37;11669:42;11654:58;11639:74;;11526:201;-1:-1:-1;;;;;11773:1:1;11757:14;;;11753:22;11740:36;;-1:-1:-1;10698:1345:1:o;12048:127::-;12109:10;12104:3;12100:20;12097:1;12090:31;12140:4;12137:1;12130:15;12164:4;12161:1;12154:15;12180:128;12247:9;;;12268:11;;;12265:37;;;12282:18;;:::i;12896:249::-;12965:6;13018:2;13006:9;12997:7;12993:23;12989:32;12986:52;;;13034:1;13031;13024:12;12986:52;13066:9;13060:16;13085:30;13109:5;13085:30;:::i;13559:127::-;13620:10;13615:3;13611:20;13608:1;13601:31;13651:4;13648:1;13641:15;13675:4;13672:1;13665:15;14508:685;14712:4;-1:-1:-1;;;;;14822:2:1;14814:6;14810:15;14799:9;14792:34;14874:2;14866:6;14862:15;14857:2;14846:9;14842:18;14835:43;;14914:6;14909:2;14898:9;14894:18;14887:34;14957:3;14952:2;14941:9;14937:18;14930:31;14998:6;14992:3;14981:9;14977:19;14970:35;15056:6;15048;15042:3;15031:9;15027:19;15014:49;15113:1;15107:3;15098:6;15087:9;15083:22;15079:32;15072:43;15183:3;15176:2;15172:7;15167:2;15159:6;15155:15;15151:29;15140:9;15136:45;15132:55;15124:63;;14508:685;;;;;;;;:::o;15198:1021::-;15374:3;15403:1;15436:6;15430:13;15466:36;15492:9;15466:36;:::i;:::-;15521:1;15538:17;;;15564:133;;;;15711:1;15706:358;;;;15531:533;;15564:133;-1:-1:-1;;15597:24:1;;15585:37;;15670:14;;15663:22;15651:35;;15642:45;;;-1:-1:-1;15564:133:1;;15706:358;15737:6;15734:1;15727:17;15767:4;15812;15809:1;15799:18;15839:1;15853:165;15867:6;15864:1;15861:13;15853:165;;;15945:14;;15932:11;;;15925:35;15988:16;;;;15882:10;;15853:165;;;15857:3;;;16047:6;16042:3;16038:16;16031:23;;15531:533;;;;;16095:6;16089:13;16111:68;16170:8;16165:3;16158:4;16150:6;16146:17;16111:68;:::i;:::-;16195:18;;15198:1021;-1:-1:-1;;;;15198:1021:1:o;16224:125::-;16289:9;;;16310:10;;;16307:36;;;16323:18;;:::i;16541:127::-;16602:10;16597:3;16593:20;16590:1;16583:31;16633:4;16630:1;16623:15;16657:4;16654:1;16647:15;16673:112;16705:1;16731;16721:35;;16736:18;;:::i;:::-;-1:-1:-1;16770:9:1;;16673:112::o;16790:486::-;17042:66;17037:3;17030:79;17012:3;17138:6;17132:13;17154:75;17222:6;17217:2;17212:3;17208:12;17201:4;17193:6;17189:17;17154:75;:::i;:::-;17249:16;;;;17267:2;17245:25;;16790:486;-1:-1:-1;;16790:486:1:o;17281:903::-;17513:3;17551:6;17545:13;17567:66;17626:6;17621:3;17614:4;17606:6;17602:17;17567:66;:::i;:::-;17694;17655:16;;17680:81;;;-1:-1:-1;17795:34:1;17788:4;17777:16;;17770:60;17862:34;17857:2;17846:14;;17839:58;17929:66;17924:2;17913:14;;17906:90;18029:66;18023:3;18012:15;;18005:91;-1:-1:-1;;;18123:3:1;18112:15;;18105:42;18174:3;18163:15;;17281:903;-1:-1:-1;17281:903:1:o;18189:496::-;18368:3;18406:6;18400:13;18422:66;18481:6;18476:3;18469:4;18461:6;18457:17;18422:66;:::i;:::-;18551:13;;18510:16;;;;18573:70;18551:13;18510:16;18620:4;18608:17;;18573:70;:::i;18690:565::-;18952:66;18947:3;18940:79;19058:30;19053:3;19049:40;19044:2;19039:3;19035:12;19028:62;18922:3;19119:6;19113:13;19135:73;19201:6;19196:2;19191:3;19187:12;19182:2;19174:6;19170:15;19135:73;:::i;:::-;19228:16;;;;19246:2;19224:25;;18690:565;-1:-1:-1;;18690:565:1:o;19260:754::-;19540:3;19578:6;19572:13;19594:66;19653:6;19648:3;19641:4;19633:6;19629:17;19594:66;:::i;:::-;19691:6;19686:3;19682:16;19669:29;;19721:66;19714:5;19707:81;19831:4;19826:3;19822:14;19815:4;19808:5;19804:16;19797:40;19868:6;19862:13;19884:79;19954:8;19949:2;19942:5;19938:14;19931:4;19923:6;19919:17;19884:79;:::i;:::-;19983:20;20005:2;19979:29;;19260:754;-1:-1:-1;;;;19260:754:1:o;20019:::-;20299:3;20337:6;20331:13;20353:66;20412:6;20407:3;20400:4;20392:6;20388:17;20353:66;:::i;:::-;20450:6;20445:3;20441:16;20428:29;;20480:66;20473:5;20466:81;20590:4;20585:3;20581:14;20574:4;20567:5;20563:16;20556:40;20627:6;20621:13;20643:79;20713:8;20708:2;20701:5;20697:14;20690:4;20682:6;20678:17;20643:79;:::i;20778:699::-;21048:3;21086:6;21080:13;21102:66;21161:6;21156:3;21149:4;21141:6;21137:17;21102:66;:::i;:::-;21199:6;21194:3;21190:16;21177:29;;21229:66;21222:5;21215:81;21327:6;21321:13;21343:81;21415:8;21408:4;21401:5;21397:16;21390:4;21382:6;21378:17;21343:81;:::i;:::-;21444:20;21466:4;21440:31;;20778:699;-1:-1:-1;;;;20778:699:1:o;21482:752::-;21762:3;21800:6;21794:13;21816:66;21875:6;21870:3;21863:4;21855:6;21851:17;21816:66;:::i;:::-;21913:6;21908:3;21904:16;21891:29;;21943:66;21936:5;21929:81;22053:2;22048:3;22044:12;22037:4;22030:5;22026:16;22019:38;22088:6;22082:13;22104:79;22174:8;22169:2;22162:5;22158:14;22151:4;22143:6;22139:17;22104:79;:::i;:::-;22203:20;22225:2;22199:29;;21482:752;-1:-1:-1;;;;21482:752:1:o;22239:695::-;22509:3;22547:6;22541:13;22563:66;22622:6;22617:3;22610:4;22602:6;22598:17;22563:66;:::i;:::-;22690;22651:16;;;22676:81;;;22782:13;;22804:79;22782:13;22869:2;22858:14;;22851:4;22839:17;;22804:79;:::i;:::-;22903:20;22925:2;22899:29;;22239:695;-1:-1:-1;;;;22239:695:1:o;22939:449::-;23191:29;23186:3;23179:42;23161:3;23250:6;23244:13;23266:75;23334:6;23329:2;23324:3;23320:12;23313:4;23305:6;23301:17;23266:75;:::i;:::-;23361:16;;;;23379:2;23357:25;;22939:449;-1:-1:-1;;22939:449:1:o;23393:120::-;23433:1;23459;23449:35;;23464:18;;:::i;:::-;-1:-1:-1;23498:9:1;;23393:120::o;23518:428::-;-1:-1:-1;;;23764:3:1;23757:24;23739:3;23810:6;23804:13;23826:74;23893:6;23889:1;23884:3;23880:11;23873:4;23865:6;23861:17;23826:74;:::i;:::-;23920:16;;;;23938:1;23916:24;;23518:428;-1:-1:-1;;23518:428:1:o;23951:441::-;24172:3;24210:6;24204:13;24226:66;24285:6;24280:3;24273:4;24265:6;24261:17;24226:66;:::i;:::-;-1:-1:-1;;;24314:16:1;;24339:18;;;-1:-1:-1;24384:1:1;24373:13;;23951:441;-1:-1:-1;23951:441:1:o;24397:651::-;24666:3;24704:6;24698:13;24720:66;24779:6;24774:3;24767:4;24759:6;24755:17;24720:66;:::i;:::-;24849:13;;24808:16;;;;24871:70;24849:13;24808:16;24918:4;24906:17;;24871:70;:::i;:::-;-1:-1:-1;;;24963:20:1;;24992:21;;;25040:1;25029:13;;24397:651;-1:-1:-1;;;;24397:651:1:o;25053:574::-;-1:-1:-1;;;25389:3:1;25382:23;25364:3;25434:6;25428:13;25450:74;25517:6;25513:1;25508:3;25504:11;25497:4;25489:6;25485:17;25450:74;:::i;:::-;-1:-1:-1;;;25583:1:1;25543:16;;;;25575:10;;;25568:26;-1:-1:-1;25618:2:1;25610:11;;25053:574;-1:-1:-1;25053:574:1:o;25632:570::-;-1:-1:-1;;;25968:3:1;25961:20;25943:3;26010:6;26004:13;26026:74;26093:6;26089:1;26084:3;26080:11;26073:4;26065:6;26061:17;26026:74;:::i;:::-;-1:-1:-1;;;26159:1:1;26119:16;;;;26151:10;;;26144:26;-1:-1:-1;26194:1:1;26186:10;;25632:570;-1:-1:-1;25632:570:1:o;26207:579::-;-1:-1:-1;;;26544:3:1;26537:25;26519:3;26591:6;26585:13;26607:75;26675:6;26670:2;26665:3;26661:12;26654:4;26646:6;26642:17;26607:75;:::i;:::-;-1:-1:-1;;;26741:2:1;26701:16;;;;26733:11;;;26726:27;-1:-1:-1;26777:2:1;26769:11;;26207:579;-1:-1:-1;26207:579:1:o;26791:135::-;26830:3;26851:17;;;26848:43;;26871:18;;:::i;:::-;-1:-1:-1;26918:1:1;26907:13;;26791:135::o

Swarm Source

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