ETH Price: $3,327.47 (-0.96%)

Token

Sappy Soulbounds (SSOULS)
 

Overview

Max Total Supply

4,263 SSOULS

Holders

4,263

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
0x6a0918fb24c3ebf07fd583823141e77e4f1a5373
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:
SappySouls

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-12-25
*/

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

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

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

    function _revert(bytes memory returndata, string memory errorMessage) private pure {
        // Look for revert reason and bubble it up if present
        if (returndata.length > 0) {
            // The easiest way to bubble the revert reason is using memory via assembly
            /// @solidity memory-safe-assembly
            assembly {
                let returndata_size := mload(returndata)
                revert(add(32, returndata), returndata_size)
            }
        } else {
            revert(errorMessage);
        }
    }
}

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


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

pragma solidity ^0.8.0;

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

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


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

pragma solidity ^0.8.0;


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

// File: @openzeppelin/contracts/token/ERC1155/IERC1155Receiver.sol


// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC1155/IERC1155Receiver.sol)

pragma solidity ^0.8.0;


/**
 * @dev _Available since v3.1._
 */
interface IERC1155Receiver is IERC165 {
    /**
     * @dev Handles the receipt of a single ERC1155 token type. This function is
     * called at the end of a `safeTransferFrom` after the balance has been updated.
     *
     * NOTE: To accept the transfer, this must return
     * `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))`
     * (i.e. 0xf23a6e61, or its own function selector).
     *
     * @param operator The address which initiated the transfer (i.e. msg.sender)
     * @param from The address which previously owned the token
     * @param id The ID of the token being transferred
     * @param value The amount of tokens being transferred
     * @param data Additional data with no specified format
     * @return `bytes4(keccak256("onERC1155Received(address,address,uint256,uint256,bytes)"))` if transfer is allowed
     */
    function onERC1155Received(
        address operator,
        address from,
        uint256 id,
        uint256 value,
        bytes calldata data
    ) external returns (bytes4);

    /**
     * @dev Handles the receipt of a multiple ERC1155 token types. This function
     * is called at the end of a `safeBatchTransferFrom` after the balances have
     * been updated.
     *
     * NOTE: To accept the transfer(s), this must return
     * `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))`
     * (i.e. 0xbc197c81, or its own function selector).
     *
     * @param operator The address which initiated the batch transfer (i.e. msg.sender)
     * @param from The address which previously owned the token
     * @param ids An array containing ids of each token being transferred (order and length must match values array)
     * @param values An array containing amounts of each token being transferred (order and length must match ids array)
     * @param data Additional data with no specified format
     * @return `bytes4(keccak256("onERC1155BatchReceived(address,address,uint256[],uint256[],bytes)"))` if transfer is allowed
     */
    function onERC1155BatchReceived(
        address operator,
        address from,
        uint256[] calldata ids,
        uint256[] calldata values,
        bytes calldata data
    ) external returns (bytes4);
}

// File: @openzeppelin/contracts/token/ERC1155/IERC1155.sol


// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC1155/IERC1155.sol)

pragma solidity ^0.8.0;


/**
 * @dev Required interface of an ERC1155 compliant contract, as defined in the
 * https://eips.ethereum.org/EIPS/eip-1155[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155 is IERC165 {
    /**
     * @dev Emitted when `value` tokens of token type `id` are transferred from `from` to `to` by `operator`.
     */
    event TransferSingle(address indexed operator, address indexed from, address indexed to, uint256 id, uint256 value);

    /**
     * @dev Equivalent to multiple {TransferSingle} events, where `operator`, `from` and `to` are the same for all
     * transfers.
     */
    event TransferBatch(
        address indexed operator,
        address indexed from,
        address indexed to,
        uint256[] ids,
        uint256[] values
    );

    /**
     * @dev Emitted when `account` grants or revokes permission to `operator` to transfer their tokens, according to
     * `approved`.
     */
    event ApprovalForAll(address indexed account, address indexed operator, bool approved);

    /**
     * @dev Emitted when the URI for token type `id` changes to `value`, if it is a non-programmatic URI.
     *
     * If an {URI} event was emitted for `id`, the standard
     * https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[guarantees] that `value` will equal the value
     * returned by {IERC1155MetadataURI-uri}.
     */
    event URI(string value, uint256 indexed id);

    /**
     * @dev Returns the amount of tokens of token type `id` owned by `account`.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) external view returns (uint256);

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {balanceOf}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] calldata accounts, uint256[] calldata ids)
        external
        view
        returns (uint256[] memory);

    /**
     * @dev Grants or revokes permission to `operator` to transfer the caller's tokens, according to `approved`,
     *
     * Emits an {ApprovalForAll} event.
     *
     * Requirements:
     *
     * - `operator` cannot be the caller.
     */
    function setApprovalForAll(address operator, bool approved) external;

    /**
     * @dev Returns true if `operator` is approved to transfer ``account``'s tokens.
     *
     * See {setApprovalForAll}.
     */
    function isApprovedForAll(address account, address operator) external view returns (bool);

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If the caller is not `from`, it must have been approved to spend ``from``'s tokens via {setApprovalForAll}.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes calldata data
    ) external;

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] calldata ids,
        uint256[] calldata amounts,
        bytes calldata data
    ) external;
}

// File: @openzeppelin/contracts/token/ERC1155/extensions/IERC1155MetadataURI.sol


// OpenZeppelin Contracts v4.4.1 (token/ERC1155/extensions/IERC1155MetadataURI.sol)

pragma solidity ^0.8.0;


/**
 * @dev Interface of the optional ERC1155MetadataExtension interface, as defined
 * in the https://eips.ethereum.org/EIPS/eip-1155#metadata-extensions[EIP].
 *
 * _Available since v3.1._
 */
interface IERC1155MetadataURI is IERC1155 {
    /**
     * @dev Returns the URI for token type `id`.
     *
     * If the `\{id\}` substring is present in the URI, it must be replaced by
     * clients with the actual token type ID.
     */
    function uri(uint256 id) external view returns (string memory);
}

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


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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


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

pragma solidity ^0.8.0;


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

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

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

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

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

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


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

pragma solidity ^0.8.0;


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

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        }
    }

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

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

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
        uint8 v = uint8((uint256(vs) >> 255) + 27);
        return tryRecover(hash, v, r, s);
    }

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

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

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

        return (signer, RecoverError.NoError);
    }

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

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}

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


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

pragma solidity ^0.8.0;

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

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

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


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

pragma solidity ^0.8.0;







/**
 * @dev Implementation of the basic standard multi-token.
 * See https://eips.ethereum.org/EIPS/eip-1155
 * Originally based on code by Enjin: https://github.com/enjin/erc-1155
 *
 * _Available since v3.1._
 */
contract ERC1155 is Context, ERC165, IERC1155, IERC1155MetadataURI {
    using Address for address;

    // Mapping from token ID to account balances
    mapping(uint256 => mapping(address => uint256)) private _balances;

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

    // Used as the URI for all token types by relying on ID substitution, e.g. https://token-cdn-domain/{id}.json
    string private _uri;

    /**
     * @dev See {_setURI}.
     */
    constructor(string memory uri_) {
        _setURI(uri_);
    }

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

    /**
     * @dev See {IERC1155MetadataURI-uri}.
     *
     * This implementation returns the same URI for *all* token types. It relies
     * on the token type ID substitution mechanism
     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
     *
     * Clients calling this function must replace the `\{id\}` substring with the
     * actual token type ID.
     */
    function uri(uint256) public view virtual override returns (string memory) {
        return _uri;
    }

    /**
     * @dev See {IERC1155-balanceOf}.
     *
     * Requirements:
     *
     * - `account` cannot be the zero address.
     */
    function balanceOf(address account, uint256 id) public view virtual override returns (uint256) {
        require(account != address(0), "ERC1155: address zero is not a valid owner");
        return _balances[id][account];
    }

    /**
     * @dev See {IERC1155-balanceOfBatch}.
     *
     * Requirements:
     *
     * - `accounts` and `ids` must have the same length.
     */
    function balanceOfBatch(address[] memory accounts, uint256[] memory ids)
        public
        view
        virtual
        override
        returns (uint256[] memory)
    {
        require(accounts.length == ids.length, "ERC1155: accounts and ids length mismatch");

        uint256[] memory batchBalances = new uint256[](accounts.length);

        for (uint256 i = 0; i < accounts.length; ++i) {
            batchBalances[i] = balanceOf(accounts[i], ids[i]);
        }

        return batchBalances;
    }

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

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

    /**
     * @dev See {IERC1155-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) public virtual override {
        require(
            from == _msgSender() || isApprovedForAll(from, _msgSender()),
            "ERC1155: caller is not token owner or approved"
        );
        _safeTransferFrom(from, to, id, amount, data);
    }

    /**
     * @dev See {IERC1155-safeBatchTransferFrom}.
     */
    function safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) public virtual override {
        require(
            from == _msgSender() || isApprovedForAll(from, _msgSender()),
            "ERC1155: caller is not token owner or approved"
        );
        _safeBatchTransferFrom(from, to, ids, amounts, data);
    }

    /**
     * @dev Transfers `amount` tokens of token type `id` from `from` to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `from` must have a balance of tokens of type `id` of at least `amount`.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function _safeTransferFrom(
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        require(to != address(0), "ERC1155: transfer to the zero address");

        address operator = _msgSender();
        uint256[] memory ids = _asSingletonArray(id);
        uint256[] memory amounts = _asSingletonArray(amount);

        _beforeTokenTransfer(operator, from, to, ids, amounts, data);

        uint256 fromBalance = _balances[id][from];
        require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
        unchecked {
            _balances[id][from] = fromBalance - amount;
        }
        _balances[id][to] += amount;

        emit TransferSingle(operator, from, to, id, amount);

        _afterTokenTransfer(operator, from, to, ids, amounts, data);

        _doSafeTransferAcceptanceCheck(operator, from, to, id, amount, data);
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_safeTransferFrom}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function _safeBatchTransferFrom(
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");
        require(to != address(0), "ERC1155: transfer to the zero address");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, from, to, ids, amounts, data);

        for (uint256 i = 0; i < ids.length; ++i) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];

            uint256 fromBalance = _balances[id][from];
            require(fromBalance >= amount, "ERC1155: insufficient balance for transfer");
            unchecked {
                _balances[id][from] = fromBalance - amount;
            }
            _balances[id][to] += amount;
        }

        emit TransferBatch(operator, from, to, ids, amounts);

        _afterTokenTransfer(operator, from, to, ids, amounts, data);

        _doSafeBatchTransferAcceptanceCheck(operator, from, to, ids, amounts, data);
    }

    /**
     * @dev Sets a new URI for all token types, by relying on the token type ID
     * substitution mechanism
     * https://eips.ethereum.org/EIPS/eip-1155#metadata[defined in the EIP].
     *
     * By this mechanism, any occurrence of the `\{id\}` substring in either the
     * URI or any of the amounts in the JSON file at said URI will be replaced by
     * clients with the token type ID.
     *
     * For example, the `https://token-cdn-domain/\{id\}.json` URI would be
     * interpreted by clients as
     * `https://token-cdn-domain/000000000000000000000000000000000000000000000000000000000004cce0.json`
     * for token type ID 0x4cce0.
     *
     * See {uri}.
     *
     * Because these URIs cannot be meaningfully represented by the {URI} event,
     * this function emits no events.
     */
    function _setURI(string memory newuri) internal virtual {
        _uri = newuri;
    }

    /**
     * @dev Creates `amount` tokens of token type `id`, and assigns them to `to`.
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155Received} and return the
     * acceptance magic value.
     */
    function _mint(
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) internal virtual {
        require(to != address(0), "ERC1155: mint to the zero address");

        address operator = _msgSender();
        uint256[] memory ids = _asSingletonArray(id);
        uint256[] memory amounts = _asSingletonArray(amount);

        _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);

        _balances[id][to] += amount;
        emit TransferSingle(operator, address(0), to, id, amount);

        _afterTokenTransfer(operator, address(0), to, ids, amounts, data);

        _doSafeTransferAcceptanceCheck(operator, address(0), to, id, amount, data);
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_mint}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     * - If `to` refers to a smart contract, it must implement {IERC1155Receiver-onERC1155BatchReceived} and return the
     * acceptance magic value.
     */
    function _mintBatch(
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {
        require(to != address(0), "ERC1155: mint to the zero address");
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, address(0), to, ids, amounts, data);

        for (uint256 i = 0; i < ids.length; i++) {
            _balances[ids[i]][to] += amounts[i];
        }

        emit TransferBatch(operator, address(0), to, ids, amounts);

        _afterTokenTransfer(operator, address(0), to, ids, amounts, data);

        _doSafeBatchTransferAcceptanceCheck(operator, address(0), to, ids, amounts, data);
    }

    /**
     * @dev Destroys `amount` tokens of token type `id` from `from`
     *
     * Emits a {TransferSingle} event.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `from` must have at least `amount` tokens of token type `id`.
     */
    function _burn(
        address from,
        uint256 id,
        uint256 amount
    ) internal virtual {
        require(from != address(0), "ERC1155: burn from the zero address");

        address operator = _msgSender();
        uint256[] memory ids = _asSingletonArray(id);
        uint256[] memory amounts = _asSingletonArray(amount);

        _beforeTokenTransfer(operator, from, address(0), ids, amounts, "");

        uint256 fromBalance = _balances[id][from];
        require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
        unchecked {
            _balances[id][from] = fromBalance - amount;
        }

        emit TransferSingle(operator, from, address(0), id, amount);

        _afterTokenTransfer(operator, from, address(0), ids, amounts, "");
    }

    /**
     * @dev xref:ROOT:erc1155.adoc#batch-operations[Batched] version of {_burn}.
     *
     * Emits a {TransferBatch} event.
     *
     * Requirements:
     *
     * - `ids` and `amounts` must have the same length.
     */
    function _burnBatch(
        address from,
        uint256[] memory ids,
        uint256[] memory amounts
    ) internal virtual {
        require(from != address(0), "ERC1155: burn from the zero address");
        require(ids.length == amounts.length, "ERC1155: ids and amounts length mismatch");

        address operator = _msgSender();

        _beforeTokenTransfer(operator, from, address(0), ids, amounts, "");

        for (uint256 i = 0; i < ids.length; i++) {
            uint256 id = ids[i];
            uint256 amount = amounts[i];

            uint256 fromBalance = _balances[id][from];
            require(fromBalance >= amount, "ERC1155: burn amount exceeds balance");
            unchecked {
                _balances[id][from] = fromBalance - amount;
            }
        }

        emit TransferBatch(operator, from, address(0), ids, amounts);

        _afterTokenTransfer(operator, from, address(0), ids, amounts, "");
    }

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

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning, as well as batched variants.
     *
     * The same hook is called on both single and batched variants. For single
     * transfers, the length of the `ids` and `amounts` arrays will be 1.
     *
     * Calling conditions (for each `id` and `amount` pair):
     *
     * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * of token type `id` will be  transferred to `to`.
     * - When `from` is zero, `amount` tokens of token type `id` will be minted
     * for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
     * will be burned.
     * - `from` and `to` are never both zero.
     * - `ids` and `amounts` have the same, non-zero length.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {}

    /**
     * @dev Hook that is called after any token transfer. This includes minting
     * and burning, as well as batched variants.
     *
     * The same hook is called on both single and batched variants. For single
     * transfers, the length of the `id` and `amount` arrays will be 1.
     *
     * Calling conditions (for each `id` and `amount` pair):
     *
     * - When `from` and `to` are both non-zero, `amount` of ``from``'s tokens
     * of token type `id` will be  transferred to `to`.
     * - When `from` is zero, `amount` tokens of token type `id` will be minted
     * for `to`.
     * - when `to` is zero, `amount` of ``from``'s tokens of token type `id`
     * will be burned.
     * - `from` and `to` are never both zero.
     * - `ids` and `amounts` have the same, non-zero length.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) internal virtual {}

    function _doSafeTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256 id,
        uint256 amount,
        bytes memory data
    ) private {
        if (to.isContract()) {
            try IERC1155Receiver(to).onERC1155Received(operator, from, id, amount, data) returns (bytes4 response) {
                if (response != IERC1155Receiver.onERC1155Received.selector) {
                    revert("ERC1155: ERC1155Receiver rejected tokens");
                }
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert("ERC1155: transfer to non-ERC1155Receiver implementer");
            }
        }
    }

    function _doSafeBatchTransferAcceptanceCheck(
        address operator,
        address from,
        address to,
        uint256[] memory ids,
        uint256[] memory amounts,
        bytes memory data
    ) private {
        if (to.isContract()) {
            try IERC1155Receiver(to).onERC1155BatchReceived(operator, from, ids, amounts, data) returns (
                bytes4 response
            ) {
                if (response != IERC1155Receiver.onERC1155BatchReceived.selector) {
                    revert("ERC1155: ERC1155Receiver rejected tokens");
                }
            } catch Error(string memory reason) {
                revert(reason);
            } catch {
                revert("ERC1155: transfer to non-ERC1155Receiver implementer");
            }
        }
    }

    function _asSingletonArray(uint256 element) private pure returns (uint256[] memory) {
        uint256[] memory array = new uint256[](1);
        array[0] = element;

        return array;
    }
}

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


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

pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

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

// File: contracts/SappySouls.sol


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

pragma solidity ^0.8.0;







contract VerifySignature is Ownable {

    using ECDSA for bytes32;

    // The version of signatures that are valid
    string private _signVersion;

    // The wallet that signed the data
    address private _signerWallet;

    constructor(string memory signVersion_, address signerWallet_){
        _signVersion = signVersion_;
        _signerWallet = signerWallet_;
    }

    /**
     * @dev External function to update the signer version if a change is required.
     *      This can only be accessed by the owner of the contract
     *      NOTE: This will not allow any previous signatures made to be used
     *
     * @param signVersion_ a new version string to be used during verification
     */
    function updateSignVersion(string calldata signVersion_) external onlyOwner {
        _signVersion = signVersion_;
    }

    /**
     * @dev External function to update the signer wallet if a change is required
     *      This can only be accessed by the owner of the contract
     *      NOTE: This will not allow any previous signatures made to be used
     *
     * @param signerWallet_ the new wallet to be the signerWallet
     */
    function updateSignerWallet(address signerWallet_) external onlyOwner {
        _signerWallet = signerWallet_;
    }

    /**
     * @dev Internal function to validate a signatures data.
     *
     * @param sender the address who sent the signature to the contract
     * @param tokenId the id the number of the token that can be minted
     * @param nonce to mark the signature has been used
     * @param signature the signature created by the signerWallet
     * @return bool whether the signature matches the passed data or not
     */
    function _verify(
        address sender,
        uint256 tokenId,
        uint256 nonce,
        bytes memory signature
    ) internal view returns (bool) {
        return keccak256(abi.encodePacked(sender, _signVersion, tokenId, nonce))
        .toEthSignedMessageHash()
        .recover(signature) == _signerWallet;
    }
}

    error FunctionNotSupported();
    error SignatureNotValid();
    error SignatureAlreadyUsed();
    error ClaimNotOpen();

/*
    Sappy Soul Bound token
 */

contract SappySouls is ERC1155, VerifySignature {
    using Strings for uint256;

    mapping(uint256 => bool) nonceUsed;

    bool public claimPaused = true;

    string private baseURI;
    string private baseURISuffix;
    string private _name = "Sappy Soulbounds";
    string private _symbol = "SSOULS";

    constructor(string memory _base, string memory _suffix)
    ERC1155("")
    VerifySignature("sappySouls-v1", msg.sender)
    {
        baseURI = _base;
        baseURISuffix = _suffix;
    }

    function airdropSappySouls(
        uint256 id,
        address [] calldata holders
    ) external onlyOwner {
        for(uint i = 0; i < holders.length; i++){
            _mint(holders[i], id, 1, "");
        }
    }

    function claimSappySoulsToWallet(
        address receiverWallet,
        uint256 id,
        uint256 nonce,
        bytes memory signature
    ) external {
        if(claimPaused) revert ClaimNotOpen();
        if(!_verify(receiverWallet, id, nonce, signature)) revert SignatureNotValid();
        if(nonceUsed[nonce]) revert SignatureAlreadyUsed();

        nonceUsed[nonce] = true;
        _mint(receiverWallet, id, 1, "");
    }

    function burnTrueSappySoul(uint256 id) external {
        _burn(msg.sender, id, 1);
    }

    function adminBurnSappySoul(address holder, uint256 id) external onlyOwner {
        _burn(holder, id, 1);
    }
    
    function name() public view virtual returns (string memory) {
        return _name;
    }

    function symbol() public view virtual returns (string memory) {
        return _symbol;
    }

    function uri(uint256 id) public view override returns (string memory) {
        return string(abi.encodePacked(baseURI, id.toString(), baseURISuffix));
    }

    function setURI(string calldata _base, string calldata _suffix) external onlyOwner {
        baseURI = _base;
        baseURISuffix = _suffix;
    }

    function pause() external onlyOwner {
        claimPaused = true;
    }

    function unpause() external onlyOwner {
        claimPaused = false;
    }

    /*
     * All functions having to do with the transfer of the NFT's have been overridden.
     * Although the approval functions don't need to be overridden, there is no use
     * for them, so I am overriding to save users gas in case they try and execute them.
     */
    function setApprovalForAll(
        address,
        bool
    ) public pure override {
        revert FunctionNotSupported();
    }

    function safeTransferFrom(
        address,
        address,
        uint256,
        uint256,
        bytes memory
    ) public pure override {
        revert FunctionNotSupported();
    }

    function safeBatchTransferFrom(
        address,
        address,
        uint256[] memory,
        uint256[] memory,
        bytes memory
    ) public pure override {
        revert FunctionNotSupported();
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_base","type":"string"},{"internalType":"string","name":"_suffix","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ClaimNotOpen","type":"error"},{"inputs":[],"name":"FunctionNotSupported","type":"error"},{"inputs":[],"name":"SignatureAlreadyUsed","type":"error"},{"inputs":[],"name":"SignatureNotValid","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"account","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"ids","type":"uint256[]"},{"indexed":false,"internalType":"uint256[]","name":"values","type":"uint256[]"}],"name":"TransferBatch","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"id","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"value","type":"uint256"}],"name":"TransferSingle","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"value","type":"string"},{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"URI","type":"event"},{"inputs":[{"internalType":"address","name":"holder","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"adminBurnSappySoul","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"address[]","name":"holders","type":"address[]"}],"name":"airdropSappySouls","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"accounts","type":"address[]"},{"internalType":"uint256[]","name":"ids","type":"uint256[]"}],"name":"balanceOfBatch","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"burnTrueSappySoul","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"claimPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"receiverWallet","type":"address"},{"internalType":"uint256","name":"id","type":"uint256"},{"internalType":"uint256","name":"nonce","type":"uint256"},{"internalType":"bytes","name":"signature","type":"bytes"}],"name":"claimSappySoulsToWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"safeBatchTransferFrom","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"bytes","name":"","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"},{"internalType":"bool","name":"","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"pure","type":"function"},{"inputs":[{"internalType":"string","name":"_base","type":"string"},{"internalType":"string","name":"_suffix","type":"string"}],"name":"setURI","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":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"signVersion_","type":"string"}],"name":"updateSignVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"signerWallet_","type":"address"}],"name":"updateSignerWallet","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"id","type":"uint256"}],"name":"uri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}]

60806040526001600760006101000a81548160ff0219169083151502179055506040518060400160405280601081526020017f536170707920536f756c626f756e647300000000000000000000000000000000815250600a90805190602001906200006c929190620002e7565b506040518060400160405280600681526020017f53534f554c530000000000000000000000000000000000000000000000000000815250600b9080519060200190620000ba929190620002e7565b50348015620000c857600080fd5b5060405162003a5138038062003a518339818101604052810190620000ee919062000415565b6040518060400160405280600d81526020017f7361707079536f756c732d76310000000000000000000000000000000000000081525033604051806020016040528060008152506200014681620001fd60201b60201c565b50620001676200015b6200021960201b60201c565b6200022160201b60201c565b81600490805190602001906200017f929190620002e7565b5080600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050508160089080519060200190620001db929190620002e7565b508060099080519060200190620001f4929190620002e7565b5050506200061e565b806002908051906020019062000215929190620002e7565b5050565b600033905090565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b828054620002f5906200052f565b90600052602060002090601f01602090048101928262000319576000855562000365565b82601f106200033457805160ff191683800117855562000365565b8280016001018555821562000365579182015b828111156200036457825182559160200191906001019062000347565b5b50905062000374919062000378565b5090565b5b808211156200039357600081600090555060010162000379565b5090565b6000620003ae620003a884620004c3565b6200049a565b905082815260208101848484011115620003cd57620003cc620005fe565b5b620003da848285620004f9565b509392505050565b600082601f830112620003fa57620003f9620005f9565b5b81516200040c84826020860162000397565b91505092915050565b600080604083850312156200042f576200042e62000608565b5b600083015167ffffffffffffffff81111562000450576200044f62000603565b5b6200045e85828601620003e2565b925050602083015167ffffffffffffffff81111562000482576200048162000603565b5b6200049085828601620003e2565b9150509250929050565b6000620004a6620004b9565b9050620004b4828262000565565b919050565b6000604051905090565b600067ffffffffffffffff821115620004e157620004e0620005ca565b5b620004ec826200060d565b9050602081019050919050565b60005b8381101562000519578082015181840152602081019050620004fc565b8381111562000529576000848401525b50505050565b600060028204905060018216806200054857607f821691505b602082108114156200055f576200055e6200059b565b5b50919050565b62000570826200060d565b810181811067ffffffffffffffff82111715620005925762000591620005ca565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b613423806200062e6000396000f3fe608060405234801561001057600080fd5b506004361061014c5760003560e01c80638da5cb5b116100c3578063bf2db4c81161007c578063bf2db4c81461034f578063c72d086b1461036b578063e985e9c514610387578063f242432a146103b7578063f2fde38b146103d3578063fbfa13aa146103ef5761014c565b80638da5cb5b146102a15780638e3a7249146102bf57806395d89b41146102db578063a22cb465146102f9578063ab5e124a14610315578063b8896d35146103335761014c565b80633f4ba83a116101155780633f4ba83a1461021b57806348386759146102255780634e1273f414610241578063715018a6146102715780638280a2711461027b5780638456cb59146102975761014c565b8062fdd58e1461015157806301ffc9a71461018157806306fdde03146101b15780630e89341c146101cf5780632eb2c2d6146101ff575b600080fd5b61016b60048036038101906101669190612059565b61040b565b6040516101789190612a81565b60405180910390f35b61019b60048036038101906101969190612194565b6104d4565b6040516101a8919061287f565b60405180910390f35b6101b96105b6565b6040516101c691906128df565b60405180910390f35b6101e960048036038101906101e491906122bc565b610648565b6040516101f691906128df565b60405180910390f35b61021960048036038101906102149190611eb3565b61067f565b005b6102236106b1565b005b61023f600480360381019061023a9190612059565b6106d6565b005b61025b6004803603810190610256919061211c565b6106ee565b604051610268919061285d565b60405180910390f35b610279610807565b005b610295600480360381019061029091906122e9565b61081b565b005b61029f61088d565b005b6102a96108b2565b6040516102b691906127e8565b60405180910390f35b6102d960048036038101906102d491906121ee565b6108dc565b005b6102e36108fa565b6040516102f091906128df565b60405180910390f35b610313600480360381019061030e9190612019565b61098c565b005b61031d6109be565b60405161032a919061287f565b60405180910390f35b61034d60048036038101906103489190612099565b6109d1565b005b6103696004803603810190610364919061223b565b610b00565b005b610385600480360381019061038091906122bc565b610b32565b005b6103a1600480360381019061039c9190611e73565b610b41565b6040516103ae919061287f565b60405180910390f35b6103d160048036038101906103cc9190611f82565b610bd5565b005b6103ed60048036038101906103e89190611e46565b610c07565b005b61040960048036038101906104049190611e46565b610c8b565b005b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561047c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610473906129a1565b60405180910390fd5b60008083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60007fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061059f57507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806105af57506105ae82610cd7565b5b9050919050565b6060600a80546105c590612d27565b80601f01602080910402602001604051908101604052809291908181526020018280546105f190612d27565b801561063e5780601f106106135761010080835404028352916020019161063e565b820191906000526020600020905b81548152906001019060200180831161062157829003601f168201915b5050505050905090565b6060600861065583610d41565b600960405160200161066993929190612791565b6040516020818303038152906040529050919050565b6040517fd37a223a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106b9610e19565b6000600760006101000a81548160ff021916908315150217905550565b6106de610e19565b6106ea82826001610e97565b5050565b60608151835114610734576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161072b90612a21565b60405180910390fd5b6000835167ffffffffffffffff81111561075157610750612ef6565b5b60405190808252806020026020018201604052801561077f5781602001602082028036833780820191505090505b50905060005b84518110156107fc576107cc8582815181106107a4576107a3612ec7565b5b60200260200101518583815181106107bf576107be612ec7565b5b602002602001015161040b565b8282815181106107df576107de612ec7565b5b602002602001018181525050806107f590612d8a565b9050610785565b508091505092915050565b61080f610e19565b61081960006110de565b565b610823610e19565b60005b828290508110156108875761087483838381811061084757610846612ec7565b5b905060200201602081019061085c9190611e46565b856001604051806020016040528060008152506111a4565b808061087f90612d8a565b915050610826565b50505050565b610895610e19565b6001600760006101000a81548160ff021916908315150217905550565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6108e4610e19565b8181600491906108f5929190611ae2565b505050565b6060600b805461090990612d27565b80601f016020809104026020016040519081016040528092919081815260200182805461093590612d27565b80156109825780601f1061095757610100808354040283529160200191610982565b820191906000526020600020905b81548152906001019060200180831161096557829003601f168201915b5050505050905090565b6040517fd37a223a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600760009054906101000a900460ff1681565b600760009054906101000a900460ff1615610a18576040517f6b68780600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a2484848484611355565b610a5a576040517f401b4d9700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900460ff1615610ab2576040517f900bb2c900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016006600084815260200190815260200160002060006101000a81548160ff021916908315150217905550610afa84846001604051806020016040528060008152506111a4565b50505050565b610b08610e19565b838360089190610b19929190611ae2565b50818160099190610b2b929190611ae2565b5050505050565b610b3e33826001610e97565b50565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6040517fd37a223a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c0f610e19565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610c7f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c7690612961565b60405180910390fd5b610c88816110de565b50565b610c93610e19565b80600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b606060006001610d50846113f9565b01905060008167ffffffffffffffff811115610d6f57610d6e612ef6565b5b6040519080825280601f01601f191660200182016040528015610da15781602001600182028036833780820191505090505b509050600082602001820190505b600115610e0e578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581610df857610df7612e3a565b5b0494506000851415610e0957610e0e565b610daf565b819350505050919050565b610e2161154c565b73ffffffffffffffffffffffffffffffffffffffff16610e3f6108b2565b73ffffffffffffffffffffffffffffffffffffffff1614610e95576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e8c90612a01565b60405180910390fd5b565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610f07576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610efe906129e1565b60405180910390fd5b6000610f1161154c565b90506000610f1e84611554565b90506000610f2b84611554565b9050610f4b838760008585604051806020016040528060008152506115ce565b600080600087815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905084811015610fe2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fd990612981565b60405180910390fd5b84810360008088815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6289896040516110af929190612a9c565b60405180910390a46110d5848860008686604051806020016040528060008152506115d6565b50505050505050565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611214576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120b90612a41565b60405180910390fd5b600061121e61154c565b9050600061122b85611554565b9050600061123885611554565b9050611249836000898585896115ce565b8460008088815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546112a89190612c04565b925050819055508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628989604051611326929190612a9c565b60405180910390a461133d836000898585896115d6565b61134c836000898989896115de565b50505050505050565b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166113d8836113ca88600489896040516020016113af9493929190612747565b604051602081830303815290604052805190602001206117c5565b6117f590919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff16149050949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310611457577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161144d5761144c612e3a565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611494576d04ee2d6d415b85acef8100000000838161148a57611489612e3a565b5b0492506020810190505b662386f26fc1000083106114c357662386f26fc1000083816114b9576114b8612e3a565b5b0492506010810190505b6305f5e10083106114ec576305f5e10083816114e2576114e1612e3a565b5b0492506008810190505b612710831061151157612710838161150757611506612e3a565b5b0492506004810190505b60648310611534576064838161152a57611529612e3a565b5b0492506002810190505b600a8310611543576001810190505b80915050919050565b600033905090565b60606000600167ffffffffffffffff81111561157357611572612ef6565b5b6040519080825280602002602001820160405280156115a15781602001602082028036833780820191505090505b50905082816000815181106115b9576115b8612ec7565b5b60200260200101818152505080915050919050565b505050505050565b505050505050565b6115fd8473ffffffffffffffffffffffffffffffffffffffff1661181c565b156117bd578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b8152600401611643959493929190612803565b602060405180830381600087803b15801561165d57600080fd5b505af192505050801561168e57506040513d601f19601f8201168201806040525081019061168b91906121c1565b60015b6117345761169a612f25565b806308c379a014156116f757506116af6132fb565b806116ba57506116f9565b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ee91906128df565b60405180910390fd5b505b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161172b90612a61565b60405180910390fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146117bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117b290612921565b60405180910390fd5b505b505050505050565b6000816040516020016117d891906127c2565b604051602081830303815290604052805190602001209050919050565b6000806000611804858561183f565b9150915061181181611891565b819250505092915050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6000806041835114156118815760008060006020860151925060408601519150606086015160001a9050611875878285856119ff565b9450945050505061188a565b60006002915091505b9250929050565b600060048111156118a5576118a4612e69565b5b8160048111156118b8576118b7612e69565b5b14156118c3576119fc565b600160048111156118d7576118d6612e69565b5b8160048111156118ea576118e9612e69565b5b141561192b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161192290612901565b60405180910390fd5b6002600481111561193f5761193e612e69565b5b81600481111561195257611951612e69565b5b1415611993576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161198a90612941565b60405180910390fd5b600360048111156119a7576119a6612e69565b5b8160048111156119ba576119b9612e69565b5b14156119fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119f2906129c1565b60405180910390fd5b5b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c1115611a3a576000600391509150611ad9565b600060018787878760405160008152602001604052604051611a5f949392919061289a565b6020604051602081039080840390855afa158015611a81573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611ad057600060019250925050611ad9565b80600092509250505b94509492505050565b828054611aee90612d27565b90600052602060002090601f016020900481019282611b105760008555611b57565b82601f10611b2957803560ff1916838001178555611b57565b82800160010185558215611b57579182015b82811115611b56578235825591602001919060010190611b3b565b5b509050611b649190611b68565b5090565b5b80821115611b81576000816000905550600101611b69565b5090565b6000611b98611b9384612aea565b612ac5565b90508083825260208201905082856020860282011115611bbb57611bba612f51565b5b60005b85811015611beb5781611bd18882611ca7565b845260208401935060208301925050600181019050611bbe565b5050509392505050565b6000611c08611c0384612b16565b612ac5565b90508083825260208201905082856020860282011115611c2b57611c2a612f51565b5b60005b85811015611c5b5781611c418882611e31565b845260208401935060208301925050600181019050611c2e565b5050509392505050565b6000611c78611c7384612b42565b612ac5565b905082815260208101848484011115611c9457611c93612f56565b5b611c9f848285612ce5565b509392505050565b600081359050611cb681613391565b92915050565b60008083601f840112611cd257611cd1612f4c565b5b8235905067ffffffffffffffff811115611cef57611cee612f47565b5b602083019150836020820283011115611d0b57611d0a612f51565b5b9250929050565b600082601f830112611d2757611d26612f4c565b5b8135611d37848260208601611b85565b91505092915050565b600082601f830112611d5557611d54612f4c565b5b8135611d65848260208601611bf5565b91505092915050565b600081359050611d7d816133a8565b92915050565b600081359050611d92816133bf565b92915050565b600081519050611da7816133bf565b92915050565b600082601f830112611dc257611dc1612f4c565b5b8135611dd2848260208601611c65565b91505092915050565b60008083601f840112611df157611df0612f4c565b5b8235905067ffffffffffffffff811115611e0e57611e0d612f47565b5b602083019150836001820283011115611e2a57611e29612f51565b5b9250929050565b600081359050611e40816133d6565b92915050565b600060208284031215611e5c57611e5b612f60565b5b6000611e6a84828501611ca7565b91505092915050565b60008060408385031215611e8a57611e89612f60565b5b6000611e9885828601611ca7565b9250506020611ea985828601611ca7565b9150509250929050565b600080600080600060a08688031215611ecf57611ece612f60565b5b6000611edd88828901611ca7565b9550506020611eee88828901611ca7565b945050604086013567ffffffffffffffff811115611f0f57611f0e612f5b565b5b611f1b88828901611d40565b935050606086013567ffffffffffffffff811115611f3c57611f3b612f5b565b5b611f4888828901611d40565b925050608086013567ffffffffffffffff811115611f6957611f68612f5b565b5b611f7588828901611dad565b9150509295509295909350565b600080600080600060a08688031215611f9e57611f9d612f60565b5b6000611fac88828901611ca7565b9550506020611fbd88828901611ca7565b9450506040611fce88828901611e31565b9350506060611fdf88828901611e31565b925050608086013567ffffffffffffffff81111561200057611fff612f5b565b5b61200c88828901611dad565b9150509295509295909350565b600080604083850312156120305761202f612f60565b5b600061203e85828601611ca7565b925050602061204f85828601611d6e565b9150509250929050565b600080604083850312156120705761206f612f60565b5b600061207e85828601611ca7565b925050602061208f85828601611e31565b9150509250929050565b600080600080608085870312156120b3576120b2612f60565b5b60006120c187828801611ca7565b94505060206120d287828801611e31565b93505060406120e387828801611e31565b925050606085013567ffffffffffffffff81111561210457612103612f5b565b5b61211087828801611dad565b91505092959194509250565b6000806040838503121561213357612132612f60565b5b600083013567ffffffffffffffff81111561215157612150612f5b565b5b61215d85828601611d12565b925050602083013567ffffffffffffffff81111561217e5761217d612f5b565b5b61218a85828601611d40565b9150509250929050565b6000602082840312156121aa576121a9612f60565b5b60006121b884828501611d83565b91505092915050565b6000602082840312156121d7576121d6612f60565b5b60006121e584828501611d98565b91505092915050565b6000806020838503121561220557612204612f60565b5b600083013567ffffffffffffffff81111561222357612222612f5b565b5b61222f85828601611ddb565b92509250509250929050565b6000806000806040858703121561225557612254612f60565b5b600085013567ffffffffffffffff81111561227357612272612f5b565b5b61227f87828801611ddb565b9450945050602085013567ffffffffffffffff8111156122a2576122a1612f5b565b5b6122ae87828801611ddb565b925092505092959194509250565b6000602082840312156122d2576122d1612f60565b5b60006122e084828501611e31565b91505092915050565b60008060006040848603121561230257612301612f60565b5b600061231086828701611e31565b935050602084013567ffffffffffffffff81111561233157612330612f5b565b5b61233d86828701611cbc565b92509250509250925092565b60006123558383612703565b60208301905092915050565b61236a81612c5a565b82525050565b61238161237c82612c5a565b612dd3565b82525050565b600061239282612b98565b61239c8185612bc6565b93506123a783612b73565b8060005b838110156123d85781516123bf8882612349565b97506123ca83612bb9565b9250506001810190506123ab565b5085935050505092915050565b6123ee81612c6c565b82525050565b6123fd81612c78565b82525050565b61241461240f82612c78565b612de5565b82525050565b600061242582612ba3565b61242f8185612bd7565b935061243f818560208601612cf4565b61244881612f65565b840191505092915050565b600061245e82612bae565b6124688185612be8565b9350612478818560208601612cf4565b61248181612f65565b840191505092915050565b600061249782612bae565b6124a18185612bf9565b93506124b1818560208601612cf4565b80840191505092915050565b600081546124ca81612d27565b6124d48186612bf9565b945060018216600081146124ef576001811461250057612533565b60ff19831686528186019350612533565b61250985612b83565b60005b8381101561252b5781548189015260018201915060208101905061250c565b838801955050505b50505092915050565b6000612549601883612be8565b915061255482612f90565b602082019050919050565b600061256c602883612be8565b915061257782612fb9565b604082019050919050565b600061258f601f83612be8565b915061259a82613008565b602082019050919050565b60006125b2601c83612bf9565b91506125bd82613031565b601c82019050919050565b60006125d5602683612be8565b91506125e08261305a565b604082019050919050565b60006125f8602483612be8565b9150612603826130a9565b604082019050919050565b600061261b602a83612be8565b9150612626826130f8565b604082019050919050565b600061263e602283612be8565b915061264982613147565b604082019050919050565b6000612661602383612be8565b915061266c82613196565b604082019050919050565b6000612684602083612be8565b915061268f826131e5565b602082019050919050565b60006126a7602983612be8565b91506126b28261320e565b604082019050919050565b60006126ca602183612be8565b91506126d58261325d565b604082019050919050565b60006126ed603483612be8565b91506126f8826132ac565b604082019050919050565b61270c81612cce565b82525050565b61271b81612cce565b82525050565b61273261272d82612cce565b612e01565b82525050565b61274181612cd8565b82525050565b60006127538287612370565b60148201915061276382866124bd565b915061276f8285612721565b60208201915061277f8284612721565b60208201915081905095945050505050565b600061279d82866124bd565b91506127a9828561248c565b91506127b582846124bd565b9150819050949350505050565b60006127cd826125a5565b91506127d98284612403565b60208201915081905092915050565b60006020820190506127fd6000830184612361565b92915050565b600060a0820190506128186000830188612361565b6128256020830187612361565b6128326040830186612712565b61283f6060830185612712565b8181036080830152612851818461241a565b90509695505050505050565b600060208201905081810360008301526128778184612387565b905092915050565b600060208201905061289460008301846123e5565b92915050565b60006080820190506128af60008301876123f4565b6128bc6020830186612738565b6128c960408301856123f4565b6128d660608301846123f4565b95945050505050565b600060208201905081810360008301526128f98184612453565b905092915050565b6000602082019050818103600083015261291a8161253c565b9050919050565b6000602082019050818103600083015261293a8161255f565b9050919050565b6000602082019050818103600083015261295a81612582565b9050919050565b6000602082019050818103600083015261297a816125c8565b9050919050565b6000602082019050818103600083015261299a816125eb565b9050919050565b600060208201905081810360008301526129ba8161260e565b9050919050565b600060208201905081810360008301526129da81612631565b9050919050565b600060208201905081810360008301526129fa81612654565b9050919050565b60006020820190508181036000830152612a1a81612677565b9050919050565b60006020820190508181036000830152612a3a8161269a565b9050919050565b60006020820190508181036000830152612a5a816126bd565b9050919050565b60006020820190508181036000830152612a7a816126e0565b9050919050565b6000602082019050612a966000830184612712565b92915050565b6000604082019050612ab16000830185612712565b612abe6020830184612712565b9392505050565b6000612acf612ae0565b9050612adb8282612d59565b919050565b6000604051905090565b600067ffffffffffffffff821115612b0557612b04612ef6565b5b602082029050602081019050919050565b600067ffffffffffffffff821115612b3157612b30612ef6565b5b602082029050602081019050919050565b600067ffffffffffffffff821115612b5d57612b5c612ef6565b5b612b6682612f65565b9050602081019050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6000612c0f82612cce565b9150612c1a83612cce565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612c4f57612c4e612e0b565b5b828201905092915050565b6000612c6582612cae565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b82818337600083830152505050565b60005b83811015612d12578082015181840152602081019050612cf7565b83811115612d21576000848401525b50505050565b60006002820490506001821680612d3f57607f821691505b60208210811415612d5357612d52612e98565b5b50919050565b612d6282612f65565b810181811067ffffffffffffffff82111715612d8157612d80612ef6565b5b80604052505050565b6000612d9582612cce565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612dc857612dc7612e0b565b5b600182019050919050565b6000612dde82612def565b9050919050565b6000819050919050565b6000612dfa82612f76565b9050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060033d1115612f445760046000803e612f41600051612f83565b90505b90565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b60008160601b9050919050565b60008160e01c9050919050565b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b7f455243313135353a204552433131353552656365697665722072656a6563746560008201527f6420746f6b656e73000000000000000000000000000000000000000000000000602082015250565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a206275726e20616d6f756e7420657863656564732062616c60008201527f616e636500000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a2061646472657373207a65726f206973206e6f742061207660008201527f616c6964206f776e657200000000000000000000000000000000000000000000602082015250565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a206275726e2066726f6d20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f455243313135353a206163636f756e747320616e6420696473206c656e67746860008201527f206d69736d617463680000000000000000000000000000000000000000000000602082015250565b7f455243313135353a206d696e7420746f20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a207472616e7366657220746f206e6f6e2d4552433131353560008201527f526563656976657220696d706c656d656e746572000000000000000000000000602082015250565b600060443d101561330b5761338e565b613313612ae0565b60043d036004823e80513d602482011167ffffffffffffffff8211171561333b57505061338e565b808201805167ffffffffffffffff811115613359575050505061338e565b80602083010160043d03850181111561337657505050505061338e565b61338582602001850186612d59565b82955050505050505b90565b61339a81612c5a565b81146133a557600080fd5b50565b6133b181612c6c565b81146133bc57600080fd5b50565b6133c881612c82565b81146133d357600080fd5b50565b6133df81612cce565b81146133ea57600080fd5b5056fea264697066735822122048d5c2e359666ac844ce5bb7b73d54e8ede0c1956dc91ba3ca7012f250bddb2864736f6c634300080700330000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b506004361061014c5760003560e01c80638da5cb5b116100c3578063bf2db4c81161007c578063bf2db4c81461034f578063c72d086b1461036b578063e985e9c514610387578063f242432a146103b7578063f2fde38b146103d3578063fbfa13aa146103ef5761014c565b80638da5cb5b146102a15780638e3a7249146102bf57806395d89b41146102db578063a22cb465146102f9578063ab5e124a14610315578063b8896d35146103335761014c565b80633f4ba83a116101155780633f4ba83a1461021b57806348386759146102255780634e1273f414610241578063715018a6146102715780638280a2711461027b5780638456cb59146102975761014c565b8062fdd58e1461015157806301ffc9a71461018157806306fdde03146101b15780630e89341c146101cf5780632eb2c2d6146101ff575b600080fd5b61016b60048036038101906101669190612059565b61040b565b6040516101789190612a81565b60405180910390f35b61019b60048036038101906101969190612194565b6104d4565b6040516101a8919061287f565b60405180910390f35b6101b96105b6565b6040516101c691906128df565b60405180910390f35b6101e960048036038101906101e491906122bc565b610648565b6040516101f691906128df565b60405180910390f35b61021960048036038101906102149190611eb3565b61067f565b005b6102236106b1565b005b61023f600480360381019061023a9190612059565b6106d6565b005b61025b6004803603810190610256919061211c565b6106ee565b604051610268919061285d565b60405180910390f35b610279610807565b005b610295600480360381019061029091906122e9565b61081b565b005b61029f61088d565b005b6102a96108b2565b6040516102b691906127e8565b60405180910390f35b6102d960048036038101906102d491906121ee565b6108dc565b005b6102e36108fa565b6040516102f091906128df565b60405180910390f35b610313600480360381019061030e9190612019565b61098c565b005b61031d6109be565b60405161032a919061287f565b60405180910390f35b61034d60048036038101906103489190612099565b6109d1565b005b6103696004803603810190610364919061223b565b610b00565b005b610385600480360381019061038091906122bc565b610b32565b005b6103a1600480360381019061039c9190611e73565b610b41565b6040516103ae919061287f565b60405180910390f35b6103d160048036038101906103cc9190611f82565b610bd5565b005b6103ed60048036038101906103e89190611e46565b610c07565b005b61040960048036038101906104049190611e46565b610c8b565b005b60008073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff16141561047c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610473906129a1565b60405180910390fd5b60008083815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905092915050565b60007fd9b67a26000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916148061059f57507f0e89341c000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b806105af57506105ae82610cd7565b5b9050919050565b6060600a80546105c590612d27565b80601f01602080910402602001604051908101604052809291908181526020018280546105f190612d27565b801561063e5780601f106106135761010080835404028352916020019161063e565b820191906000526020600020905b81548152906001019060200180831161062157829003601f168201915b5050505050905090565b6060600861065583610d41565b600960405160200161066993929190612791565b6040516020818303038152906040529050919050565b6040517fd37a223a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6106b9610e19565b6000600760006101000a81548160ff021916908315150217905550565b6106de610e19565b6106ea82826001610e97565b5050565b60608151835114610734576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161072b90612a21565b60405180910390fd5b6000835167ffffffffffffffff81111561075157610750612ef6565b5b60405190808252806020026020018201604052801561077f5781602001602082028036833780820191505090505b50905060005b84518110156107fc576107cc8582815181106107a4576107a3612ec7565b5b60200260200101518583815181106107bf576107be612ec7565b5b602002602001015161040b565b8282815181106107df576107de612ec7565b5b602002602001018181525050806107f590612d8a565b9050610785565b508091505092915050565b61080f610e19565b61081960006110de565b565b610823610e19565b60005b828290508110156108875761087483838381811061084757610846612ec7565b5b905060200201602081019061085c9190611e46565b856001604051806020016040528060008152506111a4565b808061087f90612d8a565b915050610826565b50505050565b610895610e19565b6001600760006101000a81548160ff021916908315150217905550565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6108e4610e19565b8181600491906108f5929190611ae2565b505050565b6060600b805461090990612d27565b80601f016020809104026020016040519081016040528092919081815260200182805461093590612d27565b80156109825780601f1061095757610100808354040283529160200191610982565b820191906000526020600020905b81548152906001019060200180831161096557829003601f168201915b5050505050905090565b6040517fd37a223a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b600760009054906101000a900460ff1681565b600760009054906101000a900460ff1615610a18576040517f6b68780600000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610a2484848484611355565b610a5a576040517f401b4d9700000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b6006600083815260200190815260200160002060009054906101000a900460ff1615610ab2576040517f900bb2c900000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b60016006600084815260200190815260200160002060006101000a81548160ff021916908315150217905550610afa84846001604051806020016040528060008152506111a4565b50505050565b610b08610e19565b838360089190610b19929190611ae2565b50818160099190610b2b929190611ae2565b5050505050565b610b3e33826001610e97565b50565b6000600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6040517fd37a223a00000000000000000000000000000000000000000000000000000000815260040160405180910390fd5b610c0f610e19565b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415610c7f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c7690612961565b60405180910390fd5b610c88816110de565b50565b610c93610e19565b80600560006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b606060006001610d50846113f9565b01905060008167ffffffffffffffff811115610d6f57610d6e612ef6565b5b6040519080825280601f01601f191660200182016040528015610da15781602001600182028036833780820191505090505b509050600082602001820190505b600115610e0e578080600190039150507f3031323334353637383961626364656600000000000000000000000000000000600a86061a8153600a8581610df857610df7612e3a565b5b0494506000851415610e0957610e0e565b610daf565b819350505050919050565b610e2161154c565b73ffffffffffffffffffffffffffffffffffffffff16610e3f6108b2565b73ffffffffffffffffffffffffffffffffffffffff1614610e95576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e8c90612a01565b60405180910390fd5b565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610f07576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610efe906129e1565b60405180910390fd5b6000610f1161154c565b90506000610f1e84611554565b90506000610f2b84611554565b9050610f4b838760008585604051806020016040528060008152506115ce565b600080600087815260200190815260200160002060008873ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002054905084811015610fe2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610fd990612981565b60405180910390fd5b84810360008088815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002081905550600073ffffffffffffffffffffffffffffffffffffffff168773ffffffffffffffffffffffffffffffffffffffff168573ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f6289896040516110af929190612a9c565b60405180910390a46110d5848860008686604051806020016040528060008152506115d6565b50505050505050565b6000600360009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600360006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161415611214576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161120b90612a41565b60405180910390fd5b600061121e61154c565b9050600061122b85611554565b9050600061123885611554565b9050611249836000898585896115ce565b8460008088815260200190815260200160002060008973ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546112a89190612c04565b925050819055508673ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fc3d58168c5ae7397731d063d5bbf3d657854427343f4c083240f7aacaa2d0f628989604051611326929190612a9c565b60405180910390a461133d836000898585896115d6565b61134c836000898989896115de565b50505050505050565b6000600560009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff166113d8836113ca88600489896040516020016113af9493929190612747565b604051602081830303815290604052805190602001206117c5565b6117f590919063ffffffff16565b73ffffffffffffffffffffffffffffffffffffffff16149050949350505050565b600080600090507a184f03e93ff9f4daa797ed6e38ed64bf6a1f0100000000000000008310611457577a184f03e93ff9f4daa797ed6e38ed64bf6a1f010000000000000000838161144d5761144c612e3a565b5b0492506040810190505b6d04ee2d6d415b85acef81000000008310611494576d04ee2d6d415b85acef8100000000838161148a57611489612e3a565b5b0492506020810190505b662386f26fc1000083106114c357662386f26fc1000083816114b9576114b8612e3a565b5b0492506010810190505b6305f5e10083106114ec576305f5e10083816114e2576114e1612e3a565b5b0492506008810190505b612710831061151157612710838161150757611506612e3a565b5b0492506004810190505b60648310611534576064838161152a57611529612e3a565b5b0492506002810190505b600a8310611543576001810190505b80915050919050565b600033905090565b60606000600167ffffffffffffffff81111561157357611572612ef6565b5b6040519080825280602002602001820160405280156115a15781602001602082028036833780820191505090505b50905082816000815181106115b9576115b8612ec7565b5b60200260200101818152505080915050919050565b505050505050565b505050505050565b6115fd8473ffffffffffffffffffffffffffffffffffffffff1661181c565b156117bd578373ffffffffffffffffffffffffffffffffffffffff1663f23a6e6187878686866040518663ffffffff1660e01b8152600401611643959493929190612803565b602060405180830381600087803b15801561165d57600080fd5b505af192505050801561168e57506040513d601f19601f8201168201806040525081019061168b91906121c1565b60015b6117345761169a612f25565b806308c379a014156116f757506116af6132fb565b806116ba57506116f9565b806040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116ee91906128df565b60405180910390fd5b505b6040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161172b90612a61565b60405180910390fd5b63f23a6e6160e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916146117bb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117b290612921565b60405180910390fd5b505b505050505050565b6000816040516020016117d891906127c2565b604051602081830303815290604052805190602001209050919050565b6000806000611804858561183f565b9150915061181181611891565b819250505092915050565b6000808273ffffffffffffffffffffffffffffffffffffffff163b119050919050565b6000806041835114156118815760008060006020860151925060408601519150606086015160001a9050611875878285856119ff565b9450945050505061188a565b60006002915091505b9250929050565b600060048111156118a5576118a4612e69565b5b8160048111156118b8576118b7612e69565b5b14156118c3576119fc565b600160048111156118d7576118d6612e69565b5b8160048111156118ea576118e9612e69565b5b141561192b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161192290612901565b60405180910390fd5b6002600481111561193f5761193e612e69565b5b81600481111561195257611951612e69565b5b1415611993576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161198a90612941565b60405180910390fd5b600360048111156119a7576119a6612e69565b5b8160048111156119ba576119b9612e69565b5b14156119fb576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119f2906129c1565b60405180910390fd5b5b50565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08360001c1115611a3a576000600391509150611ad9565b600060018787878760405160008152602001604052604051611a5f949392919061289a565b6020604051602081039080840390855afa158015611a81573d6000803e3d6000fd5b505050602060405103519050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611ad057600060019250925050611ad9565b80600092509250505b94509492505050565b828054611aee90612d27565b90600052602060002090601f016020900481019282611b105760008555611b57565b82601f10611b2957803560ff1916838001178555611b57565b82800160010185558215611b57579182015b82811115611b56578235825591602001919060010190611b3b565b5b509050611b649190611b68565b5090565b5b80821115611b81576000816000905550600101611b69565b5090565b6000611b98611b9384612aea565b612ac5565b90508083825260208201905082856020860282011115611bbb57611bba612f51565b5b60005b85811015611beb5781611bd18882611ca7565b845260208401935060208301925050600181019050611bbe565b5050509392505050565b6000611c08611c0384612b16565b612ac5565b90508083825260208201905082856020860282011115611c2b57611c2a612f51565b5b60005b85811015611c5b5781611c418882611e31565b845260208401935060208301925050600181019050611c2e565b5050509392505050565b6000611c78611c7384612b42565b612ac5565b905082815260208101848484011115611c9457611c93612f56565b5b611c9f848285612ce5565b509392505050565b600081359050611cb681613391565b92915050565b60008083601f840112611cd257611cd1612f4c565b5b8235905067ffffffffffffffff811115611cef57611cee612f47565b5b602083019150836020820283011115611d0b57611d0a612f51565b5b9250929050565b600082601f830112611d2757611d26612f4c565b5b8135611d37848260208601611b85565b91505092915050565b600082601f830112611d5557611d54612f4c565b5b8135611d65848260208601611bf5565b91505092915050565b600081359050611d7d816133a8565b92915050565b600081359050611d92816133bf565b92915050565b600081519050611da7816133bf565b92915050565b600082601f830112611dc257611dc1612f4c565b5b8135611dd2848260208601611c65565b91505092915050565b60008083601f840112611df157611df0612f4c565b5b8235905067ffffffffffffffff811115611e0e57611e0d612f47565b5b602083019150836001820283011115611e2a57611e29612f51565b5b9250929050565b600081359050611e40816133d6565b92915050565b600060208284031215611e5c57611e5b612f60565b5b6000611e6a84828501611ca7565b91505092915050565b60008060408385031215611e8a57611e89612f60565b5b6000611e9885828601611ca7565b9250506020611ea985828601611ca7565b9150509250929050565b600080600080600060a08688031215611ecf57611ece612f60565b5b6000611edd88828901611ca7565b9550506020611eee88828901611ca7565b945050604086013567ffffffffffffffff811115611f0f57611f0e612f5b565b5b611f1b88828901611d40565b935050606086013567ffffffffffffffff811115611f3c57611f3b612f5b565b5b611f4888828901611d40565b925050608086013567ffffffffffffffff811115611f6957611f68612f5b565b5b611f7588828901611dad565b9150509295509295909350565b600080600080600060a08688031215611f9e57611f9d612f60565b5b6000611fac88828901611ca7565b9550506020611fbd88828901611ca7565b9450506040611fce88828901611e31565b9350506060611fdf88828901611e31565b925050608086013567ffffffffffffffff81111561200057611fff612f5b565b5b61200c88828901611dad565b9150509295509295909350565b600080604083850312156120305761202f612f60565b5b600061203e85828601611ca7565b925050602061204f85828601611d6e565b9150509250929050565b600080604083850312156120705761206f612f60565b5b600061207e85828601611ca7565b925050602061208f85828601611e31565b9150509250929050565b600080600080608085870312156120b3576120b2612f60565b5b60006120c187828801611ca7565b94505060206120d287828801611e31565b93505060406120e387828801611e31565b925050606085013567ffffffffffffffff81111561210457612103612f5b565b5b61211087828801611dad565b91505092959194509250565b6000806040838503121561213357612132612f60565b5b600083013567ffffffffffffffff81111561215157612150612f5b565b5b61215d85828601611d12565b925050602083013567ffffffffffffffff81111561217e5761217d612f5b565b5b61218a85828601611d40565b9150509250929050565b6000602082840312156121aa576121a9612f60565b5b60006121b884828501611d83565b91505092915050565b6000602082840312156121d7576121d6612f60565b5b60006121e584828501611d98565b91505092915050565b6000806020838503121561220557612204612f60565b5b600083013567ffffffffffffffff81111561222357612222612f5b565b5b61222f85828601611ddb565b92509250509250929050565b6000806000806040858703121561225557612254612f60565b5b600085013567ffffffffffffffff81111561227357612272612f5b565b5b61227f87828801611ddb565b9450945050602085013567ffffffffffffffff8111156122a2576122a1612f5b565b5b6122ae87828801611ddb565b925092505092959194509250565b6000602082840312156122d2576122d1612f60565b5b60006122e084828501611e31565b91505092915050565b60008060006040848603121561230257612301612f60565b5b600061231086828701611e31565b935050602084013567ffffffffffffffff81111561233157612330612f5b565b5b61233d86828701611cbc565b92509250509250925092565b60006123558383612703565b60208301905092915050565b61236a81612c5a565b82525050565b61238161237c82612c5a565b612dd3565b82525050565b600061239282612b98565b61239c8185612bc6565b93506123a783612b73565b8060005b838110156123d85781516123bf8882612349565b97506123ca83612bb9565b9250506001810190506123ab565b5085935050505092915050565b6123ee81612c6c565b82525050565b6123fd81612c78565b82525050565b61241461240f82612c78565b612de5565b82525050565b600061242582612ba3565b61242f8185612bd7565b935061243f818560208601612cf4565b61244881612f65565b840191505092915050565b600061245e82612bae565b6124688185612be8565b9350612478818560208601612cf4565b61248181612f65565b840191505092915050565b600061249782612bae565b6124a18185612bf9565b93506124b1818560208601612cf4565b80840191505092915050565b600081546124ca81612d27565b6124d48186612bf9565b945060018216600081146124ef576001811461250057612533565b60ff19831686528186019350612533565b61250985612b83565b60005b8381101561252b5781548189015260018201915060208101905061250c565b838801955050505b50505092915050565b6000612549601883612be8565b915061255482612f90565b602082019050919050565b600061256c602883612be8565b915061257782612fb9565b604082019050919050565b600061258f601f83612be8565b915061259a82613008565b602082019050919050565b60006125b2601c83612bf9565b91506125bd82613031565b601c82019050919050565b60006125d5602683612be8565b91506125e08261305a565b604082019050919050565b60006125f8602483612be8565b9150612603826130a9565b604082019050919050565b600061261b602a83612be8565b9150612626826130f8565b604082019050919050565b600061263e602283612be8565b915061264982613147565b604082019050919050565b6000612661602383612be8565b915061266c82613196565b604082019050919050565b6000612684602083612be8565b915061268f826131e5565b602082019050919050565b60006126a7602983612be8565b91506126b28261320e565b604082019050919050565b60006126ca602183612be8565b91506126d58261325d565b604082019050919050565b60006126ed603483612be8565b91506126f8826132ac565b604082019050919050565b61270c81612cce565b82525050565b61271b81612cce565b82525050565b61273261272d82612cce565b612e01565b82525050565b61274181612cd8565b82525050565b60006127538287612370565b60148201915061276382866124bd565b915061276f8285612721565b60208201915061277f8284612721565b60208201915081905095945050505050565b600061279d82866124bd565b91506127a9828561248c565b91506127b582846124bd565b9150819050949350505050565b60006127cd826125a5565b91506127d98284612403565b60208201915081905092915050565b60006020820190506127fd6000830184612361565b92915050565b600060a0820190506128186000830188612361565b6128256020830187612361565b6128326040830186612712565b61283f6060830185612712565b8181036080830152612851818461241a565b90509695505050505050565b600060208201905081810360008301526128778184612387565b905092915050565b600060208201905061289460008301846123e5565b92915050565b60006080820190506128af60008301876123f4565b6128bc6020830186612738565b6128c960408301856123f4565b6128d660608301846123f4565b95945050505050565b600060208201905081810360008301526128f98184612453565b905092915050565b6000602082019050818103600083015261291a8161253c565b9050919050565b6000602082019050818103600083015261293a8161255f565b9050919050565b6000602082019050818103600083015261295a81612582565b9050919050565b6000602082019050818103600083015261297a816125c8565b9050919050565b6000602082019050818103600083015261299a816125eb565b9050919050565b600060208201905081810360008301526129ba8161260e565b9050919050565b600060208201905081810360008301526129da81612631565b9050919050565b600060208201905081810360008301526129fa81612654565b9050919050565b60006020820190508181036000830152612a1a81612677565b9050919050565b60006020820190508181036000830152612a3a8161269a565b9050919050565b60006020820190508181036000830152612a5a816126bd565b9050919050565b60006020820190508181036000830152612a7a816126e0565b9050919050565b6000602082019050612a966000830184612712565b92915050565b6000604082019050612ab16000830185612712565b612abe6020830184612712565b9392505050565b6000612acf612ae0565b9050612adb8282612d59565b919050565b6000604051905090565b600067ffffffffffffffff821115612b0557612b04612ef6565b5b602082029050602081019050919050565b600067ffffffffffffffff821115612b3157612b30612ef6565b5b602082029050602081019050919050565b600067ffffffffffffffff821115612b5d57612b5c612ef6565b5b612b6682612f65565b9050602081019050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6000612c0f82612cce565b9150612c1a83612cce565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115612c4f57612c4e612e0b565b5b828201905092915050565b6000612c6582612cae565b9050919050565b60008115159050919050565b6000819050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600060ff82169050919050565b82818337600083830152505050565b60005b83811015612d12578082015181840152602081019050612cf7565b83811115612d21576000848401525b50505050565b60006002820490506001821680612d3f57607f821691505b60208210811415612d5357612d52612e98565b5b50919050565b612d6282612f65565b810181811067ffffffffffffffff82111715612d8157612d80612ef6565b5b80604052505050565b6000612d9582612cce565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415612dc857612dc7612e0b565b5b600182019050919050565b6000612dde82612def565b9050919050565b6000819050919050565b6000612dfa82612f76565b9050919050565b6000819050919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b600060033d1115612f445760046000803e612f41600051612f83565b90505b90565b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b600080fd5b6000601f19601f8301169050919050565b60008160601b9050919050565b60008160e01c9050919050565b7f45434453413a20696e76616c6964207369676e61747572650000000000000000600082015250565b7f455243313135353a204552433131353552656365697665722072656a6563746560008201527f6420746f6b656e73000000000000000000000000000000000000000000000000602082015250565b7f45434453413a20696e76616c6964207369676e6174757265206c656e67746800600082015250565b7f19457468657265756d205369676e6564204d6573736167653a0a333200000000600082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a206275726e20616d6f756e7420657863656564732062616c60008201527f616e636500000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a2061646472657373207a65726f206973206e6f742061207660008201527f616c6964206f776e657200000000000000000000000000000000000000000000602082015250565b7f45434453413a20696e76616c6964207369676e6174757265202773272076616c60008201527f7565000000000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a206275726e2066726f6d20746865207a65726f206164647260008201527f6573730000000000000000000000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f455243313135353a206163636f756e747320616e6420696473206c656e67746860008201527f206d69736d617463680000000000000000000000000000000000000000000000602082015250565b7f455243313135353a206d696e7420746f20746865207a65726f2061646472657360008201527f7300000000000000000000000000000000000000000000000000000000000000602082015250565b7f455243313135353a207472616e7366657220746f206e6f6e2d4552433131353560008201527f526563656976657220696d706c656d656e746572000000000000000000000000602082015250565b600060443d101561330b5761338e565b613313612ae0565b60043d036004823e80513d602482011167ffffffffffffffff8211171561333b57505061338e565b808201805167ffffffffffffffff811115613359575050505061338e565b80602083010160043d03850181111561337657505050505061338e565b61338582602001850186612d59565b82955050505050505b90565b61339a81612c5a565b81146133a557600080fd5b50565b6133b181612c6c565b81146133bc57600080fd5b50565b6133c881612c82565b81146133d357600080fd5b50565b6133df81612cce565b81146133ea57600080fd5b5056fea264697066735822122048d5c2e359666ac844ce5bb7b73d54e8ede0c1956dc91ba3ca7012f250bddb2864736f6c63430008070033

Constructor Arguments (ABI-Encoded and is the last bytes of the Contract Creation Code above)

0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000000000000000000000000000000000000006000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _base (string):
Arg [1] : _suffix (string):

-----Encoded View---------------
4 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000060
Arg [2] : 0000000000000000000000000000000000000000000000000000000000000000
Arg [3] : 0000000000000000000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

66418:2984:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;45790:230;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44813:310;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67857:91;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68059:159;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;69179:220;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;68466:76;;;:::i;:::-;;67731:114;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;46186:524;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;63198:103;;;:::i;:::-;;66947:225;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;68385:73;;;:::i;:::-;;62550:87;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;64897:122;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67956:95;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68830:136;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;66550:30;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;67180:444;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;68226:151;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;67632:91;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;47010:168;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;68974:197;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;63456:201;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;65350:118;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;45790:230;45876:7;45923:1;45904:21;;:7;:21;;;;45896:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;45990:9;:13;46000:2;45990:13;;;;;;;;;;;:22;46004:7;45990:22;;;;;;;;;;;;;;;;45983:29;;45790:230;;;;:::o;44813:310::-;44915:4;44967:26;44952:41;;;:11;:41;;;;:110;;;;45025:37;45010:52;;;:11;:52;;;;44952:110;:163;;;;45079:36;45103:11;45079:23;:36::i;:::-;44952:163;44932:183;;44813:310;;;:::o;67857:91::-;67902:13;67935:5;67928:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67857:91;:::o;68059:159::-;68114:13;68171:7;68180:13;:2;:11;:13::i;:::-;68195;68154:55;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;68140:70;;68059:159;;;:::o;69179:220::-;69369:22;;;;;;;;;;;;;;68466:76;62436:13;:11;:13::i;:::-;68529:5:::1;68515:11;;:19;;;;;;;;;;;;;;;;;;68466:76::o:0;67731:114::-;62436:13;:11;:13::i;:::-;67817:20:::1;67823:6;67831:2;67835:1;67817:5;:20::i;:::-;67731:114:::0;;:::o;46186:524::-;46342:16;46403:3;:10;46384:8;:15;:29;46376:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;46472:30;46519:8;:15;46505:30;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;46472:63;;46553:9;46548:122;46572:8;:15;46568:1;:19;46548:122;;;46628:30;46638:8;46647:1;46638:11;;;;;;;;:::i;:::-;;;;;;;;46651:3;46655:1;46651:6;;;;;;;;:::i;:::-;;;;;;;;46628:9;:30::i;:::-;46609:13;46623:1;46609:16;;;;;;;;:::i;:::-;;;;;;;:49;;;;;46589:3;;;;:::i;:::-;;;46548:122;;;;46689:13;46682:20;;;46186:524;;;;:::o;63198:103::-;62436:13;:11;:13::i;:::-;63263:30:::1;63290:1;63263:18;:30::i;:::-;63198:103::o:0;66947:225::-;62436:13;:11;:13::i;:::-;67074:6:::1;67070:95;67090:7;;:14;;67086:1;:18;67070:95;;;67125:28;67131:7;;67139:1;67131:10;;;;;;;:::i;:::-;;;;;;;;;;;;;;;:::i;:::-;67143:2;67147:1;67125:28;;;;;;;;;;;::::0;:5:::1;:28::i;:::-;67106:3;;;;;:::i;:::-;;;;67070:95;;;;66947:225:::0;;;:::o;68385:73::-;62436:13;:11;:13::i;:::-;68446:4:::1;68432:11;;:18;;;;;;;;;;;;;;;;;;68385:73::o:0;62550:87::-;62596:7;62623:6;;;;;;;;;;;62616:13;;62550:87;:::o;64897:122::-;62436:13;:11;:13::i;:::-;64999:12:::1;;64984;:27;;;;;;;:::i;:::-;;64897:122:::0;;:::o;67956:95::-;68003:13;68036:7;68029:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67956:95;:::o;68830:136::-;68936:22;;;;;;;;;;;;;;66550:30;;;;;;;;;;;;;:::o;67180:444::-;67354:11;;;;;;;;;;;67351:37;;;67374:14;;;;;;;;;;;;;;67351:37;67403:45;67411:14;67427:2;67431:5;67438:9;67403:7;:45::i;:::-;67399:77;;67457:19;;;;;;;;;;;;;;67399:77;67490:9;:16;67500:5;67490:16;;;;;;;;;;;;;;;;;;;;;67487:50;;;67515:22;;;;;;;;;;;;;;67487:50;67569:4;67550:9;:16;67560:5;67550:16;;;;;;;;;;;;:23;;;;;;;;;;;;;;;;;;67584:32;67590:14;67606:2;67610:1;67584:32;;;;;;;;;;;;:5;:32::i;:::-;67180:444;;;;:::o;68226:151::-;62436:13;:11;:13::i;:::-;68330:5:::1;;68320:7;:15;;;;;;;:::i;:::-;;68362:7;;68346:13;:23;;;;;;;:::i;:::-;;68226:151:::0;;;;:::o;67632:91::-;67691:24;67697:10;67709:2;67713:1;67691:5;:24::i;:::-;67632:91;:::o;47010:168::-;47109:4;47133:18;:27;47152:7;47133:27;;;;;;;;;;;;;;;:37;47161:8;47133:37;;;;;;;;;;;;;;;;;;;;;;;;;47126:44;;47010:168;;;;:::o;68974:197::-;69141:22;;;;;;;;;;;;;;63456:201;62436:13;:11;:13::i;:::-;63565:1:::1;63545:22;;:8;:22;;;;63537:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;63621:28;63640:8;63621:18;:28::i;:::-;63456:201:::0;:::o;65350:118::-;62436:13;:11;:13::i;:::-;65447::::1;65431;;:29;;;;;;;;;;;;;;;;;;65350:118:::0;:::o;11241:157::-;11326:4;11365:25;11350:40;;;:11;:40;;;;11343:47;;11241:157;;;:::o;32173:716::-;32229:13;32280:14;32317:1;32297:17;32308:5;32297:10;:17::i;:::-;:21;32280:38;;32333:20;32367:6;32356:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32333:41;;32389:11;32518:6;32514:2;32510:15;32502:6;32498:28;32491:35;;32555:288;32562:4;32555:288;;;32587:5;;;;;;;;32729:8;32724:2;32717:5;32713:14;32708:30;32703:3;32695:44;32785:2;32776:11;;;;;;:::i;:::-;;;;;32819:1;32810:5;:10;32806:21;;;32822:5;;32806:21;32555:288;;;32864:6;32857:13;;;;;32173:716;;;:::o;62715:132::-;62790:12;:10;:12::i;:::-;62779:23;;:7;:5;:7::i;:::-;:23;;;62771:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;62715:132::o;54674:808::-;54817:1;54801:18;;:4;:18;;;;54793:66;;;;;;;;;;;;:::i;:::-;;;;;;;;;54872:16;54891:12;:10;:12::i;:::-;54872:31;;54914:20;54937:21;54955:2;54937:17;:21::i;:::-;54914:44;;54969:24;54996:25;55014:6;54996:17;:25::i;:::-;54969:52;;55034:66;55055:8;55065:4;55079:1;55083:3;55088:7;55034:66;;;;;;;;;;;;:20;:66::i;:::-;55113:19;55135:9;:13;55145:2;55135:13;;;;;;;;;;;:19;55149:4;55135:19;;;;;;;;;;;;;;;;55113:41;;55188:6;55173:11;:21;;55165:70;;;;;;;;;;;;:::i;:::-;;;;;;;;;55307:6;55293:11;:20;55271:9;:13;55281:2;55271:13;;;;;;;;;;;:19;55285:4;55271:19;;;;;;;;;;;;;;;:42;;;;55381:1;55342:54;;55367:4;55342:54;;55357:8;55342:54;;;55385:2;55389:6;55342:54;;;;;;;:::i;:::-;;;;;;;;55409:65;55429:8;55439:4;55453:1;55457:3;55462:7;55409:65;;;;;;;;;;;;:19;:65::i;:::-;54782:700;;;;54674:808;;;:::o;63817:191::-;63891:16;63910:6;;;;;;;;;;;63891:25;;63936:8;63927:6;;:17;;;;;;;;;;;;;;;;;;63991:8;63960:40;;63981:8;63960:40;;;;;;;;;;;;63880:128;63817:191;:::o;52431:729::-;52598:1;52584:16;;:2;:16;;;;52576:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;52651:16;52670:12;:10;:12::i;:::-;52651:31;;52693:20;52716:21;52734:2;52716:17;:21::i;:::-;52693:44;;52748:24;52775:25;52793:6;52775:17;:25::i;:::-;52748:52;;52813:66;52834:8;52852:1;52856:2;52860:3;52865:7;52874:4;52813:20;:66::i;:::-;52913:6;52892:9;:13;52902:2;52892:13;;;;;;;;;;;:17;52906:2;52892:17;;;;;;;;;;;;;;;;:27;;;;;;;:::i;:::-;;;;;;;;52972:2;52935:52;;52968:1;52935:52;;52950:8;52935:52;;;52976:2;52980:6;52935:52;;;;;;;:::i;:::-;;;;;;;;53000:65;53020:8;53038:1;53042:2;53046:3;53051:7;53060:4;53000:19;:65::i;:::-;53078:74;53109:8;53127:1;53131:2;53135;53139:6;53147:4;53078:30;:74::i;:::-;52565:595;;;52431:729;;;;:::o;65908:333::-;66063:4;66220:13;;;;;;;;;;;66087:146;;:129;66206:9;66087:100;66114:6;66122:12;66136:7;66145:5;66097:54;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;66087:65;;;;;;:98;:100::i;:::-;:118;;:129;;;;:::i;:::-;:146;;;66080:153;;65908:333;;;;;;:::o;29039:922::-;29092:7;29112:14;29129:1;29112:18;;29179:6;29170:5;:15;29166:102;;29215:6;29206:15;;;;;;:::i;:::-;;;;;29250:2;29240:12;;;;29166:102;29295:6;29286:5;:15;29282:102;;29331:6;29322:15;;;;;;:::i;:::-;;;;;29366:2;29356:12;;;;29282:102;29411:6;29402:5;:15;29398:102;;29447:6;29438:15;;;;;;:::i;:::-;;;;;29482:2;29472:12;;;;29398:102;29527:5;29518;:14;29514:99;;29562:5;29553:14;;;;;;:::i;:::-;;;;;29596:1;29586:11;;;;29514:99;29640:5;29631;:14;29627:99;;29675:5;29666:14;;;;;;:::i;:::-;;;;;29709:1;29699:11;;;;29627:99;29753:5;29744;:14;29740:99;;29788:5;29779:14;;;;;;:::i;:::-;;;;;29822:1;29812:11;;;;29740:99;29866:5;29857;:14;29853:66;;29902:1;29892:11;;;;29853:66;29947:6;29940:13;;;29039:922;;;:::o;43507:98::-;43560:7;43587:10;43580:17;;43507:98;:::o;61110:198::-;61176:16;61205:22;61244:1;61230:16;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61205:41;;61268:7;61257:5;61263:1;61257:8;;;;;;;;:::i;:::-;;;;;;;:18;;;;;61295:5;61288:12;;;61110:198;;;:::o;58133:221::-;;;;;;;:::o;59309:220::-;;;;;;;:::o;59537:744::-;59752:15;:2;:13;;;:15::i;:::-;59748:526;;;59805:2;59788:38;;;59827:8;59837:4;59843:2;59847:6;59855:4;59788:72;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;59784:479;;;;:::i;:::-;;;;;;;;;;:::i;:::-;;;;;;;;60136:6;60129:14;;;;;;;;;;;:::i;:::-;;;;;;;;59784:479;;;60185:62;;;;;;;;;;:::i;:::-;;;;;;;;59784:479;59922:43;;;59910:55;;;:8;:55;;;;59906:154;;59990:50;;;;;;;;;;:::i;:::-;;;;;;;;59906:154;59861:214;59748:526;59537:744;;;;;;:::o;41513:269::-;41582:7;41768:4;41715:58;;;;;;;;:::i;:::-;;;;;;;;;;;;;41705:69;;;;;;41698:76;;41513:269;;;:::o;37823:231::-;37901:7;37922:17;37941:18;37963:27;37974:4;37980:9;37963:10;:27::i;:::-;37921:69;;;;38001:18;38013:5;38001:11;:18::i;:::-;38037:9;38030:16;;;;37823:231;;;;:::o;1264:326::-;1324:4;1581:1;1559:7;:19;;;:23;1552:30;;1264:326;;;:::o;36274:747::-;36355:7;36364:12;36413:2;36393:9;:16;:22;36389:625;;;36432:9;36456;36480:7;36737:4;36726:9;36722:20;36716:27;36711:32;;36787:4;36776:9;36772:20;36766:27;36761:32;;36845:4;36834:9;36830:20;36824:27;36821:1;36816:36;36811:41;;36888:25;36899:4;36905:1;36908;36911;36888:10;:25::i;:::-;36881:32;;;;;;;;;36389:625;36962:1;36966:35;36946:56;;;;36274:747;;;;;;:::o;34667:521::-;34745:20;34736:29;;;;;;;;:::i;:::-;;:5;:29;;;;;;;;:::i;:::-;;;34732:449;;;34782:7;;34732:449;34843:29;34834:38;;;;;;;;:::i;:::-;;:5;:38;;;;;;;;:::i;:::-;;;34830:351;;;34889:34;;;;;;;;;;:::i;:::-;;;;;;;;34830:351;34954:35;34945:44;;;;;;;;:::i;:::-;;:5;:44;;;;;;;;:::i;:::-;;;34941:240;;;35006:41;;;;;;;;;;:::i;:::-;;;;;;;;34941:240;35078:30;35069:39;;;;;;;;:::i;:::-;;:5;:39;;;;;;;;:::i;:::-;;;35065:116;;;35125:44;;;;;;;;;;:::i;:::-;;;;;;;;35065:116;34667:521;;:::o;39275:1520::-;39406:7;39415:12;40340:66;40335:1;40327:10;;:79;40323:163;;;40439:1;40443:30;40423:51;;;;;;40323:163;40583:14;40600:24;40610:4;40616:1;40619;40622;40600:24;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;40583:41;;40657:1;40639:20;;:6;:20;;;40635:103;;;40692:1;40696:29;40676:50;;;;;;;40635:103;40758:6;40766:20;40750:37;;;;;39275:1520;;;;;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;24:722:1:-;120:5;145:81;161:64;218:6;161:64;:::i;:::-;145:81;:::i;:::-;136:90;;246:5;275:6;268:5;261:21;309:4;302:5;298:16;291:23;;335:6;385:3;377:4;369:6;365:17;360:3;356:27;353:36;350:143;;;404:79;;:::i;:::-;350:143;517:1;502:238;527:6;524:1;521:13;502:238;;;595:3;624:37;657:3;645:10;624:37;:::i;:::-;619:3;612:50;691:4;686:3;682:14;675:21;;725:4;720:3;716:14;709:21;;562:178;549:1;546;542:9;537:14;;502:238;;;506:14;126:620;;24:722;;;;;:::o;769:::-;865:5;890:81;906:64;963:6;906:64;:::i;:::-;890:81;:::i;:::-;881:90;;991:5;1020:6;1013:5;1006:21;1054:4;1047:5;1043:16;1036:23;;1080:6;1130:3;1122:4;1114:6;1110:17;1105:3;1101:27;1098:36;1095:143;;;1149:79;;:::i;:::-;1095:143;1262:1;1247:238;1272:6;1269:1;1266:13;1247:238;;;1340:3;1369:37;1402:3;1390:10;1369:37;:::i;:::-;1364:3;1357:50;1436:4;1431:3;1427:14;1420:21;;1470:4;1465:3;1461:14;1454:21;;1307:178;1294:1;1291;1287:9;1282:14;;1247:238;;;1251:14;871:620;;769:722;;;;;:::o;1497:410::-;1574:5;1599:65;1615:48;1656:6;1615:48;:::i;:::-;1599:65;:::i;:::-;1590:74;;1687:6;1680:5;1673:21;1725:4;1718:5;1714:16;1763:3;1754:6;1749:3;1745:16;1742:25;1739:112;;;1770:79;;:::i;:::-;1739:112;1860:41;1894:6;1889:3;1884;1860:41;:::i;:::-;1580:327;1497:410;;;;;:::o;1913:139::-;1959:5;1997:6;1984:20;1975:29;;2013:33;2040:5;2013:33;:::i;:::-;1913:139;;;;:::o;2075:568::-;2148:8;2158:6;2208:3;2201:4;2193:6;2189:17;2185:27;2175:122;;2216:79;;:::i;:::-;2175:122;2329:6;2316:20;2306:30;;2359:18;2351:6;2348:30;2345:117;;;2381:79;;:::i;:::-;2345:117;2495:4;2487:6;2483:17;2471:29;;2549:3;2541:4;2533:6;2529:17;2519:8;2515:32;2512:41;2509:128;;;2556:79;;:::i;:::-;2509:128;2075:568;;;;;:::o;2666:370::-;2737:5;2786:3;2779:4;2771:6;2767:17;2763:27;2753:122;;2794:79;;:::i;:::-;2753:122;2911:6;2898:20;2936:94;3026:3;3018:6;3011:4;3003:6;2999:17;2936:94;:::i;:::-;2927:103;;2743:293;2666:370;;;;:::o;3059:::-;3130:5;3179:3;3172:4;3164:6;3160:17;3156:27;3146:122;;3187:79;;:::i;:::-;3146:122;3304:6;3291:20;3329:94;3419:3;3411:6;3404:4;3396:6;3392:17;3329:94;:::i;:::-;3320:103;;3136:293;3059:370;;;;:::o;3435:133::-;3478:5;3516:6;3503:20;3494:29;;3532:30;3556:5;3532:30;:::i;:::-;3435:133;;;;:::o;3574:137::-;3619:5;3657:6;3644:20;3635:29;;3673:32;3699:5;3673:32;:::i;:::-;3574:137;;;;:::o;3717:141::-;3773:5;3804:6;3798:13;3789:22;;3820:32;3846:5;3820:32;:::i;:::-;3717:141;;;;:::o;3877:338::-;3932:5;3981:3;3974:4;3966:6;3962:17;3958:27;3948:122;;3989:79;;:::i;:::-;3948:122;4106:6;4093:20;4131:78;4205:3;4197:6;4190:4;4182:6;4178:17;4131:78;:::i;:::-;4122:87;;3938:277;3877:338;;;;:::o;4235:553::-;4293:8;4303:6;4353:3;4346:4;4338:6;4334:17;4330:27;4320:122;;4361:79;;:::i;:::-;4320:122;4474:6;4461:20;4451:30;;4504:18;4496:6;4493:30;4490:117;;;4526:79;;:::i;:::-;4490:117;4640:4;4632:6;4628:17;4616:29;;4694:3;4686:4;4678:6;4674:17;4664:8;4660:32;4657:41;4654:128;;;4701:79;;:::i;:::-;4654:128;4235:553;;;;;:::o;4794:139::-;4840:5;4878:6;4865:20;4856:29;;4894:33;4921:5;4894:33;:::i;:::-;4794:139;;;;:::o;4939:329::-;4998:6;5047:2;5035:9;5026:7;5022:23;5018:32;5015:119;;;5053:79;;:::i;:::-;5015:119;5173:1;5198:53;5243:7;5234:6;5223:9;5219:22;5198:53;:::i;:::-;5188:63;;5144:117;4939:329;;;;:::o;5274:474::-;5342:6;5350;5399:2;5387:9;5378:7;5374:23;5370:32;5367:119;;;5405:79;;:::i;:::-;5367:119;5525:1;5550:53;5595:7;5586:6;5575:9;5571:22;5550:53;:::i;:::-;5540:63;;5496:117;5652:2;5678:53;5723:7;5714:6;5703:9;5699:22;5678:53;:::i;:::-;5668:63;;5623:118;5274:474;;;;;:::o;5754:1509::-;5908:6;5916;5924;5932;5940;5989:3;5977:9;5968:7;5964:23;5960:33;5957:120;;;5996:79;;:::i;:::-;5957:120;6116:1;6141:53;6186:7;6177:6;6166:9;6162:22;6141:53;:::i;:::-;6131:63;;6087:117;6243:2;6269:53;6314:7;6305:6;6294:9;6290:22;6269:53;:::i;:::-;6259:63;;6214:118;6399:2;6388:9;6384:18;6371:32;6430:18;6422:6;6419:30;6416:117;;;6452:79;;:::i;:::-;6416:117;6557:78;6627:7;6618:6;6607:9;6603:22;6557:78;:::i;:::-;6547:88;;6342:303;6712:2;6701:9;6697:18;6684:32;6743:18;6735:6;6732:30;6729:117;;;6765:79;;:::i;:::-;6729:117;6870:78;6940:7;6931:6;6920:9;6916:22;6870:78;:::i;:::-;6860:88;;6655:303;7025:3;7014:9;7010:19;6997:33;7057:18;7049:6;7046:30;7043:117;;;7079:79;;:::i;:::-;7043:117;7184:62;7238:7;7229:6;7218:9;7214:22;7184:62;:::i;:::-;7174:72;;6968:288;5754:1509;;;;;;;;:::o;7269:1089::-;7373:6;7381;7389;7397;7405;7454:3;7442:9;7433:7;7429:23;7425:33;7422:120;;;7461:79;;:::i;:::-;7422:120;7581:1;7606:53;7651:7;7642:6;7631:9;7627:22;7606:53;:::i;:::-;7596:63;;7552:117;7708:2;7734:53;7779:7;7770:6;7759:9;7755:22;7734:53;:::i;:::-;7724:63;;7679:118;7836:2;7862:53;7907:7;7898:6;7887:9;7883:22;7862:53;:::i;:::-;7852:63;;7807:118;7964:2;7990:53;8035:7;8026:6;8015:9;8011:22;7990:53;:::i;:::-;7980:63;;7935:118;8120:3;8109:9;8105:19;8092:33;8152:18;8144:6;8141:30;8138:117;;;8174:79;;:::i;:::-;8138:117;8279:62;8333:7;8324:6;8313:9;8309:22;8279:62;:::i;:::-;8269:72;;8063:288;7269:1089;;;;;;;;:::o;8364:468::-;8429:6;8437;8486:2;8474:9;8465:7;8461:23;8457:32;8454:119;;;8492:79;;:::i;:::-;8454:119;8612:1;8637:53;8682:7;8673:6;8662:9;8658:22;8637:53;:::i;:::-;8627:63;;8583:117;8739:2;8765:50;8807:7;8798:6;8787:9;8783:22;8765:50;:::i;:::-;8755:60;;8710:115;8364:468;;;;;:::o;8838:474::-;8906:6;8914;8963:2;8951:9;8942:7;8938:23;8934:32;8931:119;;;8969:79;;:::i;:::-;8931:119;9089:1;9114:53;9159:7;9150:6;9139:9;9135:22;9114:53;:::i;:::-;9104:63;;9060:117;9216:2;9242:53;9287:7;9278:6;9267:9;9263:22;9242:53;:::i;:::-;9232:63;;9187:118;8838:474;;;;;:::o;9318:943::-;9413:6;9421;9429;9437;9486:3;9474:9;9465:7;9461:23;9457:33;9454:120;;;9493:79;;:::i;:::-;9454:120;9613:1;9638:53;9683:7;9674:6;9663:9;9659:22;9638:53;:::i;:::-;9628:63;;9584:117;9740:2;9766:53;9811:7;9802:6;9791:9;9787:22;9766:53;:::i;:::-;9756:63;;9711:118;9868:2;9894:53;9939:7;9930:6;9919:9;9915:22;9894:53;:::i;:::-;9884:63;;9839:118;10024:2;10013:9;10009:18;9996:32;10055:18;10047:6;10044:30;10041:117;;;10077:79;;:::i;:::-;10041:117;10182:62;10236:7;10227:6;10216:9;10212:22;10182:62;:::i;:::-;10172:72;;9967:287;9318:943;;;;;;;:::o;10267:894::-;10385:6;10393;10442:2;10430:9;10421:7;10417:23;10413:32;10410:119;;;10448:79;;:::i;:::-;10410:119;10596:1;10585:9;10581:17;10568:31;10626:18;10618:6;10615:30;10612:117;;;10648:79;;:::i;:::-;10612:117;10753:78;10823:7;10814:6;10803:9;10799:22;10753:78;:::i;:::-;10743:88;;10539:302;10908:2;10897:9;10893:18;10880:32;10939:18;10931:6;10928:30;10925:117;;;10961:79;;:::i;:::-;10925:117;11066:78;11136:7;11127:6;11116:9;11112:22;11066:78;:::i;:::-;11056:88;;10851:303;10267:894;;;;;:::o;11167:327::-;11225:6;11274:2;11262:9;11253:7;11249:23;11245:32;11242:119;;;11280:79;;:::i;:::-;11242:119;11400:1;11425:52;11469:7;11460:6;11449:9;11445:22;11425:52;:::i;:::-;11415:62;;11371:116;11167:327;;;;:::o;11500:349::-;11569:6;11618:2;11606:9;11597:7;11593:23;11589:32;11586:119;;;11624:79;;:::i;:::-;11586:119;11744:1;11769:63;11824:7;11815:6;11804:9;11800:22;11769:63;:::i;:::-;11759:73;;11715:127;11500:349;;;;:::o;11855:529::-;11926:6;11934;11983:2;11971:9;11962:7;11958:23;11954:32;11951:119;;;11989:79;;:::i;:::-;11951:119;12137:1;12126:9;12122:17;12109:31;12167:18;12159:6;12156:30;12153:117;;;12189:79;;:::i;:::-;12153:117;12302:65;12359:7;12350:6;12339:9;12335:22;12302:65;:::i;:::-;12284:83;;;;12080:297;11855:529;;;;;:::o;12390:874::-;12482:6;12490;12498;12506;12555:2;12543:9;12534:7;12530:23;12526:32;12523:119;;;12561:79;;:::i;:::-;12523:119;12709:1;12698:9;12694:17;12681:31;12739:18;12731:6;12728:30;12725:117;;;12761:79;;:::i;:::-;12725:117;12874:65;12931:7;12922:6;12911:9;12907:22;12874:65;:::i;:::-;12856:83;;;;12652:297;13016:2;13005:9;13001:18;12988:32;13047:18;13039:6;13036:30;13033:117;;;13069:79;;:::i;:::-;13033:117;13182:65;13239:7;13230:6;13219:9;13215:22;13182:65;:::i;:::-;13164:83;;;;12959:298;12390:874;;;;;;;:::o;13270:329::-;13329:6;13378:2;13366:9;13357:7;13353:23;13349:32;13346:119;;;13384:79;;:::i;:::-;13346:119;13504:1;13529:53;13574:7;13565:6;13554:9;13550:22;13529:53;:::i;:::-;13519:63;;13475:117;13270:329;;;;:::o;13605:704::-;13700:6;13708;13716;13765:2;13753:9;13744:7;13740:23;13736:32;13733:119;;;13771:79;;:::i;:::-;13733:119;13891:1;13916:53;13961:7;13952:6;13941:9;13937:22;13916:53;:::i;:::-;13906:63;;13862:117;14046:2;14035:9;14031:18;14018:32;14077:18;14069:6;14066:30;14063:117;;;14099:79;;:::i;:::-;14063:117;14212:80;14284:7;14275:6;14264:9;14260:22;14212:80;:::i;:::-;14194:98;;;;13989:313;13605:704;;;;;:::o;14315:179::-;14384:10;14405:46;14447:3;14439:6;14405:46;:::i;:::-;14483:4;14478:3;14474:14;14460:28;;14315:179;;;;:::o;14500:118::-;14587:24;14605:5;14587:24;:::i;:::-;14582:3;14575:37;14500:118;;:::o;14624:157::-;14729:45;14749:24;14767:5;14749:24;:::i;:::-;14729:45;:::i;:::-;14724:3;14717:58;14624:157;;:::o;14817:732::-;14936:3;14965:54;15013:5;14965:54;:::i;:::-;15035:86;15114:6;15109:3;15035:86;:::i;:::-;15028:93;;15145:56;15195:5;15145:56;:::i;:::-;15224:7;15255:1;15240:284;15265:6;15262:1;15259:13;15240:284;;;15341:6;15335:13;15368:63;15427:3;15412:13;15368:63;:::i;:::-;15361:70;;15454:60;15507:6;15454:60;:::i;:::-;15444:70;;15300:224;15287:1;15284;15280:9;15275:14;;15240:284;;;15244:14;15540:3;15533:10;;14941:608;;;14817:732;;;;:::o;15555:109::-;15636:21;15651:5;15636:21;:::i;:::-;15631:3;15624:34;15555:109;;:::o;15670:118::-;15757:24;15775:5;15757:24;:::i;:::-;15752:3;15745:37;15670:118;;:::o;15794:157::-;15899:45;15919:24;15937:5;15919:24;:::i;:::-;15899:45;:::i;:::-;15894:3;15887:58;15794:157;;:::o;15957:360::-;16043:3;16071:38;16103:5;16071:38;:::i;:::-;16125:70;16188:6;16183:3;16125:70;:::i;:::-;16118:77;;16204:52;16249:6;16244:3;16237:4;16230:5;16226:16;16204:52;:::i;:::-;16281:29;16303:6;16281:29;:::i;:::-;16276:3;16272:39;16265:46;;16047:270;15957:360;;;;:::o;16323:364::-;16411:3;16439:39;16472:5;16439:39;:::i;:::-;16494:71;16558:6;16553:3;16494:71;:::i;:::-;16487:78;;16574:52;16619:6;16614:3;16607:4;16600:5;16596:16;16574:52;:::i;:::-;16651:29;16673:6;16651:29;:::i;:::-;16646:3;16642:39;16635:46;;16415:272;16323:364;;;;:::o;16693:377::-;16799:3;16827:39;16860:5;16827:39;:::i;:::-;16882:89;16964:6;16959:3;16882:89;:::i;:::-;16875:96;;16980:52;17025:6;17020:3;17013:4;17006:5;17002:16;16980:52;:::i;:::-;17057:6;17052:3;17048:16;17041:23;;16803:267;16693:377;;;;:::o;17100:845::-;17203:3;17240:5;17234:12;17269:36;17295:9;17269:36;:::i;:::-;17321:89;17403:6;17398:3;17321:89;:::i;:::-;17314:96;;17441:1;17430:9;17426:17;17457:1;17452:137;;;;17603:1;17598:341;;;;17419:520;;17452:137;17536:4;17532:9;17521;17517:25;17512:3;17505:38;17572:6;17567:3;17563:16;17556:23;;17452:137;;17598:341;17665:38;17697:5;17665:38;:::i;:::-;17725:1;17739:154;17753:6;17750:1;17747:13;17739:154;;;17827:7;17821:14;17817:1;17812:3;17808:11;17801:35;17877:1;17868:7;17864:15;17853:26;;17775:4;17772:1;17768:12;17763:17;;17739:154;;;17922:6;17917:3;17913:16;17906:23;;17605:334;;17419:520;;17207:738;;17100:845;;;;:::o;17951:366::-;18093:3;18114:67;18178:2;18173:3;18114:67;:::i;:::-;18107:74;;18190:93;18279:3;18190:93;:::i;:::-;18308:2;18303:3;18299:12;18292:19;;17951:366;;;:::o;18323:::-;18465:3;18486:67;18550:2;18545:3;18486:67;:::i;:::-;18479:74;;18562:93;18651:3;18562:93;:::i;:::-;18680:2;18675:3;18671:12;18664:19;;18323:366;;;:::o;18695:::-;18837:3;18858:67;18922:2;18917:3;18858:67;:::i;:::-;18851:74;;18934:93;19023:3;18934:93;:::i;:::-;19052:2;19047:3;19043:12;19036:19;;18695:366;;;:::o;19067:402::-;19227:3;19248:85;19330:2;19325:3;19248:85;:::i;:::-;19241:92;;19342:93;19431:3;19342:93;:::i;:::-;19460:2;19455:3;19451:12;19444:19;;19067:402;;;:::o;19475:366::-;19617:3;19638:67;19702:2;19697:3;19638:67;:::i;:::-;19631:74;;19714:93;19803:3;19714:93;:::i;:::-;19832:2;19827:3;19823:12;19816:19;;19475:366;;;:::o;19847:::-;19989:3;20010:67;20074:2;20069:3;20010:67;:::i;:::-;20003:74;;20086:93;20175:3;20086:93;:::i;:::-;20204:2;20199:3;20195:12;20188:19;;19847:366;;;:::o;20219:::-;20361:3;20382:67;20446:2;20441:3;20382:67;:::i;:::-;20375:74;;20458:93;20547:3;20458:93;:::i;:::-;20576:2;20571:3;20567:12;20560:19;;20219:366;;;:::o;20591:::-;20733:3;20754:67;20818:2;20813:3;20754:67;:::i;:::-;20747:74;;20830:93;20919:3;20830:93;:::i;:::-;20948:2;20943:3;20939:12;20932:19;;20591:366;;;:::o;20963:::-;21105:3;21126:67;21190:2;21185:3;21126:67;:::i;:::-;21119:74;;21202:93;21291:3;21202:93;:::i;:::-;21320:2;21315:3;21311:12;21304:19;;20963:366;;;:::o;21335:::-;21477:3;21498:67;21562:2;21557:3;21498:67;:::i;:::-;21491:74;;21574:93;21663:3;21574:93;:::i;:::-;21692:2;21687:3;21683:12;21676:19;;21335:366;;;:::o;21707:::-;21849:3;21870:67;21934:2;21929:3;21870:67;:::i;:::-;21863:74;;21946:93;22035:3;21946:93;:::i;:::-;22064:2;22059:3;22055:12;22048:19;;21707:366;;;:::o;22079:::-;22221:3;22242:67;22306:2;22301:3;22242:67;:::i;:::-;22235:74;;22318:93;22407:3;22318:93;:::i;:::-;22436:2;22431:3;22427:12;22420:19;;22079:366;;;:::o;22451:::-;22593:3;22614:67;22678:2;22673:3;22614:67;:::i;:::-;22607:74;;22690:93;22779:3;22690:93;:::i;:::-;22808:2;22803:3;22799:12;22792:19;;22451:366;;;:::o;22823:108::-;22900:24;22918:5;22900:24;:::i;:::-;22895:3;22888:37;22823:108;;:::o;22937:118::-;23024:24;23042:5;23024:24;:::i;:::-;23019:3;23012:37;22937:118;;:::o;23061:157::-;23166:45;23186:24;23204:5;23186:24;:::i;:::-;23166:45;:::i;:::-;23161:3;23154:58;23061:157;;:::o;23224:112::-;23307:22;23323:5;23307:22;:::i;:::-;23302:3;23295:35;23224:112;;:::o;23342:692::-;23555:3;23570:75;23641:3;23632:6;23570:75;:::i;:::-;23670:2;23665:3;23661:12;23654:19;;23690:92;23778:3;23769:6;23690:92;:::i;:::-;23683:99;;23792:75;23863:3;23854:6;23792:75;:::i;:::-;23892:2;23887:3;23883:12;23876:19;;23905:75;23976:3;23967:6;23905:75;:::i;:::-;24005:2;24000:3;23996:12;23989:19;;24025:3;24018:10;;23342:692;;;;;;;:::o;24040:583::-;24262:3;24284:92;24372:3;24363:6;24284:92;:::i;:::-;24277:99;;24393:95;24484:3;24475:6;24393:95;:::i;:::-;24386:102;;24505:92;24593:3;24584:6;24505:92;:::i;:::-;24498:99;;24614:3;24607:10;;24040:583;;;;;;:::o;24629:522::-;24842:3;24864:148;25008:3;24864:148;:::i;:::-;24857:155;;25022:75;25093:3;25084:6;25022:75;:::i;:::-;25122:2;25117:3;25113:12;25106:19;;25142:3;25135:10;;24629:522;;;;:::o;25157:222::-;25250:4;25288:2;25277:9;25273:18;25265:26;;25301:71;25369:1;25358:9;25354:17;25345:6;25301:71;:::i;:::-;25157:222;;;;:::o;25385:751::-;25608:4;25646:3;25635:9;25631:19;25623:27;;25660:71;25728:1;25717:9;25713:17;25704:6;25660:71;:::i;:::-;25741:72;25809:2;25798:9;25794:18;25785:6;25741:72;:::i;:::-;25823;25891:2;25880:9;25876:18;25867:6;25823:72;:::i;:::-;25905;25973:2;25962:9;25958:18;25949:6;25905:72;:::i;:::-;26025:9;26019:4;26015:20;26009:3;25998:9;25994:19;25987:49;26053:76;26124:4;26115:6;26053:76;:::i;:::-;26045:84;;25385:751;;;;;;;;:::o;26142:373::-;26285:4;26323:2;26312:9;26308:18;26300:26;;26372:9;26366:4;26362:20;26358:1;26347:9;26343:17;26336:47;26400:108;26503:4;26494:6;26400:108;:::i;:::-;26392:116;;26142:373;;;;:::o;26521:210::-;26608:4;26646:2;26635:9;26631:18;26623:26;;26659:65;26721:1;26710:9;26706:17;26697:6;26659:65;:::i;:::-;26521:210;;;;:::o;26737:545::-;26910:4;26948:3;26937:9;26933:19;26925:27;;26962:71;27030:1;27019:9;27015:17;27006:6;26962:71;:::i;:::-;27043:68;27107:2;27096:9;27092:18;27083:6;27043:68;:::i;:::-;27121:72;27189:2;27178:9;27174:18;27165:6;27121:72;:::i;:::-;27203;27271:2;27260:9;27256:18;27247:6;27203:72;:::i;:::-;26737:545;;;;;;;:::o;27288:313::-;27401:4;27439:2;27428:9;27424:18;27416:26;;27488:9;27482:4;27478:20;27474:1;27463:9;27459:17;27452:47;27516:78;27589:4;27580:6;27516:78;:::i;:::-;27508:86;;27288:313;;;;:::o;27607:419::-;27773:4;27811:2;27800:9;27796:18;27788:26;;27860:9;27854:4;27850:20;27846:1;27835:9;27831:17;27824:47;27888:131;28014:4;27888:131;:::i;:::-;27880:139;;27607:419;;;:::o;28032:::-;28198:4;28236:2;28225:9;28221:18;28213:26;;28285:9;28279:4;28275:20;28271:1;28260:9;28256:17;28249:47;28313:131;28439:4;28313:131;:::i;:::-;28305:139;;28032:419;;;:::o;28457:::-;28623:4;28661:2;28650:9;28646:18;28638:26;;28710:9;28704:4;28700:20;28696:1;28685:9;28681:17;28674:47;28738:131;28864:4;28738:131;:::i;:::-;28730:139;;28457:419;;;:::o;28882:::-;29048:4;29086:2;29075:9;29071:18;29063:26;;29135:9;29129:4;29125:20;29121:1;29110:9;29106:17;29099:47;29163:131;29289:4;29163:131;:::i;:::-;29155:139;;28882:419;;;:::o;29307:::-;29473:4;29511:2;29500:9;29496:18;29488:26;;29560:9;29554:4;29550:20;29546:1;29535:9;29531:17;29524:47;29588:131;29714:4;29588:131;:::i;:::-;29580:139;;29307:419;;;:::o;29732:::-;29898:4;29936:2;29925:9;29921:18;29913:26;;29985:9;29979:4;29975:20;29971:1;29960:9;29956:17;29949:47;30013:131;30139:4;30013:131;:::i;:::-;30005:139;;29732:419;;;:::o;30157:::-;30323:4;30361:2;30350:9;30346:18;30338:26;;30410:9;30404:4;30400:20;30396:1;30385:9;30381:17;30374:47;30438:131;30564:4;30438:131;:::i;:::-;30430:139;;30157:419;;;:::o;30582:::-;30748:4;30786:2;30775:9;30771:18;30763:26;;30835:9;30829:4;30825:20;30821:1;30810:9;30806:17;30799:47;30863:131;30989:4;30863:131;:::i;:::-;30855:139;;30582:419;;;:::o;31007:::-;31173:4;31211:2;31200:9;31196:18;31188:26;;31260:9;31254:4;31250:20;31246:1;31235:9;31231:17;31224:47;31288:131;31414:4;31288:131;:::i;:::-;31280:139;;31007:419;;;:::o;31432:::-;31598:4;31636:2;31625:9;31621:18;31613:26;;31685:9;31679:4;31675:20;31671:1;31660:9;31656:17;31649:47;31713:131;31839:4;31713:131;:::i;:::-;31705:139;;31432:419;;;:::o;31857:::-;32023:4;32061:2;32050:9;32046:18;32038:26;;32110:9;32104:4;32100:20;32096:1;32085:9;32081:17;32074:47;32138:131;32264:4;32138:131;:::i;:::-;32130:139;;31857:419;;;:::o;32282:::-;32448:4;32486:2;32475:9;32471:18;32463:26;;32535:9;32529:4;32525:20;32521:1;32510:9;32506:17;32499:47;32563:131;32689:4;32563:131;:::i;:::-;32555:139;;32282:419;;;:::o;32707:222::-;32800:4;32838:2;32827:9;32823:18;32815:26;;32851:71;32919:1;32908:9;32904:17;32895:6;32851:71;:::i;:::-;32707:222;;;;:::o;32935:332::-;33056:4;33094:2;33083:9;33079:18;33071:26;;33107:71;33175:1;33164:9;33160:17;33151:6;33107:71;:::i;:::-;33188:72;33256:2;33245:9;33241:18;33232:6;33188:72;:::i;:::-;32935:332;;;;;:::o;33273:129::-;33307:6;33334:20;;:::i;:::-;33324:30;;33363:33;33391:4;33383:6;33363:33;:::i;:::-;33273:129;;;:::o;33408:75::-;33441:6;33474:2;33468:9;33458:19;;33408:75;:::o;33489:311::-;33566:4;33656:18;33648:6;33645:30;33642:56;;;33678:18;;:::i;:::-;33642:56;33728:4;33720:6;33716:17;33708:25;;33788:4;33782;33778:15;33770:23;;33489:311;;;:::o;33806:::-;33883:4;33973:18;33965:6;33962:30;33959:56;;;33995:18;;:::i;:::-;33959:56;34045:4;34037:6;34033:17;34025:25;;34105:4;34099;34095:15;34087:23;;33806:311;;;:::o;34123:307::-;34184:4;34274:18;34266:6;34263:30;34260:56;;;34296:18;;:::i;:::-;34260:56;34334:29;34356:6;34334:29;:::i;:::-;34326:37;;34418:4;34412;34408:15;34400:23;;34123:307;;;:::o;34436:132::-;34503:4;34526:3;34518:11;;34556:4;34551:3;34547:14;34539:22;;34436:132;;;:::o;34574:141::-;34623:4;34646:3;34638:11;;34669:3;34666:1;34659:14;34703:4;34700:1;34690:18;34682:26;;34574:141;;;:::o;34721:114::-;34788:6;34822:5;34816:12;34806:22;;34721:114;;;:::o;34841:98::-;34892:6;34926:5;34920:12;34910:22;;34841:98;;;:::o;34945:99::-;34997:6;35031:5;35025:12;35015:22;;34945:99;;;:::o;35050:113::-;35120:4;35152;35147:3;35143:14;35135:22;;35050:113;;;:::o;35169:184::-;35268:11;35302:6;35297:3;35290:19;35342:4;35337:3;35333:14;35318:29;;35169:184;;;;:::o;35359:168::-;35442:11;35476:6;35471:3;35464:19;35516:4;35511:3;35507:14;35492:29;;35359:168;;;;:::o;35533:169::-;35617:11;35651:6;35646:3;35639:19;35691:4;35686:3;35682:14;35667:29;;35533:169;;;;:::o;35708:148::-;35810:11;35847:3;35832:18;;35708:148;;;;:::o;35862:305::-;35902:3;35921:20;35939:1;35921:20;:::i;:::-;35916:25;;35955:20;35973:1;35955:20;:::i;:::-;35950:25;;36109:1;36041:66;36037:74;36034:1;36031:81;36028:107;;;36115:18;;:::i;:::-;36028:107;36159:1;36156;36152:9;36145:16;;35862:305;;;;:::o;36173:96::-;36210:7;36239:24;36257:5;36239:24;:::i;:::-;36228:35;;36173:96;;;:::o;36275:90::-;36309:7;36352:5;36345:13;36338:21;36327:32;;36275:90;;;:::o;36371:77::-;36408:7;36437:5;36426:16;;36371:77;;;:::o;36454:149::-;36490:7;36530:66;36523:5;36519:78;36508:89;;36454:149;;;:::o;36609:126::-;36646:7;36686:42;36679:5;36675:54;36664:65;;36609:126;;;:::o;36741:77::-;36778:7;36807:5;36796:16;;36741:77;;;:::o;36824:86::-;36859:7;36899:4;36892:5;36888:16;36877:27;;36824:86;;;:::o;36916:154::-;37000:6;36995:3;36990;36977:30;37062:1;37053:6;37048:3;37044:16;37037:27;36916:154;;;:::o;37076:307::-;37144:1;37154:113;37168:6;37165:1;37162:13;37154:113;;;37253:1;37248:3;37244:11;37238:18;37234:1;37229:3;37225:11;37218:39;37190:2;37187:1;37183:10;37178:15;;37154:113;;;37285:6;37282:1;37279:13;37276:101;;;37365:1;37356:6;37351:3;37347:16;37340:27;37276:101;37125:258;37076:307;;;:::o;37389:320::-;37433:6;37470:1;37464:4;37460:12;37450:22;;37517:1;37511:4;37507:12;37538:18;37528:81;;37594:4;37586:6;37582:17;37572:27;;37528:81;37656:2;37648:6;37645:14;37625:18;37622:38;37619:84;;;37675:18;;:::i;:::-;37619:84;37440:269;37389:320;;;:::o;37715:281::-;37798:27;37820:4;37798:27;:::i;:::-;37790:6;37786:40;37928:6;37916:10;37913:22;37892:18;37880:10;37877:34;37874:62;37871:88;;;37939:18;;:::i;:::-;37871:88;37979:10;37975:2;37968:22;37758:238;37715:281;;:::o;38002:233::-;38041:3;38064:24;38082:5;38064:24;:::i;:::-;38055:33;;38110:66;38103:5;38100:77;38097:103;;;38180:18;;:::i;:::-;38097:103;38227:1;38220:5;38216:13;38209:20;;38002:233;;;:::o;38241:100::-;38280:7;38309:26;38329:5;38309:26;:::i;:::-;38298:37;;38241:100;;;:::o;38347:79::-;38386:7;38415:5;38404:16;;38347:79;;;:::o;38432:94::-;38471:7;38500:20;38514:5;38500:20;:::i;:::-;38489:31;;38432:94;;;:::o;38532:79::-;38571:7;38600:5;38589:16;;38532:79;;;:::o;38617:180::-;38665:77;38662:1;38655:88;38762:4;38759:1;38752:15;38786:4;38783:1;38776:15;38803:180;38851:77;38848:1;38841:88;38948:4;38945:1;38938:15;38972:4;38969:1;38962:15;38989:180;39037:77;39034:1;39027:88;39134:4;39131:1;39124:15;39158:4;39155:1;39148:15;39175:180;39223:77;39220:1;39213:88;39320:4;39317:1;39310:15;39344:4;39341:1;39334:15;39361:180;39409:77;39406:1;39399:88;39506:4;39503:1;39496:15;39530:4;39527:1;39520:15;39547:180;39595:77;39592:1;39585:88;39692:4;39689:1;39682:15;39716:4;39713:1;39706:15;39733:183;39768:3;39806:1;39788:16;39785:23;39782:128;;;39844:1;39841;39838;39823:23;39866:34;39897:1;39891:8;39866:34;:::i;:::-;39859:41;;39782:128;39733:183;:::o;39922:117::-;40031:1;40028;40021:12;40045:117;40154:1;40151;40144:12;40168:117;40277:1;40274;40267:12;40291:117;40400:1;40397;40390:12;40414:117;40523:1;40520;40513:12;40537:117;40646:1;40643;40636:12;40660:102;40701:6;40752:2;40748:7;40743:2;40736:5;40732:14;40728:28;40718:38;;40660:102;;;:::o;40768:94::-;40801:8;40849:5;40845:2;40841:14;40820:35;;40768:94;;;:::o;40868:106::-;40912:8;40961:5;40956:3;40952:15;40931:36;;40868:106;;;:::o;40980:174::-;41120:26;41116:1;41108:6;41104:14;41097:50;40980:174;:::o;41160:227::-;41300:34;41296:1;41288:6;41284:14;41277:58;41369:10;41364:2;41356:6;41352:15;41345:35;41160:227;:::o;41393:181::-;41533:33;41529:1;41521:6;41517:14;41510:57;41393:181;:::o;41580:214::-;41720:66;41716:1;41708:6;41704:14;41697:90;41580:214;:::o;41800:225::-;41940:34;41936:1;41928:6;41924:14;41917:58;42009:8;42004:2;41996:6;41992:15;41985:33;41800:225;:::o;42031:223::-;42171:34;42167:1;42159:6;42155:14;42148:58;42240:6;42235:2;42227:6;42223:15;42216:31;42031:223;:::o;42260:229::-;42400:34;42396:1;42388:6;42384:14;42377:58;42469:12;42464:2;42456:6;42452:15;42445:37;42260:229;:::o;42495:221::-;42635:34;42631:1;42623:6;42619:14;42612:58;42704:4;42699:2;42691:6;42687:15;42680:29;42495:221;:::o;42722:222::-;42862:34;42858:1;42850:6;42846:14;42839:58;42931:5;42926:2;42918:6;42914:15;42907:30;42722:222;:::o;42950:182::-;43090:34;43086:1;43078:6;43074:14;43067:58;42950:182;:::o;43138:228::-;43278:34;43274:1;43266:6;43262:14;43255:58;43347:11;43342:2;43334:6;43330:15;43323:36;43138:228;:::o;43372:220::-;43512:34;43508:1;43500:6;43496:14;43489:58;43581:3;43576:2;43568:6;43564:15;43557:28;43372:220;:::o;43598:239::-;43738:34;43734:1;43726:6;43722:14;43715:58;43807:22;43802:2;43794:6;43790:15;43783:47;43598:239;:::o;43843:711::-;43882:3;43920:4;43902:16;43899:26;43896:39;;;43928:5;;43896:39;43957:20;;:::i;:::-;44032:1;44014:16;44010:24;44007:1;44001:4;43986:49;44065:4;44059:11;44164:16;44157:4;44149:6;44145:17;44142:39;44109:18;44101:6;44098:30;44082:113;44079:146;;;44210:5;;;;44079:146;44256:6;44250:4;44246:17;44292:3;44286:10;44319:18;44311:6;44308:30;44305:43;;;44341:5;;;;;;44305:43;44389:6;44382:4;44377:3;44373:14;44369:27;44448:1;44430:16;44426:24;44420:4;44416:35;44411:3;44408:44;44405:57;;;44455:5;;;;;;;44405:57;44472;44520:6;44514:4;44510:17;44502:6;44498:30;44492:4;44472:57;:::i;:::-;44545:3;44538:10;;43886:668;;;;;43843:711;;:::o;44560:122::-;44633:24;44651:5;44633:24;:::i;:::-;44626:5;44623:35;44613:63;;44672:1;44669;44662:12;44613:63;44560:122;:::o;44688:116::-;44758:21;44773:5;44758:21;:::i;:::-;44751:5;44748:32;44738:60;;44794:1;44791;44784:12;44738:60;44688:116;:::o;44810:120::-;44882:23;44899:5;44882:23;:::i;:::-;44875:5;44872:34;44862:62;;44920:1;44917;44910:12;44862:62;44810:120;:::o;44936:122::-;45009:24;45027:5;45009:24;:::i;:::-;45002:5;44999:35;44989:63;;45048:1;45045;45038:12;44989:63;44936:122;:::o

Swarm Source

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