ETH Price: $2,439.93 (+0.11%)

Token

Cryptorank (CRK)

Overview

Max Total Supply

0 CRK

Holders

1,452

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 CRK
0x56f32f0d96e9e3dfb129e4ea5931bdebdf21e5bb
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information

Contract Source Code Verified (Exact Match)

Contract Name:
Cryptorank

Compiler Version
v0.8.12+commit.f00d7308

Optimization Enabled:
Yes with 3 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at optimistic.etherscan.io on 2024-03-21
*/

/**
 *Submitted for verification at polygonscan.com on 2024-03-07
*/

// Sources flattened with hardhat v2.21.0 https://hardhat.org

// SPDX-License-Identifier: MIT AND Unlicense

// File @openzeppelin/contracts/utils/[email protected]

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Context.sol)

pragma solidity ^0.8.0;

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

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


// File @openzeppelin/contracts/access/[email protected]

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (access/Ownable.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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


// File @openzeppelin/contracts/utils/introspection/[email protected]

// Original license: SPDX_License_Identifier: MIT
// 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/token/ERC721/[email protected]

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

    /**
     * @dev Transfers `tokenId` token from `from` to `to`.
     *
     * WARNING: Note that the caller is responsible to confirm that the recipient is capable of receiving ERC721
     * or else they may be permanently lost. Usage of {safeTransferFrom} prevents loss, though the caller must
     * understand this adds an external call which potentially creates a reentrancy vulnerability.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     * - If the caller is not `from`, it must be approved to move this token by either {approve} or {setApprovalForAll}.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(address from, address to, uint256 tokenId) external;

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

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

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

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


// File @openzeppelin/contracts/token/ERC721/extensions/[email protected]

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {
    /**
     * @dev Returns the token collection name.
     */
    function name() external view returns (string memory);

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

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


// File @openzeppelin/contracts/token/ERC721/[email protected]

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v4.6.0) (token/ERC721/IERC721Receiver.sol)

pragma solidity ^0.8.0;

/**
 * @title ERC721 token receiver interface
 * @dev Interface for any contract that wants to support safeTransfers
 * from ERC721 asset contracts.
 */
interface IERC721Receiver {
    /**
     * @dev Whenever an {IERC721} `tokenId` token is transferred to this contract via {IERC721-safeTransferFrom}
     * by `operator` from `from`, this function is called.
     *
     * It must return its Solidity selector to confirm the token transfer.
     * If any other value is returned or the interface is not implemented by the recipient, the transfer will be reverted.
     *
     * The selector can be obtained in Solidity with `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}


// File @openzeppelin/contracts/utils/[email protected]

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.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
     *
     * Furthermore, `isContract` will also return true if the target contract within
     * the same transaction is already scheduled for destruction by `SELFDESTRUCT`,
     * which only has an effect at the end of a transaction.
     * ====
     *
     * [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://consensys.net/diligence/blog/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.8.0/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/[email protected]

// Original license: SPDX_License_Identifier: MIT
// 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/utils/math/[email protected]

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/math/Math.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

            // Make sure the result is less than 2^256. Also prevents denominator == 0.
            require(denominator > prod1, "Math: mulDiv overflow");

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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


// File @openzeppelin/contracts/utils/math/[email protected]

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v4.8.0) (utils/math/SignedMath.sol)

pragma solidity ^0.8.0;

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

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

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

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


// File @openzeppelin/contracts/utils/[email protected]

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (utils/Strings.sol)

pragma solidity ^0.8.0;


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

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

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

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

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

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

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


// File @openzeppelin/contracts/token/ERC721/[email protected]

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;







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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: address zero is not a valid owner");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _ownerOf(tokenId);
        require(owner != address(0), "ERC721: invalid token ID");
        return owner;
    }

    /**
     * @dev See {IERC721Metadata-name}.
     */
    function name() public view virtual override returns (string memory) {
        return _name;
    }

    /**
     * @dev See {IERC721Metadata-symbol}.
     */
    function symbol() public view virtual override returns (string memory) {
        return _symbol;
    }

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        _requireMinted(tokenId);

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

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

    /**
     * @dev See {IERC721-approve}.
     */
    function approve(address to, uint256 tokenId) public virtual override {
        address owner = ERC721.ownerOf(tokenId);
        require(to != owner, "ERC721: approval to current owner");

        require(
            _msgSender() == owner || isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not token owner or approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        _requireMinted(tokenId);

        return _tokenApprovals[tokenId];
    }

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

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

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(address from, address to, uint256 tokenId) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved");

        _transfer(from, to, tokenId);
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId) public virtual override {
        safeTransferFrom(from, to, tokenId, "");
    }

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(address from, address to, uint256 tokenId, bytes memory data) public virtual override {
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: caller is not token owner or approved");
        _safeTransfer(from, to, tokenId, data);
    }

    /**
     * @dev Safely transfers `tokenId` token from `from` to `to`, checking first that contract recipients
     * are aware of the ERC721 protocol to prevent tokens from being forever locked.
     *
     * `data` is additional data, it has no specified format and it is sent in call to `to`.
     *
     * This internal function is equivalent to {safeTransferFrom}, and can be used to e.g.
     * implement alternative mechanisms to perform token transfer, such as signature-based.
     *
     * Requirements:
     *
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     * - `tokenId` token must exist and be owned by `from`.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeTransfer(address from, address to, uint256 tokenId, bytes memory data) internal virtual {
        _transfer(from, to, tokenId);
        require(_checkOnERC721Received(from, to, tokenId, data), "ERC721: transfer to non ERC721Receiver implementer");
    }

    /**
     * @dev Returns the owner of the `tokenId`. Does NOT revert if token doesn't exist
     */
    function _ownerOf(uint256 tokenId) internal view virtual returns (address) {
        return _owners[tokenId];
    }

    /**
     * @dev Returns whether `tokenId` exists.
     *
     * Tokens can be managed by their owner or approved accounts via {approve} or {setApprovalForAll}.
     *
     * Tokens start existing when they are minted (`_mint`),
     * and stop existing when they are burned (`_burn`).
     */
    function _exists(uint256 tokenId) internal view virtual returns (bool) {
        return _ownerOf(tokenId) != address(0);
    }

    /**
     * @dev Returns whether `spender` is allowed to manage `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _isApprovedOrOwner(address spender, uint256 tokenId) internal view virtual returns (bool) {
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || isApprovedForAll(owner, spender) || getApproved(tokenId) == spender);
    }

    /**
     * @dev Safely mints `tokenId` and transfers it to `to`.
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - If `to` refers to a smart contract, it must implement {IERC721Receiver-onERC721Received}, which is called upon a safe transfer.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(address to, uint256 tokenId) internal virtual {
        _safeMint(to, tokenId, "");
    }

    /**
     * @dev Same as {xref-ERC721-_safeMint-address-uint256-}[`_safeMint`], with an additional `data` parameter which is
     * forwarded in {IERC721Receiver-onERC721Received} to contract recipients.
     */
    function _safeMint(address to, uint256 tokenId, bytes memory data) internal virtual {
        _mint(to, tokenId);
        require(
            _checkOnERC721Received(address(0), to, tokenId, data),
            "ERC721: transfer to non ERC721Receiver implementer"
        );
    }

    /**
     * @dev Mints `tokenId` and transfers it to `to`.
     *
     * WARNING: Usage of this method is discouraged, use {_safeMint} whenever possible
     *
     * Requirements:
     *
     * - `tokenId` must not exist.
     * - `to` cannot be the zero address.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 tokenId) internal virtual {
        require(to != address(0), "ERC721: mint to the zero address");
        require(!_exists(tokenId), "ERC721: token already minted");

        _beforeTokenTransfer(address(0), to, tokenId, 1);

        // Check that tokenId was not minted by `_beforeTokenTransfer` hook
        require(!_exists(tokenId), "ERC721: token already minted");

        unchecked {
            // Will not overflow unless all 2**256 token ids are minted to the same owner.
            // Given that tokens are minted one by one, it is impossible in practice that
            // this ever happens. Might change if we allow batch minting.
            // The ERC fails to describe this case.
            _balances[to] += 1;
        }

        _owners[tokenId] = to;

        emit Transfer(address(0), to, tokenId);

        _afterTokenTransfer(address(0), to, tokenId, 1);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     * This is an internal function that does not check if the sender is authorized to operate on the token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId) internal virtual {
        address owner = ERC721.ownerOf(tokenId);

        _beforeTokenTransfer(owner, address(0), tokenId, 1);

        // Update ownership in case tokenId was transferred by `_beforeTokenTransfer` hook
        owner = ERC721.ownerOf(tokenId);

        // Clear approvals
        delete _tokenApprovals[tokenId];

        unchecked {
            // Cannot overflow, as that would require more tokens to be burned/transferred
            // out than the owner initially received through minting and transferring in.
            _balances[owner] -= 1;
        }
        delete _owners[tokenId];

        emit Transfer(owner, address(0), tokenId);

        _afterTokenTransfer(owner, address(0), tokenId, 1);
    }

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(address from, address to, uint256 tokenId) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId, 1);

        // Check that tokenId was not transferred by `_beforeTokenTransfer` hook
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer from incorrect owner");

        // Clear approvals from the previous owner
        delete _tokenApprovals[tokenId];

        unchecked {
            // `_balances[from]` cannot overflow for the same reason as described in `_burn`:
            // `from`'s balance is the number of token held, which is at least one before the current
            // transfer.
            // `_balances[to]` could overflow in the conditions described in `_mint`. That would require
            // all 2**256 token ids to be minted, which in practice is impossible.
            _balances[from] -= 1;
            _balances[to] += 1;
        }
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId, 1);
    }

    /**
     * @dev Approve `to` to operate on `tokenId`
     *
     * Emits an {Approval} event.
     */
    function _approve(address to, uint256 tokenId) internal virtual {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId);
    }

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

    /**
     * @dev Reverts if the `tokenId` has not been minted yet.
     */
    function _requireMinted(uint256 tokenId) internal view virtual {
        require(_exists(tokenId), "ERC721: invalid token ID");
    }

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target address.
     * The call is not executed if the target address is not a contract.
     *
     * @param from address representing the previous owner of the given token ID
     * @param to target address that will receive the tokens
     * @param tokenId uint256 ID of the token to be transferred
     * @param data bytes optional data to send along with the call
     * @return bool whether the call correctly returned the expected magic value
     */
    function _checkOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory data
    ) private returns (bool) {
        if (to.isContract()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, data) returns (bytes4 retval) {
                return retval == IERC721Receiver.onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    /// @solidity memory-safe-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting and burning. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens will be transferred to `to`.
     * - When `from` is zero, the tokens will be minted for `to`.
     * - When `to` is zero, ``from``'s tokens will be burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}

    /**
     * @dev Hook that is called after any token transfer. This includes minting and burning. If {ERC721Consecutive} is
     * used, the hook may be called as part of a consecutive (batch) mint, as indicated by `batchSize` greater than 1.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s tokens were transferred to `to`.
     * - When `from` is zero, the tokens were minted for `to`.
     * - When `to` is zero, ``from``'s tokens were burned.
     * - `from` and `to` are never both zero.
     * - `batchSize` is non-zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(address from, address to, uint256 firstTokenId, uint256 batchSize) internal virtual {}

    /**
     * @dev Unsafe write access to the balances, used by extensions that "mint" tokens using an {ownerOf} override.
     *
     * WARNING: Anyone calling this MUST ensure that the balances remain consistent with the ownership. The invariant
     * being that for any address `a` the value returned by `balanceOf(a)` must be equal to the number of tokens such
     * that `ownerOf(tokenId)` is `a`.
     */
    // solhint-disable-next-line func-name-mixedcase
    function __unsafe_increaseBalance(address account, uint256 amount) internal {
        _balances[account] += amount;
    }
}


// File contracts/token/onft721/interfaces/IONFT721Core.sol

// Original license: SPDX_License_Identifier: MIT

pragma solidity >=0.5.0;

/**
 * @dev Interface of the ONFT Core standard
 */
interface IONFT721Core is IERC165 {
    /**
     * @dev Emitted when `_tokenIds[]` are moved from the `_sender` to (`_dstChainId`, `_toAddress`)
     * `_nonce` is the outbound nonce from
     */
    event SendToChain(uint16 indexed _dstChainId, address indexed _from, bytes indexed _toAddress, uint[] _tokenIds);
    event ReceiveFromChain(uint16 indexed _srcChainId, bytes indexed _srcAddress, address indexed _toAddress, uint[] _tokenIds);
    event SetMinGasToTransferAndStore(uint _minGasToTransferAndStore);
    event SetDstChainIdToTransferGas(uint16 _dstChainId, uint _dstChainIdToTransferGas);
    event SetDstChainIdToBatchLimit(uint16 _dstChainId, uint _dstChainIdToBatchLimit);

    /**
     * @dev Emitted when `_payload` was received from lz, but not enough gas to deliver all tokenIds
     */
    event CreditStored(bytes32 _hashedPayload, bytes _payload);
    /**
     * @dev Emitted when `_hashedPayload` has been completely delivered
     */
    event CreditCleared(bytes32 _hashedPayload);

    /**
     * @dev send token `_tokenId` to (`_dstChainId`, `_toAddress`) from `_from`
     * `_toAddress` can be any size depending on the `dstChainId`.
     * `_zroPaymentAddress` set to address(0x0) if not paying in ZRO (LayerZero Token)
     * `_adapterParams` is a flexible bytes array to indicate messaging adapter services
     */
    function sendFrom(
        address _from,
        uint16 _dstChainId,
        bytes calldata _toAddress,
        uint _tokenId,
        address payable _refundAddress,
        address _zroPaymentAddress,
        bytes calldata _adapterParams
    ) external payable;

    /**
     * @dev send tokens `_tokenIds[]` to (`_dstChainId`, `_toAddress`) from `_from`
     * `_toAddress` can be any size depending on the `dstChainId`.
     * `_zroPaymentAddress` set to address(0x0) if not paying in ZRO (LayerZero Token)
     * `_adapterParams` is a flexible bytes array to indicate messaging adapter services
     */
    function sendBatchFrom(
        address _from,
        uint16 _dstChainId,
        bytes calldata _toAddress,
        uint[] calldata _tokenIds,
        address payable _refundAddress,
        address _zroPaymentAddress,
        bytes calldata _adapterParams
    ) external payable;

    /**
     * @dev estimate send token `_tokenId` to (`_dstChainId`, `_toAddress`)
     * _dstChainId - L0 defined chain id to send tokens too
     * _toAddress - dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain
     * _tokenId - token Id to transfer
     * _useZro - indicates to use zro to pay L0 fees
     * _adapterParams - flexible bytes array to indicate messaging adapter services in L0
     */
    function estimateSendFee(
        uint16 _dstChainId,
        bytes calldata _toAddress,
        uint _tokenId,
        bool _useZro,
        bytes calldata _adapterParams
    ) external view returns (uint nativeFee, uint zroFee);

    /**
     * @dev estimate send token `_tokenId` to (`_dstChainId`, `_toAddress`)
     * _dstChainId - L0 defined chain id to send tokens too
     * _toAddress - dynamic bytes array which contains the address to whom you are sending tokens to on the dstChain
     * _tokenIds[] - token Ids to transfer
     * _useZro - indicates to use zro to pay L0 fees
     * _adapterParams - flexible bytes array to indicate messaging adapter services in L0
     */
    function estimateSendBatchFee(
        uint16 _dstChainId,
        bytes calldata _toAddress,
        uint[] calldata _tokenIds,
        bool _useZro,
        bytes calldata _adapterParams
    ) external view returns (uint nativeFee, uint zroFee);
}


// File contracts/token/onft721/interfaces/IONFT721.sol

// Original license: SPDX_License_Identifier: MIT

pragma solidity >=0.5.0;


/**
 * @dev Interface of the ONFT standard
 */
interface IONFT721 is IONFT721Core, IERC721 {

}


// File @openzeppelin/contracts/security/[email protected]

// Original license: SPDX_License_Identifier: MIT
// OpenZeppelin Contracts (last updated v4.9.0) (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

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

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

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

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

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


// File contracts/libraries/ExcessivelySafeCall.sol

// Original license: SPDX_License_Identifier: MIT
pragma solidity >=0.7.6;

library ExcessivelySafeCall {
    uint constant LOW_28_MASK = 0x00000000ffffffffffffffffffffffffffffffffffffffffffffffffffffffff;

    /// @notice Use when you _really_ really _really_ don't trust the called
    /// contract. This prevents the called contract from causing reversion of
    /// the caller in as many ways as we can.
    /// @dev The main difference between this and a solidity low-level call is
    /// that we limit the number of bytes that the callee can cause to be
    /// copied to caller memory. This prevents stupid things like malicious
    /// contracts returning 10,000,000 bytes causing a local OOG when copying
    /// to memory.
    /// @param _target The address to call
    /// @param _gas The amount of gas to forward to the remote contract
    /// @param _maxCopy The maximum number of bytes of returndata to copy
    /// to memory.
    /// @param _calldata The data to send to the remote contract
    /// @return success and returndata, as `.call()`. Returndata is capped to
    /// `_maxCopy` bytes.
    function excessivelySafeCall(
        address _target,
        uint _gas,
        uint16 _maxCopy,
        bytes memory _calldata
    ) internal returns (bool, bytes memory) {
        // set up for assembly call
        uint _toCopy;
        bool _success;
        bytes memory _returnData = new bytes(_maxCopy);
        // dispatch message to recipient
        // by assembly calling "handle" function
        // we call via assembly to avoid memcopying a very large returndata
        // returned by a malicious contract
        assembly {
            _success := call(
                _gas, // gas
                _target, // recipient
                0, // ether value
                add(_calldata, 0x20), // inloc
                mload(_calldata), // inlen
                0, // outloc
                0 // outlen
            )
            // limit our copy to 256 bytes
            _toCopy := returndatasize()
            if gt(_toCopy, _maxCopy) {
                _toCopy := _maxCopy
            }
            // Store the length of the copied bytes
            mstore(_returnData, _toCopy)
            // copy the bytes from returndata[0:_toCopy]
            returndatacopy(add(_returnData, 0x20), 0, _toCopy)
        }
        return (_success, _returnData);
    }

    /// @notice Use when you _really_ really _really_ don't trust the called
    /// contract. This prevents the called contract from causing reversion of
    /// the caller in as many ways as we can.
    /// @dev The main difference between this and a solidity low-level call is
    /// that we limit the number of bytes that the callee can cause to be
    /// copied to caller memory. This prevents stupid things like malicious
    /// contracts returning 10,000,000 bytes causing a local OOG when copying
    /// to memory.
    /// @param _target The address to call
    /// @param _gas The amount of gas to forward to the remote contract
    /// @param _maxCopy The maximum number of bytes of returndata to copy
    /// to memory.
    /// @param _calldata The data to send to the remote contract
    /// @return success and returndata, as `.call()`. Returndata is capped to
    /// `_maxCopy` bytes.
    function excessivelySafeStaticCall(
        address _target,
        uint _gas,
        uint16 _maxCopy,
        bytes memory _calldata
    ) internal view returns (bool, bytes memory) {
        // set up for assembly call
        uint _toCopy;
        bool _success;
        bytes memory _returnData = new bytes(_maxCopy);
        // dispatch message to recipient
        // by assembly calling "handle" function
        // we call via assembly to avoid memcopying a very large returndata
        // returned by a malicious contract
        assembly {
            _success := staticcall(
                _gas, // gas
                _target, // recipient
                add(_calldata, 0x20), // inloc
                mload(_calldata), // inlen
                0, // outloc
                0 // outlen
            )
            // limit our copy to 256 bytes
            _toCopy := returndatasize()
            if gt(_toCopy, _maxCopy) {
                _toCopy := _maxCopy
            }
            // Store the length of the copied bytes
            mstore(_returnData, _toCopy)
            // copy the bytes from returndata[0:_toCopy]
            returndatacopy(add(_returnData, 0x20), 0, _toCopy)
        }
        return (_success, _returnData);
    }

    /**
     * @notice Swaps function selectors in encoded contract calls
     * @dev Allows reuse of encoded calldata for functions with identical
     * argument types but different names. It simply swaps out the first 4 bytes
     * for the new selector. This function modifies memory in place, and should
     * only be used with caution.
     * @param _newSelector The new 4-byte selector
     * @param _buf The encoded contract args
     */
    function swapSelector(bytes4 _newSelector, bytes memory _buf) internal pure {
        require(_buf.length >= 4);
        uint _mask = LOW_28_MASK;
        assembly {
            // load the first word of
            let _word := mload(add(_buf, 0x20))
            // mask out the top 4 bytes
            // /x
            _word := and(_word, _mask)
            _word := or(_newSelector, _word)
            mstore(add(_buf, 0x20), _word)
        }
    }
}


// File contracts/libraries/BytesLib.sol

// Original license: SPDX_License_Identifier: Unlicense
/*
 * @title Solidity Bytes Arrays Utils
 * @author Gonçalo Sá <[email protected]>
 *
 * @dev Bytes tightly packed arrays utility library for ethereum contracts written in Solidity.
 *      The library lets you concatenate, slice and type cast bytes arrays both in memory and storage.
 */
pragma solidity >=0.8.0 <0.9.0;

library BytesLib {
    function concat(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bytes memory) {
        bytes memory tempBytes;

        assembly {
            // Get a location of some free memory and store it in tempBytes as
            // Solidity does for memory variables.
            tempBytes := mload(0x40)

            // Store the length of the first bytes array at the beginning of
            // the memory for tempBytes.
            let length := mload(_preBytes)
            mstore(tempBytes, length)

            // Maintain a memory counter for the current write location in the
            // temp bytes array by adding the 32 bytes for the array length to
            // the starting location.
            let mc := add(tempBytes, 0x20)
            // Stop copying when the memory counter reaches the length of the
            // first bytes array.
            let end := add(mc, length)

            for {
                // Initialize a copy counter to the start of the _preBytes data,
                // 32 bytes into its memory.
                let cc := add(_preBytes, 0x20)
            } lt(mc, end) {
                // Increase both counters by 32 bytes each iteration.
                mc := add(mc, 0x20)
                cc := add(cc, 0x20)
            } {
                // Write the _preBytes data into the tempBytes memory 32 bytes
                // at a time.
                mstore(mc, mload(cc))
            }

            // Add the length of _postBytes to the current length of tempBytes
            // and store it as the new length in the first 32 bytes of the
            // tempBytes memory.
            length := mload(_postBytes)
            mstore(tempBytes, add(length, mload(tempBytes)))

            // Move the memory counter back from a multiple of 0x20 to the
            // actual end of the _preBytes data.
            mc := end
            // Stop copying when the memory counter reaches the new combined
            // length of the arrays.
            end := add(mc, length)

            for {
                let cc := add(_postBytes, 0x20)
            } lt(mc, end) {
                mc := add(mc, 0x20)
                cc := add(cc, 0x20)
            } {
                mstore(mc, mload(cc))
            }

            // Update the free-memory pointer by padding our last write location
            // to 32 bytes: add 31 bytes to the end of tempBytes to move to the
            // next 32 byte block, then round down to the nearest multiple of
            // 32. If the sum of the length of the two arrays is zero then add
            // one before rounding down to leave a blank 32 bytes (the length block with 0).
            mstore(
                0x40,
                and(
                    add(add(end, iszero(add(length, mload(_preBytes)))), 31),
                    not(31) // Round down to the nearest 32 bytes.
                )
            )
        }

        return tempBytes;
    }

    function concatStorage(bytes storage _preBytes, bytes memory _postBytes) internal {
        assembly {
            // Read the first 32 bytes of _preBytes storage, which is the length
            // of the array. (We don't need to use the offset into the slot
            // because arrays use the entire slot.)
            let fslot := sload(_preBytes.slot)
            // Arrays of 31 bytes or less have an even value in their slot,
            // while longer arrays have an odd value. The actual length is
            // the slot divided by two for odd values, and the lowest order
            // byte divided by two for even values.
            // If the slot is even, bitwise and the slot with 255 and divide by
            // two to get the length. If the slot is odd, bitwise and the slot
            // with -1 and divide by two.
            let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
            let mlength := mload(_postBytes)
            let newlength := add(slength, mlength)
            // slength can contain both the length and contents of the array
            // if length < 32 bytes so let's prepare for that
            // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
            switch add(lt(slength, 32), lt(newlength, 32))
            case 2 {
                // Since the new array still fits in the slot, we just need to
                // update the contents of the slot.
                // uint256(bytes_storage) = uint256(bytes_storage) + uint256(bytes_memory) + new_length
                sstore(
                    _preBytes.slot,
                    // all the modifications to the slot are inside this
                    // next block
                    add(
                        // we can just add to the slot contents because the
                        // bytes we want to change are the LSBs
                        fslot,
                        add(
                            mul(
                                div(
                                    // load the bytes from memory
                                    mload(add(_postBytes, 0x20)),
                                    // zero all bytes to the right
                                    exp(0x100, sub(32, mlength))
                                ),
                                // and now shift left the number of bytes to
                                // leave space for the length in the slot
                                exp(0x100, sub(32, newlength))
                            ),
                            // increase length by the double of the memory
                            // bytes length
                            mul(mlength, 2)
                        )
                    )
                )
            }
            case 1 {
                // The stored value fits in the slot, but the combined value
                // will exceed it.
                // get the keccak hash to get the contents of the array
                mstore(0x0, _preBytes.slot)
                let sc := add(keccak256(0x0, 0x20), div(slength, 32))

                // save new length
                sstore(_preBytes.slot, add(mul(newlength, 2), 1))

                // The contents of the _postBytes array start 32 bytes into
                // the structure. Our first read should obtain the `submod`
                // bytes that can fit into the unused space in the last word
                // of the stored array. To get this, we read 32 bytes starting
                // from `submod`, so the data we read overlaps with the array
                // contents by `submod` bytes. Masking the lowest-order
                // `submod` bytes allows us to add that value directly to the
                // stored value.

                let submod := sub(32, slength)
                let mc := add(_postBytes, submod)
                let end := add(_postBytes, mlength)
                let mask := sub(exp(0x100, submod), 1)

                sstore(sc, add(and(fslot, 0xffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00), and(mload(mc), mask)))

                for {
                    mc := add(mc, 0x20)
                    sc := add(sc, 1)
                } lt(mc, end) {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } {
                    sstore(sc, mload(mc))
                }

                mask := exp(0x100, sub(mc, end))

                sstore(sc, mul(div(mload(mc), mask), mask))
            }
            default {
                // get the keccak hash to get the contents of the array
                mstore(0x0, _preBytes.slot)
                // Start copying to the last used word of the stored array.
                let sc := add(keccak256(0x0, 0x20), div(slength, 32))

                // save new length
                sstore(_preBytes.slot, add(mul(newlength, 2), 1))

                // Copy over the first `submod` bytes of the new data as in
                // case 1 above.
                let slengthmod := mod(slength, 32)
                let mlengthmod := mod(mlength, 32)
                let submod := sub(32, slengthmod)
                let mc := add(_postBytes, submod)
                let end := add(_postBytes, mlength)
                let mask := sub(exp(0x100, submod), 1)

                sstore(sc, add(sload(sc), and(mload(mc), mask)))

                for {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } lt(mc, end) {
                    sc := add(sc, 1)
                    mc := add(mc, 0x20)
                } {
                    sstore(sc, mload(mc))
                }

                mask := exp(0x100, sub(mc, end))

                sstore(sc, mul(div(mload(mc), mask), mask))
            }
        }
    }

    function slice(
        bytes memory _bytes,
        uint _start,
        uint _length
    ) internal pure returns (bytes memory) {
        require(_length + 31 >= _length, "slice_overflow");
        require(_bytes.length >= _start + _length, "slice_outOfBounds");

        bytes memory tempBytes;

        assembly {
            switch iszero(_length)
            case 0 {
                // Get a location of some free memory and store it in tempBytes as
                // Solidity does for memory variables.
                tempBytes := mload(0x40)

                // The first word of the slice result is potentially a partial
                // word read from the original array. To read it, we calculate
                // the length of that partial word and start copying that many
                // bytes into the array. The first word we copy will start with
                // data we don't care about, but the last `lengthmod` bytes will
                // land at the beginning of the contents of the new array. When
                // we're done copying, we overwrite the full first word with
                // the actual length of the slice.
                let lengthmod := and(_length, 31)

                // The multiplication in the next line is necessary
                // because when slicing multiples of 32 bytes (lengthmod == 0)
                // the following copy loop was copying the origin's length
                // and then ending prematurely not copying everything it should.
                let mc := add(add(tempBytes, lengthmod), mul(0x20, iszero(lengthmod)))
                let end := add(mc, _length)

                for {
                    // The multiplication in the next line has the same exact purpose
                    // as the one above.
                    let cc := add(add(add(_bytes, lengthmod), mul(0x20, iszero(lengthmod))), _start)
                } lt(mc, end) {
                    mc := add(mc, 0x20)
                    cc := add(cc, 0x20)
                } {
                    mstore(mc, mload(cc))
                }

                mstore(tempBytes, _length)

                //update free-memory pointer
                //allocating the array padded to 32 bytes like the compiler does now
                mstore(0x40, and(add(mc, 31), not(31)))
            }
            //if we want a zero-length slice let's just return a zero-length array
            default {
                tempBytes := mload(0x40)
                //zero out the 32 bytes slice we are about to return
                //we need to do it because Solidity does not garbage collect
                mstore(tempBytes, 0)

                mstore(0x40, add(tempBytes, 0x20))
            }
        }

        return tempBytes;
    }

    function toAddress(bytes memory _bytes, uint _start) internal pure returns (address) {
        require(_bytes.length >= _start + 20, "toAddress_outOfBounds");
        address tempAddress;

        assembly {
            tempAddress := div(mload(add(add(_bytes, 0x20), _start)), 0x1000000000000000000000000)
        }

        return tempAddress;
    }

    function toUint8(bytes memory _bytes, uint _start) internal pure returns (uint8) {
        require(_bytes.length >= _start + 1, "toUint8_outOfBounds");
        uint8 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x1), _start))
        }

        return tempUint;
    }

    function toUint16(bytes memory _bytes, uint _start) internal pure returns (uint16) {
        require(_bytes.length >= _start + 2, "toUint16_outOfBounds");
        uint16 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x2), _start))
        }

        return tempUint;
    }

    function toUint32(bytes memory _bytes, uint _start) internal pure returns (uint32) {
        require(_bytes.length >= _start + 4, "toUint32_outOfBounds");
        uint32 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x4), _start))
        }

        return tempUint;
    }

    function toUint64(bytes memory _bytes, uint _start) internal pure returns (uint64) {
        require(_bytes.length >= _start + 8, "toUint64_outOfBounds");
        uint64 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x8), _start))
        }

        return tempUint;
    }

    function toUint96(bytes memory _bytes, uint _start) internal pure returns (uint96) {
        require(_bytes.length >= _start + 12, "toUint96_outOfBounds");
        uint96 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0xc), _start))
        }

        return tempUint;
    }

    function toUint128(bytes memory _bytes, uint _start) internal pure returns (uint128) {
        require(_bytes.length >= _start + 16, "toUint128_outOfBounds");
        uint128 tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x10), _start))
        }

        return tempUint;
    }

    function toUint256(bytes memory _bytes, uint _start) internal pure returns (uint) {
        require(_bytes.length >= _start + 32, "toUint256_outOfBounds");
        uint tempUint;

        assembly {
            tempUint := mload(add(add(_bytes, 0x20), _start))
        }

        return tempUint;
    }

    function toBytes32(bytes memory _bytes, uint _start) internal pure returns (bytes32) {
        require(_bytes.length >= _start + 32, "toBytes32_outOfBounds");
        bytes32 tempBytes32;

        assembly {
            tempBytes32 := mload(add(add(_bytes, 0x20), _start))
        }

        return tempBytes32;
    }

    function equal(bytes memory _preBytes, bytes memory _postBytes) internal pure returns (bool) {
        bool success = true;

        assembly {
            let length := mload(_preBytes)

            // if lengths don't match the arrays are not equal
            switch eq(length, mload(_postBytes))
            case 1 {
                // cb is a circuit breaker in the for loop since there's
                //  no said feature for inline assembly loops
                // cb = 1 - don't breaker
                // cb = 0 - break
                let cb := 1

                let mc := add(_preBytes, 0x20)
                let end := add(mc, length)

                for {
                    let cc := add(_postBytes, 0x20)
                    // the next line is the loop condition:
                    // while(uint256(mc < end) + cb == 2)
                } eq(add(lt(mc, end), cb), 2) {
                    mc := add(mc, 0x20)
                    cc := add(cc, 0x20)
                } {
                    // if any of these checks fails then arrays are not equal
                    if iszero(eq(mload(mc), mload(cc))) {
                        // unsuccess:
                        success := 0
                        cb := 0
                    }
                }
            }
            default {
                // unsuccess:
                success := 0
            }
        }

        return success;
    }

    function equalStorage(bytes storage _preBytes, bytes memory _postBytes) internal view returns (bool) {
        bool success = true;

        assembly {
            // we know _preBytes_offset is 0
            let fslot := sload(_preBytes.slot)
            // Decode the length of the stored array like in concatStorage().
            let slength := div(and(fslot, sub(mul(0x100, iszero(and(fslot, 1))), 1)), 2)
            let mlength := mload(_postBytes)

            // if lengths don't match the arrays are not equal
            switch eq(slength, mlength)
            case 1 {
                // slength can contain both the length and contents of the array
                // if length < 32 bytes so let's prepare for that
                // v. http://solidity.readthedocs.io/en/latest/miscellaneous.html#layout-of-state-variables-in-storage
                if iszero(iszero(slength)) {
                    switch lt(slength, 32)
                    case 1 {
                        // blank the last byte which is the length
                        fslot := mul(div(fslot, 0x100), 0x100)

                        if iszero(eq(fslot, mload(add(_postBytes, 0x20)))) {
                            // unsuccess:
                            success := 0
                        }
                    }
                    default {
                        // cb is a circuit breaker in the for loop since there's
                        //  no said feature for inline assembly loops
                        // cb = 1 - don't breaker
                        // cb = 0 - break
                        let cb := 1

                        // get the keccak hash to get the contents of the array
                        mstore(0x0, _preBytes.slot)
                        let sc := keccak256(0x0, 0x20)

                        let mc := add(_postBytes, 0x20)
                        let end := add(mc, mlength)

                        // the next line is the loop condition:
                        // while(uint256(mc < end) + cb == 2)
                        for {

                        } eq(add(lt(mc, end), cb), 2) {
                            sc := add(sc, 1)
                            mc := add(mc, 0x20)
                        } {
                            if iszero(eq(sload(sc), mload(mc))) {
                                // unsuccess:
                                success := 0
                                cb := 0
                            }
                        }
                    }
                }
            }
            default {
                // unsuccess:
                success := 0
            }
        }

        return success;
    }
}


// File contracts/lzApp/interfaces/ILayerZeroUserApplicationConfig.sol

// Original license: SPDX_License_Identifier: MIT

pragma solidity >=0.5.0;

interface ILayerZeroUserApplicationConfig {
    // @notice set the configuration of the LayerZero messaging library of the specified version
    // @param _version - messaging library version
    // @param _chainId - the chainId for the pending config change
    // @param _configType - type of configuration. every messaging library has its own convention.
    // @param _config - configuration in the bytes. can encode arbitrary content.
    function setConfig(
        uint16 _version,
        uint16 _chainId,
        uint _configType,
        bytes calldata _config
    ) external;

    // @notice set the send() LayerZero messaging library version to _version
    // @param _version - new messaging library version
    function setSendVersion(uint16 _version) external;

    // @notice set the lzReceive() LayerZero messaging library version to _version
    // @param _version - new messaging library version
    function setReceiveVersion(uint16 _version) external;

    // @notice Only when the UA needs to resume the message flow in blocking mode and clear the stored payload
    // @param _srcChainId - the chainId of the source chain
    // @param _srcAddress - the contract address of the source contract at the source chain
    function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external;
}


// File contracts/lzApp/interfaces/ILayerZeroEndpoint.sol

// Original license: SPDX_License_Identifier: MIT

pragma solidity >=0.5.0;

interface ILayerZeroEndpoint is ILayerZeroUserApplicationConfig {
    // @notice send a LayerZero message to the specified address at a LayerZero endpoint.
    // @param _dstChainId - the destination chain identifier
    // @param _destination - the address on destination chain (in bytes). address length/format may vary by chains
    // @param _payload - a custom bytes payload to send to the destination contract
    // @param _refundAddress - if the source transaction is cheaper than the amount of value passed, refund the additional amount to this address
    // @param _zroPaymentAddress - the address of the ZRO token holder who would pay for the transaction
    // @param _adapterParams - parameters for custom functionality. e.g. receive airdropped native gas from the relayer on destination
    function send(
        uint16 _dstChainId,
        bytes calldata _destination,
        bytes calldata _payload,
        address payable _refundAddress,
        address _zroPaymentAddress,
        bytes calldata _adapterParams
    ) external payable;

    // @notice used by the messaging library to publish verified payload
    // @param _srcChainId - the source chain identifier
    // @param _srcAddress - the source contract (as bytes) at the source chain
    // @param _dstAddress - the address on destination chain
    // @param _nonce - the unbound message ordering nonce
    // @param _gasLimit - the gas limit for external contract execution
    // @param _payload - verified payload to send to the destination contract
    function receivePayload(
        uint16 _srcChainId,
        bytes calldata _srcAddress,
        address _dstAddress,
        uint64 _nonce,
        uint _gasLimit,
        bytes calldata _payload
    ) external;

    // @notice get the inboundNonce of a lzApp from a source chain which could be EVM or non-EVM chain
    // @param _srcChainId - the source chain identifier
    // @param _srcAddress - the source chain contract address
    function getInboundNonce(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (uint64);

    // @notice get the outboundNonce from this source chain which, consequently, is always an EVM
    // @param _srcAddress - the source chain contract address
    function getOutboundNonce(uint16 _dstChainId, address _srcAddress) external view returns (uint64);

    // @notice gets a quote in source native gas, for the amount that send() requires to pay for message delivery
    // @param _dstChainId - the destination chain identifier
    // @param _userApplication - the user app address on this EVM chain
    // @param _payload - the custom message to send over LayerZero
    // @param _payInZRO - if false, user app pays the protocol fee in native token
    // @param _adapterParam - parameters for the adapter service, e.g. send some dust native token to dstChain
    function estimateFees(
        uint16 _dstChainId,
        address _userApplication,
        bytes calldata _payload,
        bool _payInZRO,
        bytes calldata _adapterParam
    ) external view returns (uint nativeFee, uint zroFee);

    // @notice get this Endpoint's immutable source identifier
    function getChainId() external view returns (uint16);

    // @notice the interface to retry failed message on this Endpoint destination
    // @param _srcChainId - the source chain identifier
    // @param _srcAddress - the source chain contract address
    // @param _payload - the payload to be retried
    function retryPayload(
        uint16 _srcChainId,
        bytes calldata _srcAddress,
        bytes calldata _payload
    ) external;

    // @notice query if any STORED payload (message blocking) at the endpoint.
    // @param _srcChainId - the source chain identifier
    // @param _srcAddress - the source chain contract address
    function hasStoredPayload(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool);

    // @notice query if the _libraryAddress is valid for sending msgs.
    // @param _userApplication - the user app address on this EVM chain
    function getSendLibraryAddress(address _userApplication) external view returns (address);

    // @notice query if the _libraryAddress is valid for receiving msgs.
    // @param _userApplication - the user app address on this EVM chain
    function getReceiveLibraryAddress(address _userApplication) external view returns (address);

    // @notice query if the non-reentrancy guard for send() is on
    // @return true if the guard is on. false otherwise
    function isSendingPayload() external view returns (bool);

    // @notice query if the non-reentrancy guard for receive() is on
    // @return true if the guard is on. false otherwise
    function isReceivingPayload() external view returns (bool);

    // @notice get the configuration of the LayerZero messaging library of the specified version
    // @param _version - messaging library version
    // @param _chainId - the chainId for the pending config change
    // @param _userApplication - the contract address of the user application
    // @param _configType - type of configuration. every messaging library has its own convention.
    function getConfig(
        uint16 _version,
        uint16 _chainId,
        address _userApplication,
        uint _configType
    ) external view returns (bytes memory);

    // @notice get the send() LayerZero messaging library version
    // @param _userApplication - the contract address of the user application
    function getSendVersion(address _userApplication) external view returns (uint16);

    // @notice get the lzReceive() LayerZero messaging library version
    // @param _userApplication - the contract address of the user application
    function getReceiveVersion(address _userApplication) external view returns (uint16);
}


// File contracts/lzApp/interfaces/ILayerZeroReceiver.sol

// Original license: SPDX_License_Identifier: MIT

pragma solidity >=0.5.0;

interface ILayerZeroReceiver {
    // @notice LayerZero endpoint will invoke this function to deliver the message on the destination
    // @param _srcChainId - the source endpoint identifier
    // @param _srcAddress - the source sending contract address from the source chain
    // @param _nonce - the ordered message nonce
    // @param _payload - the signed payload is the UA bytes has encoded to be sent
    function lzReceive(
        uint16 _srcChainId,
        bytes calldata _srcAddress,
        uint64 _nonce,
        bytes calldata _payload
    ) external;
}


// File contracts/lzApp/LzApp.sol

// Original license: SPDX_License_Identifier: MIT

pragma solidity ^0.8.0;





/*
 * a generic LzReceiver implementation
 */
abstract contract LzApp is Ownable, ILayerZeroReceiver, ILayerZeroUserApplicationConfig {
    using BytesLib for bytes;

    // ua can not send payload larger than this by default, but it can be changed by the ua owner
    uint public constant DEFAULT_PAYLOAD_SIZE_LIMIT = 10000;

    ILayerZeroEndpoint public immutable lzEndpoint;
    mapping(uint16 => bytes) public trustedRemoteLookup;
    mapping(uint16 => mapping(uint16 => uint)) public minDstGasLookup;
    mapping(uint16 => uint) public payloadSizeLimitLookup;
    address public precrime;

    event SetPrecrime(address precrime);
    event SetTrustedRemote(uint16 _remoteChainId, bytes _path);
    event SetTrustedRemoteAddress(uint16 _remoteChainId, bytes _remoteAddress);
    event SetMinDstGas(uint16 _dstChainId, uint16 _type, uint _minDstGas);

    constructor(address _endpoint) {
        lzEndpoint = ILayerZeroEndpoint(_endpoint);
    }

    function lzReceive(
        uint16 _srcChainId,
        bytes calldata _srcAddress,
        uint64 _nonce,
        bytes calldata _payload
    ) public virtual override {
        // lzReceive must be called by the endpoint for security
        require(_msgSender() == address(lzEndpoint), "LzApp: invalid endpoint caller");

        bytes memory trustedRemote = trustedRemoteLookup[_srcChainId];
        // if will still block the message pathway from (srcChainId, srcAddress). should not receive message from untrusted remote.
        require(
            _srcAddress.length == trustedRemote.length && trustedRemote.length > 0 && keccak256(_srcAddress) == keccak256(trustedRemote),
            "LzApp: invalid source sending contract"
        );

        _blockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);
    }

    // abstract function - the default behaviour of LayerZero is blocking. See: NonblockingLzApp if you dont need to enforce ordered messaging
    function _blockingLzReceive(
        uint16 _srcChainId,
        bytes memory _srcAddress,
        uint64 _nonce,
        bytes memory _payload
    ) internal virtual;

    function _lzSend(
        uint16 _dstChainId,
        bytes memory _payload,
        address payable _refundAddress,
        address _zroPaymentAddress,
        bytes memory _adapterParams,
        uint _nativeFee
    ) internal virtual {
        bytes memory trustedRemote = trustedRemoteLookup[_dstChainId];
        require(trustedRemote.length != 0, "LzApp: destination chain is not a trusted source");
        _checkPayloadSize(_dstChainId, _payload.length);
        lzEndpoint.send{value: _nativeFee}(_dstChainId, trustedRemote, _payload, _refundAddress, _zroPaymentAddress, _adapterParams);
    }

    function _checkGasLimit(
        uint16 _dstChainId,
        uint16 _type,
        bytes memory _adapterParams,
        uint _extraGas
    ) internal view virtual {
        uint providedGasLimit = _getGasLimit(_adapterParams);
        uint minGasLimit = minDstGasLookup[_dstChainId][_type];
        require(minGasLimit > 0, "LzApp: minGasLimit not set");
        require(providedGasLimit >= minGasLimit + _extraGas, "LzApp: gas limit is too low");
    }

    function _getGasLimit(bytes memory _adapterParams) internal pure virtual returns (uint gasLimit) {
        require(_adapterParams.length >= 34, "LzApp: invalid adapterParams");
        assembly {
            gasLimit := mload(add(_adapterParams, 34))
        }
    }

    function _checkPayloadSize(uint16 _dstChainId, uint _payloadSize) internal view virtual {
        uint payloadSizeLimit = payloadSizeLimitLookup[_dstChainId];
        if (payloadSizeLimit == 0) {
            // use default if not set
            payloadSizeLimit = DEFAULT_PAYLOAD_SIZE_LIMIT;
        }
        require(_payloadSize <= payloadSizeLimit, "LzApp: payload size is too large");
    }

    //---------------------------UserApplication config----------------------------------------
    function getConfig(
        uint16 _version,
        uint16 _chainId,
        address,
        uint _configType
    ) external view returns (bytes memory) {
        return lzEndpoint.getConfig(_version, _chainId, address(this), _configType);
    }

    // generic config for LayerZero user Application
    function setConfig(
        uint16 _version,
        uint16 _chainId,
        uint _configType,
        bytes calldata _config
    ) external override onlyOwner {
        lzEndpoint.setConfig(_version, _chainId, _configType, _config);
    }

    function setSendVersion(uint16 _version) external override onlyOwner {
        lzEndpoint.setSendVersion(_version);
    }

    function setReceiveVersion(uint16 _version) external override onlyOwner {
        lzEndpoint.setReceiveVersion(_version);
    }

    function forceResumeReceive(uint16 _srcChainId, bytes calldata _srcAddress) external override onlyOwner {
        lzEndpoint.forceResumeReceive(_srcChainId, _srcAddress);
    }

    // _path = abi.encodePacked(remoteAddress, localAddress)
    // this function set the trusted path for the cross-chain communication
    function setTrustedRemote(uint16 _remoteChainId, bytes calldata _path) external onlyOwner {
        trustedRemoteLookup[_remoteChainId] = _path;
        emit SetTrustedRemote(_remoteChainId, _path);
    }

    function setTrustedRemoteAddress(uint16 _remoteChainId, bytes calldata _remoteAddress) external onlyOwner {
        trustedRemoteLookup[_remoteChainId] = abi.encodePacked(_remoteAddress, address(this));
        emit SetTrustedRemoteAddress(_remoteChainId, _remoteAddress);
    }

    function getTrustedRemoteAddress(uint16 _remoteChainId) external view returns (bytes memory) {
        bytes memory path = trustedRemoteLookup[_remoteChainId];
        require(path.length != 0, "LzApp: no trusted path record");
        return path.slice(0, path.length - 20); // the last 20 bytes should be address(this)
    }

    function setPrecrime(address _precrime) external onlyOwner {
        precrime = _precrime;
        emit SetPrecrime(_precrime);
    }

    function setMinDstGas(
        uint16 _dstChainId,
        uint16 _packetType,
        uint _minGas
    ) external onlyOwner {
        minDstGasLookup[_dstChainId][_packetType] = _minGas;
        emit SetMinDstGas(_dstChainId, _packetType, _minGas);
    }

    // if the size is 0, it means default size limit
    function setPayloadSizeLimit(uint16 _dstChainId, uint _size) external onlyOwner {
        payloadSizeLimitLookup[_dstChainId] = _size;
    }

    //--------------------------- VIEW FUNCTION ----------------------------------------
    function isTrustedRemote(uint16 _srcChainId, bytes calldata _srcAddress) external view returns (bool) {
        bytes memory trustedSource = trustedRemoteLookup[_srcChainId];
        return keccak256(trustedSource) == keccak256(_srcAddress);
    }
}


// File contracts/lzApp/NonblockingLzApp.sol

// Original license: SPDX_License_Identifier: MIT

pragma solidity ^0.8.0;


/*
 * the default LayerZero messaging behaviour is blocking, i.e. any failed message will block the channel
 * this abstract class try-catch all fail messages and store locally for future retry. hence, non-blocking
 * NOTE: if the srcAddress is not configured properly, it will still block the message pathway from (srcChainId, srcAddress)
 */
abstract contract NonblockingLzApp is LzApp {
    using ExcessivelySafeCall for address;

    constructor(address _endpoint) LzApp(_endpoint) {}

    mapping(uint16 => mapping(bytes => mapping(uint64 => bytes32))) public failedMessages;

    event MessageFailed(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes _payload, bytes _reason);
    event RetryMessageSuccess(uint16 _srcChainId, bytes _srcAddress, uint64 _nonce, bytes32 _payloadHash);

    // overriding the virtual function in LzReceiver
    function _blockingLzReceive(
        uint16 _srcChainId,
        bytes memory _srcAddress,
        uint64 _nonce,
        bytes memory _payload
    ) internal virtual override {
        (bool success, bytes memory reason) = address(this).excessivelySafeCall(
            gasleft(),
            150,
            abi.encodeWithSelector(this.nonblockingLzReceive.selector, _srcChainId, _srcAddress, _nonce, _payload)
        );
        if (!success) {
            _storeFailedMessage(_srcChainId, _srcAddress, _nonce, _payload, reason);
        }
    }

    function _storeFailedMessage(
        uint16 _srcChainId,
        bytes memory _srcAddress,
        uint64 _nonce,
        bytes memory _payload,
        bytes memory _reason
    ) internal virtual {
        failedMessages[_srcChainId][_srcAddress][_nonce] = keccak256(_payload);
        emit MessageFailed(_srcChainId, _srcAddress, _nonce, _payload, _reason);
    }

    function nonblockingLzReceive(
        uint16 _srcChainId,
        bytes calldata _srcAddress,
        uint64 _nonce,
        bytes calldata _payload
    ) public virtual {
        // only internal transaction
        require(_msgSender() == address(this), "NonblockingLzApp: caller must be LzApp");
        _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);
    }

    //@notice override this function
    function _nonblockingLzReceive(
        uint16 _srcChainId,
        bytes memory _srcAddress,
        uint64 _nonce,
        bytes memory _payload
    ) internal virtual;

    function retryMessage(
        uint16 _srcChainId,
        bytes calldata _srcAddress,
        uint64 _nonce,
        bytes calldata _payload
    ) public payable virtual {
        // assert there is message to retry
        bytes32 payloadHash = failedMessages[_srcChainId][_srcAddress][_nonce];
        require(payloadHash != bytes32(0), "NonblockingLzApp: no stored message");
        require(keccak256(_payload) == payloadHash, "NonblockingLzApp: invalid payload");
        // clear the stored message
        failedMessages[_srcChainId][_srcAddress][_nonce] = bytes32(0);
        // execute the message. revert if it fails again
        _nonblockingLzReceive(_srcChainId, _srcAddress, _nonce, _payload);
        emit RetryMessageSuccess(_srcChainId, _srcAddress, _nonce, payloadHash);
    }
}


// File contracts/token/onft721/ONFT721Core.sol

// Original license: SPDX_License_Identifier: MIT

pragma solidity ^0.8.0;




abstract contract ONFT721Core is NonblockingLzApp, ERC165, ReentrancyGuard, IONFT721Core {
    uint16 public constant FUNCTION_TYPE_SEND = 1;

    struct StoredCredit {
        uint16 srcChainId;
        address toAddress;
        uint index; // which index of the tokenIds remain
        bool creditsRemain;
    }

    uint public minGasToTransferAndStore; // min amount of gas required to transfer, and also store the payload
    mapping(uint16 => uint) public dstChainIdToBatchLimit;
    mapping(uint16 => uint) public dstChainIdToTransferGas; // per transfer amount of gas required to mint/transfer on the dst
    mapping(bytes32 => StoredCredit) public storedCredits;

    constructor(uint _minGasToTransferAndStore, address _lzEndpoint) NonblockingLzApp(_lzEndpoint) {
        require(_minGasToTransferAndStore > 0, "minGasToTransferAndStore must be > 0");
        minGasToTransferAndStore = _minGasToTransferAndStore;
    }

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

    function estimateSendFee(
        uint16 _dstChainId,
        bytes memory _toAddress,
        uint _tokenId,
        bool _useZro,
        bytes memory _adapterParams
    ) public view virtual override returns (uint nativeFee, uint zroFee) {
        return estimateSendBatchFee(_dstChainId, _toAddress, _toSingletonArray(_tokenId), _useZro, _adapterParams);
    }

    function estimateSendBatchFee(
        uint16 _dstChainId,
        bytes memory _toAddress,
        uint[] memory _tokenIds,
        bool _useZro,
        bytes memory _adapterParams
    ) public view virtual override returns (uint nativeFee, uint zroFee) {
        bytes memory payload = abi.encode(_toAddress, _tokenIds);
        return lzEndpoint.estimateFees(_dstChainId, address(this), payload, _useZro, _adapterParams);
    }

    function sendFrom(
        address _from,
        uint16 _dstChainId,
        bytes memory _toAddress,
        uint _tokenId,
        address payable _refundAddress,
        address _zroPaymentAddress,
        bytes memory _adapterParams
    ) public payable virtual override {
        _send(_from, _dstChainId, _toAddress, _toSingletonArray(_tokenId), _refundAddress, _zroPaymentAddress, _adapterParams);
    }

    function sendBatchFrom(
        address _from,
        uint16 _dstChainId,
        bytes memory _toAddress,
        uint[] memory _tokenIds,
        address payable _refundAddress,
        address _zroPaymentAddress,
        bytes memory _adapterParams
    ) public payable virtual override {
        _send(_from, _dstChainId, _toAddress, _tokenIds, _refundAddress, _zroPaymentAddress, _adapterParams);
    }

    function _send(
        address _from,
        uint16 _dstChainId,
        bytes memory _toAddress,
        uint[] memory _tokenIds,
        address payable _refundAddress,
        address _zroPaymentAddress,
        bytes memory _adapterParams
    ) internal virtual {
        // allow 1 by default
        require(_tokenIds.length > 0, "tokenIds[] is empty");
        require(_tokenIds.length == 1 || _tokenIds.length <= dstChainIdToBatchLimit[_dstChainId], "batch size exceeds dst batch limit");

        for (uint i = 0; i < _tokenIds.length; i++) {
            _debitFrom(_from, _dstChainId, _toAddress, _tokenIds[i]);
        }

        bytes memory payload = abi.encode(_toAddress, _tokenIds);

        _checkGasLimit(_dstChainId, FUNCTION_TYPE_SEND, _adapterParams, dstChainIdToTransferGas[_dstChainId] * _tokenIds.length);
        _lzSend(_dstChainId, payload, _refundAddress, _zroPaymentAddress, _adapterParams, msg.value);
        emit SendToChain(_dstChainId, _from, _toAddress, _tokenIds);
    }

    function _nonblockingLzReceive(
        uint16 _srcChainId,
        bytes memory _srcAddress,
        uint64, /*_nonce*/
        bytes memory _payload
    ) internal virtual override {
        // decode and load the toAddress
        (bytes memory toAddressBytes, uint[] memory tokenIds) = abi.decode(_payload, (bytes, uint[]));

        address toAddress;
        assembly {
            toAddress := mload(add(toAddressBytes, 20))
        }

        uint nextIndex = _creditTill(_srcChainId, toAddress, 0, tokenIds);
        if (nextIndex < tokenIds.length) {
            // not enough gas to complete transfers, store to be cleared in another tx
            bytes32 hashedPayload = keccak256(_payload);
            storedCredits[hashedPayload] = StoredCredit(_srcChainId, toAddress, nextIndex, true);
            emit CreditStored(hashedPayload, _payload);
        }

        emit ReceiveFromChain(_srcChainId, _srcAddress, toAddress, tokenIds);
    }

    // Public function for anyone to clear and deliver the remaining batch sent tokenIds
    function clearCredits(bytes memory _payload) external virtual nonReentrant {
        bytes32 hashedPayload = keccak256(_payload);
        require(storedCredits[hashedPayload].creditsRemain, "no credits stored");

        (, uint[] memory tokenIds) = abi.decode(_payload, (bytes, uint[]));

        uint nextIndex = _creditTill(
            storedCredits[hashedPayload].srcChainId,
            storedCredits[hashedPayload].toAddress,
            storedCredits[hashedPayload].index,
            tokenIds
        );
        require(nextIndex > storedCredits[hashedPayload].index, "not enough gas to process credit transfer");

        if (nextIndex == tokenIds.length) {
            // cleared the credits, delete the element
            delete storedCredits[hashedPayload];
            emit CreditCleared(hashedPayload);
        } else {
            // store the next index to mint
            storedCredits[hashedPayload] = StoredCredit(
                storedCredits[hashedPayload].srcChainId,
                storedCredits[hashedPayload].toAddress,
                nextIndex,
                true
            );
        }
    }

    // When a srcChain has the ability to transfer more chainIds in a single tx than the dst can do.
    // Needs the ability to iterate and stop if the minGasToTransferAndStore is not met
    function _creditTill(
        uint16 _srcChainId,
        address _toAddress,
        uint _startIndex,
        uint[] memory _tokenIds
    ) internal returns (uint) {
        uint i = _startIndex;
        while (i < _tokenIds.length) {
            // if not enough gas to process, store this index for next loop
            if (gasleft() < minGasToTransferAndStore) break;

            _creditTo(_srcChainId, _toAddress, _tokenIds[i]);
            i++;
        }

        // indicates the next index to send of tokenIds,
        // if i == tokenIds.length, we are finished
        return i;
    }

    function setMinGasToTransferAndStore(uint _minGasToTransferAndStore) external onlyOwner {
        require(_minGasToTransferAndStore > 0, "minGasToTransferAndStore must be > 0");
        minGasToTransferAndStore = _minGasToTransferAndStore;
        emit SetMinGasToTransferAndStore(_minGasToTransferAndStore);
    }

    // ensures enough gas in adapter params to handle batch transfer gas amounts on the dst
    function setDstChainIdToTransferGas(uint16 _dstChainId, uint _dstChainIdToTransferGas) external onlyOwner {
        require(_dstChainIdToTransferGas > 0, "dstChainIdToTransferGas must be > 0");
        dstChainIdToTransferGas[_dstChainId] = _dstChainIdToTransferGas;
        emit SetDstChainIdToTransferGas(_dstChainId, _dstChainIdToTransferGas);
    }

    // limit on src the amount of tokens to batch send
    function setDstChainIdToBatchLimit(uint16 _dstChainId, uint _dstChainIdToBatchLimit) external onlyOwner {
        require(_dstChainIdToBatchLimit > 0, "dstChainIdToBatchLimit must be > 0");
        dstChainIdToBatchLimit[_dstChainId] = _dstChainIdToBatchLimit;
        emit SetDstChainIdToBatchLimit(_dstChainId, _dstChainIdToBatchLimit);
    }

    function _debitFrom(
        address _from,
        uint16 _dstChainId,
        bytes memory _toAddress,
        uint _tokenId
    ) internal virtual;

    function _creditTo(
        uint16 _srcChainId,
        address _toAddress,
        uint _tokenId
    ) internal virtual;

    function _toSingletonArray(uint element) internal pure returns (uint[] memory) {
        uint[] memory array = new uint[](1);
        array[0] = element;
        return array;
    }
}


// File contracts/token/onft721/ONFT721.sol

// Original license: SPDX_License_Identifier: MIT

pragma solidity ^0.8.0;



// NOTE: this ONFT contract has no public minting logic.
// must implement your own minting logic in child classes
contract ONFT721 is ONFT721Core, ERC721, IONFT721 {
    constructor(
        string memory _name,
        string memory _symbol,
        uint _minGasToTransfer,
        address _lzEndpoint
    ) ERC721(_name, _symbol) ONFT721Core(_minGasToTransfer, _lzEndpoint) {}

    function supportsInterface(bytes4 interfaceId) public view virtual override(ONFT721Core, ERC721, IERC165) returns (bool) {
        return interfaceId == type(IONFT721).interfaceId || super.supportsInterface(interfaceId);
    }

    function _debitFrom(
        address _from,
        uint16,
        bytes memory,
        uint _tokenId
    ) internal virtual override {
        require(_isApprovedOrOwner(_msgSender(), _tokenId), "ONFT721: send caller is not owner nor approved");
        require(ERC721.ownerOf(_tokenId) == _from, "ONFT721: send from incorrect owner");
        _transfer(_from, address(this), _tokenId);
    }

    function _creditTo(
        uint16,
        address _toAddress,
        uint _tokenId
    ) internal virtual override {
        require(!_exists(_tokenId) || (_exists(_tokenId) && ERC721.ownerOf(_tokenId) == address(this)));
        if (!_exists(_tokenId)) {
            _safeMint(_toAddress, _tokenId);
        } else {
            _transfer(address(this), _toAddress, _tokenId);
        }
    }
}


// File contracts/Cryptorank.sol

// Original license: SPDX_License_Identifier: MIT

pragma solidity ^0.8.0;

contract Cryptorank is ONFT721 {
    event ReferralMint(string referral, address sender, uint count);
    event ReferralBridge(string referral, address sender);
    event ReferralGas(string referral, address sender);

    error InsufficientPayment(uint fee, uint value);
    error ArrayLengthsNotEqual();

    address constant OWNER = 0xBE135bcF2B6F05e2AD5a3a227E15222Bfd7c0B22;

    uint public fee;
    uint public nextMintId;
    string public baseUri;

    constructor(
        string memory name,
        string memory symbol,
        string memory baseUri_,
        uint _minGasToTransfer,
        address _layerZeroEndpoint,
        uint fee_,
        uint128 chainId_,
        uint16[] memory _remoteChainIds,
        uint minDstGas
    ) ONFT721(name, symbol, _minGasToTransfer, _layerZeroEndpoint) {
        uint nextMintId_ = (uint(chainId_) << 128) + 1;
        fee = fee_;
        baseUri = baseUri_;

        _setMinDstGasBatch(_remoteChainIds, 1, minDstGas);
        _transferOwnership(OWNER);

        _safeMint(msg.sender, nextMintId_);
        nextMintId = nextMintId_ + 1;
    }

    // _path = abi.encodePacked(remoteAddress, localAddress)
    // this function set the trusted path for the cross-chain communication
    function setTrustedRemoteBatch(uint16[] memory _remoteChainIds, bytes[] memory _paths) external onlyOwner {
        if (_remoteChainIds.length != _paths.length) revert ArrayLengthsNotEqual();

        for (uint i = 0; i < _remoteChainIds.length; i++) {
            trustedRemoteLookup[_remoteChainIds[i]] = _paths[i];
            emit SetTrustedRemote(_remoteChainIds[i], _paths[i]);
        }
    }

    function _setMinDstGasBatch(
        uint16[] memory _dstChainIds,
        uint16 _packetType,
        uint _minGas
    ) internal {
        for (uint i = 0; i < _dstChainIds.length; i++) {
            minDstGasLookup[_dstChainIds[i]][_packetType] = _minGas;
            emit SetMinDstGas(_dstChainIds[i], _packetType, _minGas);
        }
    }

    function setFee(uint fee_) external onlyOwner {
        fee = fee_;
    }

    function setBaseUri(string calldata baseUri_) external onlyOwner {
        baseUri = baseUri_;
    }

    function mintBatch(string calldata referral, uint count) external payable {
        uint totalFee = fee * count;
        if (msg.value < totalFee) revert InsufficientPayment(totalFee, msg.value);
        uint newId = nextMintId;

        for (uint i = 0; i < count; i++) {
            _safeMint(msg.sender, newId + i);
        }

        nextMintId += count;
        emit ReferralMint(referral, msg.sender, count);
    }

    function mint(string calldata referral) external payable {
        if (msg.value < fee) revert InsufficientPayment(fee, msg.value);

        uint newId = nextMintId;
        nextMintId++;

        _safeMint(msg.sender, newId);
        emit ReferralMint(referral, msg.sender, 1);
    }

    function estimateGasBridgeFee(
        uint16 _dstChainId,
        bool _useZro,
        bytes memory _adapterParams
    ) public view virtual returns (uint nativeFee, uint zroFee) {
        bytes memory payload = abi.encode(msg.sender, 0);
        return lzEndpoint.estimateFees(_dstChainId, payable(address(this)), payload, _useZro, _adapterParams);
    }

    function bridgeGas(
        uint16 _dstChainId,
        address _zroPaymentAddress,
        bytes memory _adapterParams,
        string memory referral
    ) public payable {
        _checkGasLimit(_dstChainId, FUNCTION_TYPE_SEND, _adapterParams, dstChainIdToTransferGas[_dstChainId]);
        _lzSend(_dstChainId, abi.encode(msg.sender, 0), payable(address(this)), _zroPaymentAddress, _adapterParams, msg.value);
        emit ReferralGas(referral, msg.sender);
    }

    function sendFromWithReferral(
        address _from,
        uint16 _dstChainId,
        bytes memory _toAddress,
        uint _tokenId,
        address payable _refundAddress,
        address _zroPaymentAddress,
        bytes memory _adapterParams,
        string memory referral
    ) public payable {
        _send(_from, _dstChainId, _toAddress, _toSingletonArray(_tokenId), _refundAddress, _zroPaymentAddress, _adapterParams);
        emit ReferralBridge(referral, msg.sender);
    }

    function sendBatchFromWithReferral(
        address _from,
        uint16 _dstChainId,
        bytes memory _toAddress,
        uint[] memory _tokenIds,
        address payable _refundAddress,
        address _zroPaymentAddress,
        bytes memory _adapterParams,
        string memory referral
    ) public payable {
        _send(_from, _dstChainId, _toAddress, _tokenIds, _refundAddress, _zroPaymentAddress, _adapterParams);
        emit ReferralBridge(referral, msg.sender);
    }

    function withdraw() public onlyOwner {
        (bool success, ) = payable(msg.sender).call{value: address(this).balance}("");
        require(success);
    }

    function _baseURI() internal view override returns (string memory) {
        return baseUri;
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"name","type":"string"},{"internalType":"string","name":"symbol","type":"string"},{"internalType":"string","name":"baseUri_","type":"string"},{"internalType":"uint256","name":"_minGasToTransfer","type":"uint256"},{"internalType":"address","name":"_layerZeroEndpoint","type":"address"},{"internalType":"uint256","name":"fee_","type":"uint256"},{"internalType":"uint128","name":"chainId_","type":"uint128"},{"internalType":"uint16[]","name":"_remoteChainIds","type":"uint16[]"},{"internalType":"uint256","name":"minDstGas","type":"uint256"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ArrayLengthsNotEqual","type":"error"},{"inputs":[{"internalType":"uint256","name":"fee","type":"uint256"},{"internalType":"uint256","name":"value","type":"uint256"}],"name":"InsufficientPayment","type":"error"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"_hashedPayload","type":"bytes32"}],"name":"CreditCleared","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"bytes32","name":"_hashedPayload","type":"bytes32"},{"indexed":false,"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"CreditStored","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"_nonce","type":"uint64"},{"indexed":false,"internalType":"bytes","name":"_payload","type":"bytes"},{"indexed":false,"internalType":"bytes","name":"_reason","type":"bytes"}],"name":"MessageFailed","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":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":true,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":true,"internalType":"address","name":"_toAddress","type":"address"},{"indexed":false,"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"ReceiveFromChain","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"referral","type":"string"},{"indexed":false,"internalType":"address","name":"sender","type":"address"}],"name":"ReferralBridge","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"referral","type":"string"},{"indexed":false,"internalType":"address","name":"sender","type":"address"}],"name":"ReferralGas","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"referral","type":"string"},{"indexed":false,"internalType":"address","name":"sender","type":"address"},{"indexed":false,"internalType":"uint256","name":"count","type":"uint256"}],"name":"ReferralMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"indexed":false,"internalType":"uint64","name":"_nonce","type":"uint64"},{"indexed":false,"internalType":"bytes32","name":"_payloadHash","type":"bytes32"}],"name":"RetryMessageSuccess","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"indexed":true,"internalType":"address","name":"_from","type":"address"},{"indexed":true,"internalType":"bytes","name":"_toAddress","type":"bytes"},{"indexed":false,"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"}],"name":"SendToChain","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"_dstChainIdToBatchLimit","type":"uint256"}],"name":"SetDstChainIdToBatchLimit","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"_dstChainIdToTransferGas","type":"uint256"}],"name":"SetDstChainIdToTransferGas","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"indexed":false,"internalType":"uint16","name":"_type","type":"uint16"},{"indexed":false,"internalType":"uint256","name":"_minDstGas","type":"uint256"}],"name":"SetMinDstGas","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"_minGasToTransferAndStore","type":"uint256"}],"name":"SetMinGasToTransferAndStore","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"precrime","type":"address"}],"name":"SetPrecrime","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_path","type":"bytes"}],"name":"SetTrustedRemote","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"indexed":false,"internalType":"bytes","name":"_remoteAddress","type":"bytes"}],"name":"SetTrustedRemoteAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"DEFAULT_PAYLOAD_SIZE_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"FUNCTION_TYPE_SEND","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"address","name":"_zroPaymentAddress","type":"address"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"},{"internalType":"string","name":"referral","type":"string"}],"name":"bridgeGas","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"clearCredits","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"dstChainIdToBatchLimit","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"dstChainIdToTransferGas","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bool","name":"_useZro","type":"bool"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"estimateGasBridgeFee","outputs":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"zroFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"bool","name":"_useZro","type":"bool"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"estimateSendBatchFee","outputs":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"zroFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bool","name":"_useZro","type":"bool"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"estimateSendFee","outputs":[{"internalType":"uint256","name":"nativeFee","type":"uint256"},{"internalType":"uint256","name":"zroFee","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"bytes","name":"","type":"bytes"},{"internalType":"uint64","name":"","type":"uint64"}],"name":"failedMessages","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"fee","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"}],"name":"forceResumeReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"},{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"address","name":"","type":"address"},{"internalType":"uint256","name":"_configType","type":"uint256"}],"name":"getConfig","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"}],"name":"getTrustedRemoteAddress","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"}],"name":"isTrustedRemote","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"lzEndpoint","outputs":[{"internalType":"contract ILayerZeroEndpoint","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"lzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"},{"internalType":"uint16","name":"","type":"uint16"}],"name":"minDstGasLookup","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"minGasToTransferAndStore","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"string","name":"referral","type":"string"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"string","name":"referral","type":"string"},{"internalType":"uint256","name":"count","type":"uint256"}],"name":"mintBatch","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextMintId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"nonblockingLzReceive","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"payloadSizeLimitLookup","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"precrime","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_srcChainId","type":"uint16"},{"internalType":"bytes","name":"_srcAddress","type":"bytes"},{"internalType":"uint64","name":"_nonce","type":"uint64"},{"internalType":"bytes","name":"_payload","type":"bytes"}],"name":"retryMessage","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"internalType":"address","name":"_zroPaymentAddress","type":"address"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"sendBatchFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256[]","name":"_tokenIds","type":"uint256[]"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"internalType":"address","name":"_zroPaymentAddress","type":"address"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"},{"internalType":"string","name":"referral","type":"string"}],"name":"sendBatchFromWithReferral","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"internalType":"address","name":"_zroPaymentAddress","type":"address"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"}],"name":"sendFrom","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"_from","type":"address"},{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"bytes","name":"_toAddress","type":"bytes"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"address payable","name":"_refundAddress","type":"address"},{"internalType":"address","name":"_zroPaymentAddress","type":"address"},{"internalType":"bytes","name":"_adapterParams","type":"bytes"},{"internalType":"string","name":"referral","type":"string"}],"name":"sendFromWithReferral","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseUri_","type":"string"}],"name":"setBaseUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"},{"internalType":"uint16","name":"_chainId","type":"uint16"},{"internalType":"uint256","name":"_configType","type":"uint256"},{"internalType":"bytes","name":"_config","type":"bytes"}],"name":"setConfig","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_dstChainIdToBatchLimit","type":"uint256"}],"name":"setDstChainIdToBatchLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_dstChainIdToTransferGas","type":"uint256"}],"name":"setDstChainIdToTransferGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"fee_","type":"uint256"}],"name":"setFee","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint16","name":"_packetType","type":"uint16"},{"internalType":"uint256","name":"_minGas","type":"uint256"}],"name":"setMinDstGas","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_minGasToTransferAndStore","type":"uint256"}],"name":"setMinGasToTransferAndStore","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_dstChainId","type":"uint16"},{"internalType":"uint256","name":"_size","type":"uint256"}],"name":"setPayloadSizeLimit","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_precrime","type":"address"}],"name":"setPrecrime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"}],"name":"setReceiveVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_version","type":"uint16"}],"name":"setSendVersion","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"internalType":"bytes","name":"_path","type":"bytes"}],"name":"setTrustedRemote","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"_remoteChainId","type":"uint16"},{"internalType":"bytes","name":"_remoteAddress","type":"bytes"}],"name":"setTrustedRemoteAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16[]","name":"_remoteChainIds","type":"uint16[]"},{"internalType":"bytes[]","name":"_paths","type":"bytes[]"}],"name":"setTrustedRemoteBatch","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"name":"storedCredits","outputs":[{"internalType":"uint16","name":"srcChainId","type":"uint16"},{"internalType":"address","name":"toAddress","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"},{"internalType":"bool","name":"creditsRemain","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint16","name":"","type":"uint16"}],"name":"trustedRemoteLookup","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60a06040523480156200001157600080fd5b5060405162005ae738038062005ae78339810160408190526200003491620007e8565b88888787838383838080620000493362000186565b6001600160a01b031660805250600160065581620000ba5760405162461bcd60e51b8152602060048201526024808201527f6d696e476173546f5472616e73666572416e6453746f7265206d7573742062656044820152630203e20360e41b60648201526084015b60405180910390fd5b506007558151620000d390600b9060208501906200058f565b508051620000e990600c9060208401906200058f565b5050505050505060006080846001600160801b0316901b60016200010e9190620008fa565b601186905588519091506200012b9060139060208b01906200058f565b506200013a83600184620001d6565b6200015973be135bcf2b6f05e2ad5a3a227e15222bfd7c0b2262000186565b620001653382620002c5565b62000172816001620008fa565b6012555062000a9898505050505050505050565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60005b8351811015620002bf578160026000868481518110620001fd57620001fd62000915565b602002602001015161ffff1661ffff16815260200190815260200160002060008561ffff1661ffff168152602001908152602001600020819055507f9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac08482815181106200026e576200026e62000915565b60200260200101518484604051620002a29392919061ffff9384168152919092166020820152604081019190915260600190565b60405180910390a180620002b6816200092b565b915050620001d9565b50505050565b620002e7828260405180602001604052806000815250620002eb60201b60201c565b5050565b620002f783836200032a565b62000306600084848462000443565b620003255760405162461bcd60e51b8152600401620000b19062000949565b505050565b6001600160a01b038216620003825760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401620000b1565b6200038d8162000563565b15620003ad5760405162461bcd60e51b8152600401620000b1906200099b565b620003b88162000563565b15620003d85760405162461bcd60e51b8152600401620000b1906200099b565b6001600160a01b0382166000818152600e6020908152604080832080546001019055848352600d90915280822080546001600160a01b0319168417905551839291907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b600062000464846001600160a01b03166200058060201b620025b51760201c565b156200055757604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906200049e903390899088908890600401620009d2565b6020604051808303816000875af1925050508015620004dc575060408051601f3d908101601f19168201909252620004d99181019062000a28565b60015b6200053c573d8080156200050d576040519150601f19603f3d011682016040523d82523d6000602084013e62000512565b606091505b508051620005345760405162461bcd60e51b8152600401620000b19062000949565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506200055b565b5060015b949350505050565b6000908152600d60205260409020546001600160a01b0316151590565b6001600160a01b03163b151590565b8280546200059d9062000a5b565b90600052602060002090601f016020900481019282620005c157600085556200060c565b82601f10620005dc57805160ff19168380011785556200060c565b828001600101855582156200060c579182015b828111156200060c578251825591602001919060010190620005ef565b506200061a9291506200061e565b5090565b5b808211156200061a57600081556001016200061f565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b038111828210171562000676576200067662000635565b604052919050565b60005b838110156200069b57818101518382015260200162000681565b83811115620002bf5750506000910152565b600082601f830112620006bf57600080fd5b81516001600160401b03811115620006db57620006db62000635565b620006f0601f8201601f19166020016200064b565b8181528460208386010111156200070657600080fd5b6200055b8260208301602087016200067e565b80516001600160a01b03811681146200073157600080fd5b919050565b80516001600160801b03811681146200073157600080fd5b600082601f8301126200076057600080fd5b815160206001600160401b038211156200077e576200077e62000635565b8160051b6200078f8282016200064b565b9283528481018201928281019087851115620007aa57600080fd5b83870192505b84831015620007dd57825161ffff81168114620007cd5760008081fd5b82529183019190830190620007b0565b979650505050505050565b60008060008060008060008060006101208a8c0312156200080857600080fd5b89516001600160401b03808211156200082057600080fd5b6200082e8d838e01620006ad565b9a5060208c01519150808211156200084557600080fd5b620008538d838e01620006ad565b995060408c01519150808211156200086a57600080fd5b620008788d838e01620006ad565b985060608c015197506200088f60808d0162000719565b965060a08c01519550620008a660c08d0162000736565b945060e08c0151915080821115620008bd57600080fd5b50620008cc8c828d016200074e565b9250506101008a015190509295985092959850929598565b634e487b7160e01b600052601160045260246000fd5b60008219821115620009105762000910620008e4565b500190565b634e487b7160e01b600052603260045260246000fd5b6000600019821415620009425762000942620008e4565b5060010190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252601c908201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604082015260600190565b600060018060a01b03808716835280861660208401525083604083015260806060830152825180608084015262000a118160a08501602087016200067e565b601f01601f19169190910160a00195945050505050565b60006020828403121562000a3b57600080fd5b81516001600160e01b03198116811462000a5457600080fd5b9392505050565b600181811c9082168062000a7057607f821691505b6020821081141562000a9257634e487b7160e01b600052602260045260246000fd5b50919050565b608051614ff462000af3600039600081816108ff01528181610b4901528181610e4d015281816110d2015281816112c701528181611e660152818161225701528181612400015281816125330152612b640152614ff46000f3fe6080604052600436106102d25760003560e01c80621d3567146102d757806301ffc9a7146102f957806306fdde031461032e57806307e0db1714610350578063081812fc14610370578063095ea7b31461039d5780630b4cad4c146103bd5780630df37483146103dd57806310ddb137146103fd57806322a3ecf91461041d57806323b872dd146104a05780632a205e3d146104c05780633ccfd60b146104f55780633d8b38f61461050a5780633f1f4fa41461052a57806342842e0e1461056557806342d65a8d14610585578063468fa2af146105a557806348288190146105b85780634ac3f4ff146105ce57806351905636146105fb5780635b8c41e61461060e5780636352211e1461065d57806366ad5c8a1461067d57806369fe0e2d1461069d5780636aa99da3146106bd57806370a08231146106d3578063715018a6146106f35780637533d7881461070857806376fffcd0146107285780638cfd8f5c146107485780638da5cb5b146107805780638ffa1f2a14610795578063950c8a74146107b557806395d89b41146107d55780639abc8320146107ea5780639ea5d6b1146107ff5780639f38369a1461081f578063a0bcfc7f1461083f578063a22cb4651461085f578063a6c3d1651461087f578063ab3ffb931461089f578063ac37cf53146108b2578063af3fb21c146108c5578063b353aaa7146108ed578063b770f98414610921578063b88d4fde14610934578063baf3292d14610954578063c446183414610974578063c7565b011461098a578063c87b56dd1461099d578063cbed8b9c146109bd578063d12473a5146109dd578063d1deba1f146109fd578063d85d3d2714610a10578063da09f15d14610a23578063ddca3f4314610a43578063df2a5b3b14610a59578063e985e9c514610a79578063eb8d72b714610a99578063f235364114610ab9578063f2fde38b14610ad9578063f5ecbdbc14610af9578063fa25f9b614610b19575b600080fd5b3480156102e357600080fd5b506102f76102f2366004613af9565b610b46565b005b34801561030557600080fd5b50610319610314366004613ba2565b610d77565b60405190151581526020015b60405180910390f35b34801561033a57600080fd5b50610343610d9a565b6040516103259190613c17565b34801561035c57600080fd5b506102f761036b366004613c2a565b610e2c565b34801561037c57600080fd5b5061039061038b366004613c45565b610eb5565b6040516103259190613c5e565b3480156103a957600080fd5b506102f76103b8366004613c92565b610edc565b3480156103c957600080fd5b506102f76103d8366004613c45565b610ff2565b3480156103e957600080fd5b506102f76103f8366004613cbe565b611092565b34801561040957600080fd5b506102f7610418366004613c2a565b6110b1565b34801561042957600080fd5b50610471610438366004613c45565b600a6020526000908152604090208054600182015460029092015461ffff821692620100009092046001600160a01b0316919060ff1684565b6040805161ffff90951685526001600160a01b0390931660208501529183015215156060820152608001610325565b3480156104ac57600080fd5b506102f76104bb366004613cda565b611109565b3480156104cc57600080fd5b506104e06104db366004613dee565b61113b565b60408051928352602083019190915201610325565b34801561050157600080fd5b506102f7611161565b34801561051657600080fd5b50610319610525366004613e7c565b6111c1565b34801561053657600080fd5b50610557610545366004613c2a565b60036020526000908152604090205481565b604051908152602001610325565b34801561057157600080fd5b506102f7610580366004613cda565b61128d565b34801561059157600080fd5b506102f76105a0366004613e7c565b6112a8565b6102f76105b3366004613ece565b61132e565b3480156105c457600080fd5b5061055760075481565b3480156105da57600080fd5b506105576105e9366004613c2a565b60086020526000908152604090205481565b6102f7610609366004613f54565b6113c1565b34801561061a57600080fd5b5061055761062936600461400d565b6005602090815260009384526040808520845180860184018051928152908401958401959095209452929052825290205481565b34801561066957600080fd5b50610390610678366004613c45565b6113d8565b34801561068957600080fd5b506102f7610698366004613af9565b61140c565b3480156106a957600080fd5b506102f76106b8366004613c45565b6114e8565b3480156106c957600080fd5b5061055760125481565b3480156106df57600080fd5b506105576106ee36600461406a565b6114f5565b3480156106ff57600080fd5b506102f761157b565b34801561071457600080fd5b50610343610723366004613c2a565b61158f565b34801561073457600080fd5b506102f7610743366004614134565b611629565b34801561075457600080fd5b506105576107633660046141f3565b600260209081526000928352604080842090915290825290205481565b34801561078c57600080fd5b5061039061172c565b3480156107a157600080fd5b506102f76107b0366004614226565b61173b565b3480156107c157600080fd5b50600454610390906001600160a01b031681565b3480156107e157600080fd5b50610343611984565b3480156107f657600080fd5b50610343611993565b34801561080b57600080fd5b506102f761081a366004613cbe565b6119a0565b34801561082b57600080fd5b5061034361083a366004613c2a565b611a57565b34801561084b57600080fd5b506102f761085a36600461425a565b611b6e565b34801561086b57600080fd5b506102f761087a36600461429b565b611b82565b34801561088b57600080fd5b506102f761089a366004613e7c565b611b91565b6102f76108ad366004614322565b611c24565b6102f76108c03660046143d7565b611c33565b3480156108d157600080fd5b506108da600181565b60405161ffff9091168152602001610325565b3480156108f957600080fd5b506103907f000000000000000000000000000000000000000000000000000000000000000081565b6102f761092f366004614422565b611ced565b34801561094057600080fd5b506102f761094f366004614511565b611d3f565b34801561096057600080fd5b506102f761096f36600461406a565b611d77565b34801561098057600080fd5b5061055761271081565b6102f7610998366004614570565b611dca565b3480156109a957600080fd5b506103436109b8366004613c45565b611de1565b3480156109c957600080fd5b506102f76109d83660046145e1565b611e47565b3480156109e957600080fd5b506102f76109f8366004613cbe565b611edc565b6102f7610a0b366004613af9565b611f8c565b6102f7610a1e36600461425a565b6121a2565b348015610a2f57600080fd5b506104e0610a3e36600461464f565b612217565b348015610a4f57600080fd5b5061055760115481565b348015610a6557600080fd5b506102f7610a743660046146ac565b6122e1565b348015610a8557600080fd5b50610319610a943660046146e8565b61234b565b348015610aa557600080fd5b506102f7610ab4366004613e7c565b612379565b348015610ac557600080fd5b506104e0610ad4366004614721565b6123c1565b348015610ae557600080fd5b506102f7610af436600461406a565b61248c565b348015610b0557600080fd5b50610343610b1436600461479a565b612502565b348015610b2557600080fd5b50610557610b34366004613c2a565b60096020526000908152604090205481565b337f00000000000000000000000000000000000000000000000000000000000000006001600160a01b031614610bc35760405162461bcd60e51b815260206004820152601e60248201527f4c7a4170703a20696e76616c696420656e64706f696e742063616c6c6572000060448201526064015b60405180910390fd5b61ffff861660009081526001602052604081208054610be1906147e7565b80601f0160208091040260200160405190810160405280929190818152602001828054610c0d906147e7565b8015610c5a5780601f10610c2f57610100808354040283529160200191610c5a565b820191906000526020600020905b815481529060010190602001808311610c3d57829003601f168201915b50505050509050805186869050148015610c75575060008151115b8015610c9d575080516020820120604051610c939088908890614822565b6040518091039020145b610cf85760405162461bcd60e51b815260206004820152602660248201527f4c7a4170703a20696e76616c696420736f757263652073656e64696e6720636f6044820152651b9d1c9858dd60d21b6064820152608401610bba565b610d6e8787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881528a9350915088908890819084018382808284376000920191909152506125c492505050565b50505050505050565b60006001600160e01b031982161580610d945750610d948261263d565b92915050565b6060600b8054610da9906147e7565b80601f0160208091040260200160405190810160405280929190818152602001828054610dd5906147e7565b8015610e225780601f10610df757610100808354040283529160200191610e22565b820191906000526020600020905b815481529060010190602001808311610e0557829003601f168201915b5050505050905090565b610e3461267d565b6040516307e0db1760e01b815261ffff821660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906307e0db17906024015b600060405180830381600087803b158015610e9a57600080fd5b505af1158015610eae573d6000803e3d6000fd5b5050505050565b6000610ec0826126dc565b506000908152600f60205260409020546001600160a01b031690565b6000610ee7826113d8565b9050806001600160a01b0316836001600160a01b03161415610f555760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610bba565b336001600160a01b0382161480610f715750610f71813361234b565b610fe35760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610bba565b610fed8383612701565b505050565b610ffa61267d565b600081116110565760405162461bcd60e51b8152602060048201526024808201527f6d696e476173546f5472616e73666572416e6453746f7265206d7573742062656044820152630203e20360e41b6064820152608401610bba565b60078190556040518181527ffebbc4f8bb9ec2313950c718d43123124b15778efda4c1f1d529de2995b4f34d906020015b60405180910390a150565b61109a61267d565b61ffff909116600090815260036020526040902055565b6110b961267d565b6040516310ddb13760e01b815261ffff821660048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906310ddb13790602401610e80565b611114335b8261276f565b6111305760405162461bcd60e51b8152600401610bba90614832565b610fed8383836127cd565b600080611153878761114c8861291f565b87876123c1565b915091509550959350505050565b61116961267d565b604051600090339047908381818185875af1925050503d80600081146111ab576040519150601f19603f3d011682016040523d82523d6000602084013e6111b0565b606091505b50509050806111be57600080fd5b50565b61ffff8316600090815260016020526040812080548291906111e2906147e7565b80601f016020809104026020016040519081016040528092919081815260200182805461120e906147e7565b801561125b5780601f106112305761010080835404028352916020019161125b565b820191906000526020600020905b81548152906001019060200180831161123e57829003601f168201915b505050505090508383604051611272929190614822565b60405180910390208180519060200120149150509392505050565b610fed83838360405180602001604052806000815250611d3f565b6112b061267d565b6040516342d65a8d60e01b81526001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906342d65a8d90611300908690869086906004016148a8565b600060405180830381600087803b15801561131a57600080fd5b505af1158015610d6e573d6000803e3d6000fd5b61ffff8416600090815260096020526040902054611352908590600190859061296a565b6113828433600060405160200161136a9291906148c6565b60405160208183030381529060405230868634612a3a565b7f5720f01742c072b3cf489909863e630a6bdead9fe5ff36bbadbfc6f442c928c681336040516113b39291906148e2565b60405180910390a150505050565b610d6e8787876113d08861291f565b878787612be0565b6000806113e483612db4565b90506001600160a01b038116610d945760405162461bcd60e51b8152600401610bba9061490c565b33301461146a5760405162461bcd60e51b815260206004820152602660248201527f4e6f6e626c6f636b696e674c7a4170703a2063616c6c6572206d7573742062656044820152650204c7a4170760d41b6064820152608401610bba565b6114e08686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f890181900481028201810190925287815289935091508790879081908401838280828437600092019190915250612dcf92505050565b505050505050565b6114f061267d565b601155565b60006001600160a01b03821661155f5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610bba565b506001600160a01b03166000908152600e602052604090205490565b61158361267d565b61158d6000612f26565b565b600160205260009081526040902080546115a8906147e7565b80601f01602080910402602001604051908101604052809291908181526020018280546115d4906147e7565b80156116215780601f106115f657610100808354040283529160200191611621565b820191906000526020600020905b81548152906001019060200180831161160457829003601f168201915b505050505081565b61163161267d565b80518251146116535760405163440de63f60e01b815260040160405180910390fd5b60005b8251811015610fed578181815181106116715761167161493e565b60200260200101516001600085848151811061168f5761168f61493e565b602002602001015161ffff1661ffff16815260200190815260200160002090805190602001906116c0929190613976565b50600080516020614f9f8339815191528382815181106116e2576116e261493e565b60200260200101518383815181106116fc576116fc61493e565b6020026020010151604051611712929190614954565b60405180910390a18061172481614987565b915050611656565b6000546001600160a01b031690565b611743612f76565b80516020808301919091206000818152600a90925260409091206002015460ff166117a45760405162461bcd60e51b81526020600482015260116024820152701b9bc818dc99591a5d1cc81cdd1bdc9959607a1b6044820152606401610bba565b6000828060200190518101906117ba91906149e7565b6000848152600a6020526040812080546001909101549294509092506117f69161ffff8216916201000090046001600160a01b03169085612fd0565b6000848152600a6020526040902060010154909150811161186b5760405162461bcd60e51b815260206004820152602960248201527f6e6f7420656e6f7567682067617320746f2070726f6365737320637265646974604482015268103a3930b739b332b960b91b6064820152608401610bba565b81518114156118e3576000838152600a602052604080822080546001600160b01b031916815560018101929092556002909101805460ff19169055517fd7be02b8dd0d27bd0517a9cb4d7469ce27df4313821ae5ec1ff69acc594ba233906118d69085815260200190565b60405180910390a1611977565b604080516080810182526000858152600a6020818152848320805461ffff80821687526001600160a01b03620100008084048216868a019081529989018b8152600160608b01818152998f90529790965297519851169096026001600160b01b03199091169690951695909517939093178455915191830191909155516002909101805491151560ff199092169190911790555b5050506111be6001600655565b6060600c8054610da9906147e7565b601380546115a8906147e7565b6119a861267d565b60008111611a035760405162461bcd60e51b815260206004820152602260248201527f647374436861696e4964546f42617463684c696d6974206d757374206265203e604482015261020360f41b6064820152608401610bba565b61ffff8216600081815260086020908152604091829020849055815192835282018390527f7315f7654d594ead24a30160ed9ba2d23247f543016b918343591e93d7afdb6d91015b60405180910390a15050565b61ffff8116600090815260016020526040812080546060929190611a7a906147e7565b80601f0160208091040260200160405190810160405280929190818152602001828054611aa6906147e7565b8015611af35780601f10611ac857610100808354040283529160200191611af3565b820191906000526020600020905b815481529060010190602001808311611ad657829003601f168201915b50505050509050805160001415611b4c5760405162461bcd60e51b815260206004820152601d60248201527f4c7a4170703a206e6f20747275737465642070617468207265636f72640000006044820152606401610bba565b611b67600060148351611b5f9190614aa1565b839190613022565b9392505050565b611b7661267d565b610fed601383836139fa565b611b8d33838361312f565b5050565b611b9961267d565b818130604051602001611bae93929190614ab8565b60408051601f1981840301815291815261ffff85166000908152600160209081529190208251611be393919290910190613976565b507f8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce838383604051611c17939291906148a8565b60405180910390a1505050565b610d6e87878787878787612be0565b600081601154611c439190614ad9565b905080341015611c6f5760405163b99e2ab760e01b815260048101829052346024820152604401610bba565b60125460005b83811015611ca257611c9033611c8b8385614af8565b6131fa565b80611c9a81614987565b915050611c75565b508260126000828254611cb59190614af8565b9091555050604051600080516020614f7f83398151915290611cde908790879033908890614b10565b60405180910390a15050505050565b611cfc88888888888888612be0565b7f5ab1a06533ffe44ad2e290926a22350e1916f557908cef6b3c9debca9119287e8133604051611d2d9291906148e2565b60405180910390a15050505050505050565b611d49338361276f565b611d655760405162461bcd60e51b8152600401610bba90614832565b611d7184848484613214565b50505050565b611d7f61267d565b600480546001600160a01b0319166001600160a01b0383161790556040517f5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b90611087908390613c5e565b611cfc888888611dd98961291f565b888888612be0565b6060611dec826126dc565b6000611df6613247565b90506000815111611e165760405180602001604052806000815250611b67565b80611e2084613256565b604051602001611e31929190614b40565b6040516020818303038152906040529392505050565b611e4f61267d565b6040516332fb62e760e21b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063cbed8b9c90611ea39088908890889088908890600401614b6f565b600060405180830381600087803b158015611ebd57600080fd5b505af1158015611ed1573d6000803e3d6000fd5b505050505050505050565b611ee461267d565b60008111611f405760405162461bcd60e51b815260206004820152602360248201527f647374436861696e4964546f5472616e73666572476173206d7573742062652060448201526203e20360ec1b6064820152608401610bba565b61ffff8216600081815260096020908152604091829020849055815192835282018390527fc46df2983228ac2d9754e94a0d565e6671665dc8ad38602bc8e544f0685a29fb9101611a4b565b61ffff86166000908152600560205260408082209051611faf9088908890614822565b90815260408051602092819003830190206001600160401b0387166000908152925290205490508061202f5760405162461bcd60e51b815260206004820152602360248201527f4e6f6e626c6f636b696e674c7a4170703a206e6f2073746f726564206d65737360448201526261676560e81b6064820152608401610bba565b808383604051612040929190614822565b60405180910390201461209f5760405162461bcd60e51b815260206004820152602160248201527f4e6f6e626c6f636b696e674c7a4170703a20696e76616c6964207061796c6f616044820152601960fa1b6064820152608401610bba565b61ffff871660009081526005602052604080822090516120c29089908990614822565b90815260408051602092819003830181206001600160401b038916600090815290845282902093909355601f8801829004820283018201905286825261215a918991899089908190840183828082843760009201919091525050604080516020601f8a018190048102820181019092528881528a935091508890889081908401838280828437600092019190915250612dcf92505050565b7fc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e58787878785604051612191959493929190614ba8565b60405180910390a150505050505050565b6011543410156121d25760115460405163b99e2ab760e01b81526004810191909152346024820152604401610bba565b6012805490819060006121e483614987565b91905055506121f333826131fa565b600080516020614f7f8339815191528383336001604051611c179493929190614b10565b60008060003360006040516020016122309291906148c6565b60408051601f198184030181529082905263040a7bb160e41b825291506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906340a7bb1090612294908990309086908b908b90600401614be3565b6040805180830381865afa1580156122b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d49190614c37565b9250925050935093915050565b6122e961267d565b61ffff83811660008181526002602090815260408083209487168084529482529182902085905581519283528201929092529081018290527f9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac090606001611c17565b6001600160a01b03918216600090815260106020908152604080832093909416825291909152205460ff1690565b61238161267d565b61ffff8316600090815260016020526040902061239f9083836139fa565b50600080516020614f9f833981519152838383604051611c17939291906148a8565b600080600086866040516020016123d9929190614c96565b60408051601f198184030181529082905263040a7bb160e41b825291506001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906340a7bb109061243d908b90309086908b908b90600401614be3565b6040805180830381865afa158015612459573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061247d9190614c37565b92509250509550959350505050565b61249461267d565b6001600160a01b0381166124f95760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610bba565b6111be81612f26565b604051633d7b2f6f60e21b815261ffff808616600483015284166024820152306044820152606481018290526060907f00000000000000000000000000000000000000000000000000000000000000006001600160a01b03169063f5ecbdbc90608401600060405180830381865afa158015612582573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526125aa9190810190614cc4565b90505b949350505050565b6001600160a01b03163b151590565b6000806126275a60966366ad5c8a60e01b898989896040516024016125ec9493929190614cf8565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152309291906132f2565b91509150816114e0576114e0868686868561337c565b60006001600160e01b031982166380ac58cd60e01b148061266e57506001600160e01b03198216635b5e139f60e01b145b80610d945750610d948261340a565b3361268661172c565b6001600160a01b03161461158d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610bba565b6126e58161343f565b6111be5760405162461bcd60e51b8152600401610bba9061490c565b6000818152600f6020526040902080546001600160a01b0319166001600160a01b0384169081179091558190612736826113d8565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061277b836113d8565b9050806001600160a01b0316846001600160a01b031614806127a257506127a2818561234b565b806125ad5750836001600160a01b03166127bb84610eb5565b6001600160a01b031614949350505050565b826001600160a01b03166127e0826113d8565b6001600160a01b0316146128065760405162461bcd60e51b8152600401610bba90614d36565b6001600160a01b0382166128685760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610bba565b826001600160a01b031661287b826113d8565b6001600160a01b0316146128a15760405162461bcd60e51b8152600401610bba90614d36565b6000818152600f6020908152604080832080546001600160a01b03199081169091556001600160a01b03878116808652600e8552838620805460001901905590871680865283862080546001019055868652600d9094528285208054909216841790915590518493600080516020614f5f83398151915291a4505050565b604080516001808252818301909252606091600091906020808301908036833701905050905082816000815181106129595761295961493e565b602090810291909101015292915050565b60006129758361345c565b61ffff808716600090815260026020908152604080832093891683529290522054909150806129e35760405162461bcd60e51b815260206004820152601a602482015279131e905c1c0e881b5a5b91d85cd31a5b5a5d081b9bdd081cd95d60321b6044820152606401610bba565b6129ed8382614af8565b8210156114e05760405162461bcd60e51b815260206004820152601b60248201527a4c7a4170703a20676173206c696d697420697320746f6f206c6f7760281b6044820152606401610bba565b61ffff861660009081526001602052604081208054612a58906147e7565b80601f0160208091040260200160405190810160405280929190818152602001828054612a84906147e7565b8015612ad15780601f10612aa657610100808354040283529160200191612ad1565b820191906000526020600020905b815481529060010190602001808311612ab457829003601f168201915b50505050509050805160001415612b435760405162461bcd60e51b815260206004820152603060248201527f4c7a4170703a2064657374696e6174696f6e20636861696e206973206e6f742060448201526f61207472757374656420736f7572636560801b6064820152608401610bba565b612b4e8787516134b7565b60405162c5803160e81b81526001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000169063c5803100908490612ba5908b9086908c908c908c908c90600401614d7b565b6000604051808303818588803b158015612bbe57600080fd5b505af1158015612bd2573d6000803e3d6000fd5b505050505050505050505050565b6000845111612c275760405162461bcd60e51b8152602060048201526013602482015272746f6b656e4964735b5d20697320656d70747960681b6044820152606401610bba565b835160011480612c4b575061ffff8616600090815260086020526040902054845111155b612ca25760405162461bcd60e51b815260206004820152602260248201527f62617463682073697a65206578636565647320647374206261746368206c696d6044820152611a5d60f21b6064820152608401610bba565b60005b8451811015612ce557612cd3888888888581518110612cc657612cc661493e565b6020026020010151613525565b80612cdd81614987565b915050612ca5565b5060008585604051602001612cfb929190614c96565b6040516020818303038152906040529050612d40876001848851600960008d61ffff1661ffff16815260200190815260200160002054612d3b9190614ad9565b61296a565b612d4e878286868634612a3a565b85604051612d5c9190614de2565b6040518091039020886001600160a01b03168861ffff167fe1b87c47fdeb4f9cbadbca9df3af7aba453bb6e501075d0440d88125b711522a88604051612da29190614dfe565b60405180910390a45050505050505050565b6000908152600d60205260409020546001600160a01b031690565b60008082806020019051810190612de691906149e7565b601482015191935091506000612dfe88838386612fd0565b90508251811015612ed25784516020808701919091206040805160808101825261ffff808d1682526001600160a01b038088168387019081528385018881526001606086018181526000898152600a909a529887902095518654935190941662010000026001600160b01b03199093169390941692909217178355519082015592516002909301805493151560ff199094169390931790925590517f10e0b70d256bccc84b7027506978bd8b68984a870788b93b479def144c839ad790612ec89083908990614e11565b60405180910390a1505b816001600160a01b031687604051612eea9190614de2565b60405180910390208961ffff167f5b821db8a46f8ecbe1941ba2f51cfeea9643268b56631f70d45e2a745d99026586604051612da29190614dfe565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60026006541415612fc95760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610bba565b6002600655565b6000825b82518110156125aa576007545a1015612fec576125aa565b61301086868584815181106130035761300361493e565b6020026020010151613610565b8061301a81614987565b915050612fd4565b60608161303081601f614af8565b101561306f5760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b6044820152606401610bba565b6130798284614af8565b845110156130bd5760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b6044820152606401610bba565b6060821580156130dc5760405191506000825260208201604052613126565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156131155780518352602092830192016130fd565b5050858452601f01601f1916604052505b50949350505050565b816001600160a01b0316836001600160a01b0316141561318d5760405162461bcd60e51b815260206004820152601960248201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b6044820152606401610bba565b6001600160a01b03838116600081815260106020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611b8d828260405180602001604052806000815250613670565b61321f8484846127cd565b61322b848484846136a3565b611d715760405162461bcd60e51b8152600401610bba90614e2a565b606060138054610da9906147e7565b60606000613263836137a5565b60010190506000816001600160401b0381111561328257613282613d1b565b6040519080825280601f01601f1916602001820160405280156132ac576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846132e5576132ea565b6132b6565b509392505050565b6000606060008060008661ffff166001600160401b0381111561331757613317613d1b565b6040519080825280601f01601f191660200182016040528015613341576020820181803683370190505b50905060008087516020890160008d8df191503d925086831115613363578692505b828152826000602083013e909890975095505050505050565b8180519060200120600560008761ffff1661ffff168152602001908152602001600020856040516133ad9190614de2565b9081526040805191829003602090810183206001600160401b0388166000908152915220919091557fe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c90611cde9087908790879087908790614e7c565b60006001600160e01b031982166322bac5d960e01b1480610d9457506301ffc9a760e01b6001600160e01b0319831614610d94565b60008061344b83612db4565b6001600160a01b0316141592915050565b60006022825110156134af5760405162461bcd60e51b815260206004820152601c60248201527b4c7a4170703a20696e76616c69642061646170746572506172616d7360201b6044820152606401610bba565b506022015190565b61ffff8216600090815260036020526040902054806134d557506127105b80821115610fed5760405162461bcd60e51b815260206004820181905260248201527f4c7a4170703a207061796c6f61642073697a6520697320746f6f206c617267656044820152606401610bba565b61352e3361110e565b6135915760405162461bcd60e51b815260206004820152602e60248201527f4f4e46543732313a2073656e642063616c6c6572206973206e6f74206f776e6560448201526d1c881b9bdc88185c1c1c9bdd995960921b6064820152608401610bba565b836001600160a01b03166135a4826113d8565b6001600160a01b0316146136055760405162461bcd60e51b815260206004820152602260248201527f4f4e46543732313a2073656e642066726f6d20696e636f7272656374206f776e60448201526132b960f11b6064820152608401610bba565b611d718430836127cd565b6136198161343f565b158061364557506136298161343f565b801561364557503061363a826113d8565b6001600160a01b0316145b61364e57600080fd5b6136578161343f565b61366557610fed82826131fa565b610fed3083836127cd565b61367a838361387b565b61368760008484846136a3565b610fed5760405162461bcd60e51b8152600401610bba90614e2a565b60006136b7846001600160a01b03166125b5565b1561379d57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906136ee903390899088908890600401614ece565b6020604051808303816000875af1925050508015613729575060408051601f3d908101601f1916820190925261372691810190614f0b565b60015b613783573d808015613757576040519150601f19603f3d011682016040523d82523d6000602084013e61375c565b606091505b50805161377b5760405162461bcd60e51b8152600401610bba90614e2a565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506125ad565b5060016125ad565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106137e45772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6904ee2d6d415b85acef8160201b831061380e576904ee2d6d415b85acef8160201b830492506020015b662386f26fc10000831061382c57662386f26fc10000830492506010015b6305f5e1008310613844576305f5e100830492506008015b612710831061385857612710830492506004015b6064831061386a576064830492506002015b600a8310610d945760010192915050565b6001600160a01b0382166138d15760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610bba565b6138da8161343f565b156138f75760405162461bcd60e51b8152600401610bba90614f28565b6139008161343f565b1561391d5760405162461bcd60e51b8152600401610bba90614f28565b6001600160a01b0382166000818152600e6020908152604080832080546001019055848352600d90915280822080546001600160a01b031916841790555183929190600080516020614f5f833981519152908290a45050565b828054613982906147e7565b90600052602060002090601f0160209004810192826139a457600085556139ea565b82601f106139bd57805160ff19168380011785556139ea565b828001600101855582156139ea579182015b828111156139ea5782518255916020019190600101906139cf565b506139f6929150613a6e565b5090565b828054613a06906147e7565b90600052602060002090601f016020900481019282613a2857600085556139ea565b82601f10613a415782800160ff198235161785556139ea565b828001600101855582156139ea579182015b828111156139ea578235825591602001919060010190613a53565b5b808211156139f65760008155600101613a6f565b803561ffff81168114613a9557600080fd5b919050565b60008083601f840112613aac57600080fd5b5081356001600160401b03811115613ac357600080fd5b602083019150836020828501011115613adb57600080fd5b9250929050565b80356001600160401b0381168114613a9557600080fd5b60008060008060008060808789031215613b1257600080fd5b613b1b87613a83565b955060208701356001600160401b0380821115613b3757600080fd5b613b438a838b01613a9a565b9097509550859150613b5760408a01613ae2565b94506060890135915080821115613b6d57600080fd5b50613b7a89828a01613a9a565b979a9699509497509295939492505050565b6001600160e01b0319811681146111be57600080fd5b600060208284031215613bb457600080fd5b8135611b6781613b8c565b60005b83811015613bda578181015183820152602001613bc2565b83811115611d715750506000910152565b60008151808452613c03816020860160208601613bbf565b601f01601f19169290920160200192915050565b602081526000611b676020830184613beb565b600060208284031215613c3c57600080fd5b611b6782613a83565b600060208284031215613c5757600080fd5b5035919050565b6001600160a01b0391909116815260200190565b6001600160a01b03811681146111be57600080fd5b8035613a9581613c72565b60008060408385031215613ca557600080fd5b8235613cb081613c72565b946020939093013593505050565b60008060408385031215613cd157600080fd5b613cb083613a83565b600080600060608486031215613cef57600080fd5b8335613cfa81613c72565b92506020840135613d0a81613c72565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613d5957613d59613d1b565b604052919050565b60006001600160401b03821115613d7a57613d7a613d1b565b50601f01601f191660200190565b600082601f830112613d9957600080fd5b8135613dac613da782613d61565b613d31565b818152846020838601011115613dc157600080fd5b816020850160208301376000918101602001919091529392505050565b80358015158114613a9557600080fd5b600080600080600060a08688031215613e0657600080fd5b613e0f86613a83565b945060208601356001600160401b0380821115613e2b57600080fd5b613e3789838a01613d88565b955060408801359450613e4c60608901613dde565b93506080880135915080821115613e6257600080fd5b50613e6f88828901613d88565b9150509295509295909350565b600080600060408486031215613e9157600080fd5b613e9a84613a83565b925060208401356001600160401b03811115613eb557600080fd5b613ec186828701613a9a565b9497909650939450505050565b60008060008060808587031215613ee457600080fd5b613eed85613a83565b93506020850135613efd81613c72565b925060408501356001600160401b0380821115613f1957600080fd5b613f2588838901613d88565b93506060870135915080821115613f3b57600080fd5b50613f4887828801613d88565b91505092959194509250565b600080600080600080600060e0888a031215613f6f57600080fd5b8735613f7a81613c72565b9650613f8860208901613a83565b955060408801356001600160401b0380821115613fa457600080fd5b613fb08b838c01613d88565b965060608a0135955060808a01359150613fc982613c72565b90935060a089013590613fdb82613c72565b90925060c08901359080821115613ff157600080fd5b50613ffe8a828b01613d88565b91505092959891949750929550565b60008060006060848603121561402257600080fd5b61402b84613a83565b925060208401356001600160401b0381111561404657600080fd5b61405286828701613d88565b92505061406160408501613ae2565b90509250925092565b60006020828403121561407c57600080fd5b8135611b6781613c72565b60006001600160401b038211156140a0576140a0613d1b565b5060051b60200190565b600082601f8301126140bb57600080fd5b813560206140cb613da783614087565b82815260059290921b840181019181810190868411156140ea57600080fd5b8286015b848110156141295780356001600160401b0381111561410d5760008081fd5b61411b8986838b0101613d88565b8452509183019183016140ee565b509695505050505050565b6000806040838503121561414757600080fd5b82356001600160401b038082111561415e57600080fd5b818501915085601f83011261417257600080fd5b81356020614182613da783614087565b82815260059290921b840181019181810190898411156141a157600080fd5b948201945b838610156141c6576141b786613a83565b825294820194908201906141a6565b965050860135925050808211156141dc57600080fd5b506141e9858286016140aa565b9150509250929050565b6000806040838503121561420657600080fd5b61420f83613a83565b915061421d60208401613a83565b90509250929050565b60006020828403121561423857600080fd5b81356001600160401b0381111561424e57600080fd5b6125ad84828501613d88565b6000806020838503121561426d57600080fd5b82356001600160401b0381111561428357600080fd5b61428f85828601613a9a565b90969095509350505050565b600080604083850312156142ae57600080fd5b82356142b981613c72565b915061421d60208401613dde565b600082601f8301126142d857600080fd5b813560206142e8613da783614087565b82815260059290921b8401810191818101908684111561430757600080fd5b8286015b84811015614129578035835291830191830161430b565b600080600080600080600060e0888a03121561433d57600080fd5b873561434881613c72565b965061435660208901613a83565b955060408801356001600160401b038082111561437257600080fd5b61437e8b838c01613d88565b965060608a013591508082111561439457600080fd5b6143a08b838c016142c7565b955060808a013591506143b282613c72565b8194506143c160a08b01613c87565b935060c08a0135915080821115613ff157600080fd5b6000806000604084860312156143ec57600080fd5b83356001600160401b0381111561440257600080fd5b61440e86828701613a9a565b909790965060209590950135949350505050565b600080600080600080600080610100898b03121561443f57600080fd5b61444889613c87565b975061445660208a01613a83565b965060408901356001600160401b038082111561447257600080fd5b61447e8c838d01613d88565b975060608b013591508082111561449457600080fd5b6144a08c838d016142c7565b96506144ae60808c01613c87565b95506144bc60a08c01613c87565b945060c08b01359150808211156144d257600080fd5b6144de8c838d01613d88565b935060e08b01359150808211156144f457600080fd5b506145018b828c01613d88565b9150509295985092959890939650565b6000806000806080858703121561452757600080fd5b843561453281613c72565b9350602085013561454281613c72565b92506040850135915060608501356001600160401b0381111561456457600080fd5b613f4887828801613d88565b600080600080600080600080610100898b03121561458d57600080fd5b61459689613c87565b97506145a460208a01613a83565b965060408901356001600160401b03808211156145c057600080fd5b6145cc8c838d01613d88565b975060608b013596506144ae60808c01613c87565b6000806000806000608086880312156145f957600080fd5b61460286613a83565b945061461060208701613a83565b93506040860135925060608601356001600160401b0381111561463257600080fd5b61463e88828901613a9a565b969995985093965092949392505050565b60008060006060848603121561466457600080fd5b61466d84613a83565b925061467b60208501613dde565b915060408401356001600160401b0381111561469657600080fd5b6146a286828701613d88565b9150509250925092565b6000806000606084860312156146c157600080fd5b6146ca84613a83565b92506146d860208501613a83565b9150604084013590509250925092565b600080604083850312156146fb57600080fd5b823561470681613c72565b9150602083013561471681613c72565b809150509250929050565b600080600080600060a0868803121561473957600080fd5b61474286613a83565b945060208601356001600160401b038082111561475e57600080fd5b61476a89838a01613d88565b9550604088013591508082111561478057600080fd5b61478c89838a016142c7565b9450613e4c60608901613dde565b600080600080608085870312156147b057600080fd5b6147b985613a83565b93506147c760208601613a83565b925060408501356147d781613c72565b9396929550929360600135925050565b600181811c908216806147fb57607f821691505b6020821081141561481c57634e487b7160e01b600052602260045260246000fd5b50919050565b8183823760009101908152919050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b61ffff841681526040602082015260006125aa60408301848661487f565b6001600160a01b0392909216825260ff16602082015260400190565b6040815260006148f56040830185613beb565b905060018060a01b03831660208301529392505050565b602080825260189082015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b61ffff831681526040602082015260006125ad6040830184613beb565b634e487b7160e01b600052601160045260246000fd5b600060001982141561499b5761499b614971565b5060010190565b600082601f8301126149b357600080fd5b81516149c1613da782613d61565b8181528460208386010111156149d657600080fd5b6125ad826020830160208701613bbf565b600080604083850312156149fa57600080fd5b82516001600160401b0380821115614a1157600080fd5b614a1d868387016149a2565b9350602091508185015181811115614a3457600080fd5b85019050601f81018613614a4757600080fd5b8051614a55613da782614087565b81815260059190911b82018301908381019088831115614a7457600080fd5b928401925b82841015614a9257835182529284019290840190614a79565b80955050505050509250929050565b600082821015614ab357614ab3614971565b500390565b8284823760609190911b6001600160601b0319169101908152601401919050565b6000816000190483118215151615614af357614af3614971565b500290565b60008219821115614b0b57614b0b614971565b500190565b606081526000614b2460608301868861487f565b6001600160a01b03949094166020830152506040015292915050565b60008351614b52818460208801613bbf565b835190830190614b66818360208801613bbf565b01949350505050565b600061ffff808816835280871660208401525084604083015260806060830152614b9d60808301848661487f565b979650505050505050565b61ffff86168152608060208201526000614bc660808301868861487f565b6001600160401b0394909416604083015250606001529392505050565b61ffff861681526001600160a01b038516602082015260a060408201819052600090614c1190830186613beb565b84151560608401528281036080840152614c2b8185613beb565b98975050505050505050565b60008060408385031215614c4a57600080fd5b505080516020909101519092909150565b600081518084526020808501945080840160005b83811015614c8b57815187529582019590820190600101614c6f565b509495945050505050565b604081526000614ca96040830185613beb565b8281036020840152614cbb8185614c5b565b95945050505050565b600060208284031215614cd657600080fd5b81516001600160401b03811115614cec57600080fd5b6125ad848285016149a2565b61ffff85168152608060208201526000614d156080830186613beb565b6001600160401b03851660408401528281036060840152614b9d8185613beb565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b61ffff8716815260c060208201526000614d9860c0830188613beb565b8281036040840152614daa8188613beb565b6001600160a01b0387811660608601528616608085015283810360a08501529050614dd58185613beb565b9998505050505050505050565b60008251614df4818460208701613bbf565b9190910192915050565b602081526000611b676020830184614c5b565b8281526040602082015260006125ad6040830184613beb565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b61ffff8616815260a060208201526000614e9960a0830187613beb565b6001600160401b03861660408401528281036060840152614eba8186613beb565b90508281036080840152614c2b8185613beb565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090614f0190830184613beb565b9695505050505050565b600060208284031215614f1d57600080fd5b8151611b6781613b8c565b6020808252601c908201527b115490cdcc8c4e881d1bdad95b88185b1c9958591e481b5a5b9d195960221b60408201526060019056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0d28d8d5b183af824884dfca74f986a6a5d684d9c4af1621f0d0754fb54887bfa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470daba2646970667358221220f45c480028e65d4db9530ecb63865b2b72186e5df1833e5bfac2082c826785ed64736f6c634300080c00330000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000186a00000000000000000000000003c2269811836af69497e5f486a85d7316753cf62000000000000000000000000000000000000000000000000000028048c5ec000000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000a43727970746f72616e6b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000343524b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d68747470733a2f2f6170692e63727970746f72616e6b2e696f2f6465646963617465642f776562332f6e66742f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000270000000000000000000000000000000000000000000000000000000000000066000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000006a000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000af00000000000000000000000000000000000000000000000000000000000000b8000000000000000000000000000000000000000000000000000000000000009e0000000000000000000000000000000000000000000000000000000000000091000000000000000000000000000000000000000000000000000000000000006f00000000000000000000000000000000000000000000000000000000000000d6000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000a7000000000000000000000000000000000000000000000000000000000000007d00000000000000000000000000000000000000000000000000000000000000b1000000000000000000000000000000000000000000000000000000000000008a00000000000000000000000000000000000000000000000000000000000000b500000000000000000000000000000000000000000000000000000000000000b70000000000000000000000000000000000000000000000000000000000000096000000000000000000000000000000000000000000000000000000000000009900000000000000000000000000000000000000000000000000000000000000d300000000000000000000000000000000000000000000000000000000000000ca000000000000000000000000000000000000000000000000000000000000009f000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000c300000000000000000000000000000000000000000000000000000000000000a5000000000000000000000000000000000000000000000000000000000000009700000000000000000000000000000000000000000000000000000000000000d400000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000ad00000000000000000000000000000000000000000000000000000000000000c7000000000000000000000000000000000000000000000000000000000000009b00000000000000000000000000000000000000000000000000000000000000d200000000000000000000000000000000000000000000000000000000000000d800000000000000000000000000000000000000000000000000000000000000d900000000000000000000000000000000000000000000000000000000000000e600000000000000000000000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000000f30000000000000000000000000000000000000000000000000000000000000101

Deployed Bytecode

0x6080604052600436106102d25760003560e01c80621d3567146102d757806301ffc9a7146102f957806306fdde031461032e57806307e0db1714610350578063081812fc14610370578063095ea7b31461039d5780630b4cad4c146103bd5780630df37483146103dd57806310ddb137146103fd57806322a3ecf91461041d57806323b872dd146104a05780632a205e3d146104c05780633ccfd60b146104f55780633d8b38f61461050a5780633f1f4fa41461052a57806342842e0e1461056557806342d65a8d14610585578063468fa2af146105a557806348288190146105b85780634ac3f4ff146105ce57806351905636146105fb5780635b8c41e61461060e5780636352211e1461065d57806366ad5c8a1461067d57806369fe0e2d1461069d5780636aa99da3146106bd57806370a08231146106d3578063715018a6146106f35780637533d7881461070857806376fffcd0146107285780638cfd8f5c146107485780638da5cb5b146107805780638ffa1f2a14610795578063950c8a74146107b557806395d89b41146107d55780639abc8320146107ea5780639ea5d6b1146107ff5780639f38369a1461081f578063a0bcfc7f1461083f578063a22cb4651461085f578063a6c3d1651461087f578063ab3ffb931461089f578063ac37cf53146108b2578063af3fb21c146108c5578063b353aaa7146108ed578063b770f98414610921578063b88d4fde14610934578063baf3292d14610954578063c446183414610974578063c7565b011461098a578063c87b56dd1461099d578063cbed8b9c146109bd578063d12473a5146109dd578063d1deba1f146109fd578063d85d3d2714610a10578063da09f15d14610a23578063ddca3f4314610a43578063df2a5b3b14610a59578063e985e9c514610a79578063eb8d72b714610a99578063f235364114610ab9578063f2fde38b14610ad9578063f5ecbdbc14610af9578063fa25f9b614610b19575b600080fd5b3480156102e357600080fd5b506102f76102f2366004613af9565b610b46565b005b34801561030557600080fd5b50610319610314366004613ba2565b610d77565b60405190151581526020015b60405180910390f35b34801561033a57600080fd5b50610343610d9a565b6040516103259190613c17565b34801561035c57600080fd5b506102f761036b366004613c2a565b610e2c565b34801561037c57600080fd5b5061039061038b366004613c45565b610eb5565b6040516103259190613c5e565b3480156103a957600080fd5b506102f76103b8366004613c92565b610edc565b3480156103c957600080fd5b506102f76103d8366004613c45565b610ff2565b3480156103e957600080fd5b506102f76103f8366004613cbe565b611092565b34801561040957600080fd5b506102f7610418366004613c2a565b6110b1565b34801561042957600080fd5b50610471610438366004613c45565b600a6020526000908152604090208054600182015460029092015461ffff821692620100009092046001600160a01b0316919060ff1684565b6040805161ffff90951685526001600160a01b0390931660208501529183015215156060820152608001610325565b3480156104ac57600080fd5b506102f76104bb366004613cda565b611109565b3480156104cc57600080fd5b506104e06104db366004613dee565b61113b565b60408051928352602083019190915201610325565b34801561050157600080fd5b506102f7611161565b34801561051657600080fd5b50610319610525366004613e7c565b6111c1565b34801561053657600080fd5b50610557610545366004613c2a565b60036020526000908152604090205481565b604051908152602001610325565b34801561057157600080fd5b506102f7610580366004613cda565b61128d565b34801561059157600080fd5b506102f76105a0366004613e7c565b6112a8565b6102f76105b3366004613ece565b61132e565b3480156105c457600080fd5b5061055760075481565b3480156105da57600080fd5b506105576105e9366004613c2a565b60086020526000908152604090205481565b6102f7610609366004613f54565b6113c1565b34801561061a57600080fd5b5061055761062936600461400d565b6005602090815260009384526040808520845180860184018051928152908401958401959095209452929052825290205481565b34801561066957600080fd5b50610390610678366004613c45565b6113d8565b34801561068957600080fd5b506102f7610698366004613af9565b61140c565b3480156106a957600080fd5b506102f76106b8366004613c45565b6114e8565b3480156106c957600080fd5b5061055760125481565b3480156106df57600080fd5b506105576106ee36600461406a565b6114f5565b3480156106ff57600080fd5b506102f761157b565b34801561071457600080fd5b50610343610723366004613c2a565b61158f565b34801561073457600080fd5b506102f7610743366004614134565b611629565b34801561075457600080fd5b506105576107633660046141f3565b600260209081526000928352604080842090915290825290205481565b34801561078c57600080fd5b5061039061172c565b3480156107a157600080fd5b506102f76107b0366004614226565b61173b565b3480156107c157600080fd5b50600454610390906001600160a01b031681565b3480156107e157600080fd5b50610343611984565b3480156107f657600080fd5b50610343611993565b34801561080b57600080fd5b506102f761081a366004613cbe565b6119a0565b34801561082b57600080fd5b5061034361083a366004613c2a565b611a57565b34801561084b57600080fd5b506102f761085a36600461425a565b611b6e565b34801561086b57600080fd5b506102f761087a36600461429b565b611b82565b34801561088b57600080fd5b506102f761089a366004613e7c565b611b91565b6102f76108ad366004614322565b611c24565b6102f76108c03660046143d7565b611c33565b3480156108d157600080fd5b506108da600181565b60405161ffff9091168152602001610325565b3480156108f957600080fd5b506103907f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf6281565b6102f761092f366004614422565b611ced565b34801561094057600080fd5b506102f761094f366004614511565b611d3f565b34801561096057600080fd5b506102f761096f36600461406a565b611d77565b34801561098057600080fd5b5061055761271081565b6102f7610998366004614570565b611dca565b3480156109a957600080fd5b506103436109b8366004613c45565b611de1565b3480156109c957600080fd5b506102f76109d83660046145e1565b611e47565b3480156109e957600080fd5b506102f76109f8366004613cbe565b611edc565b6102f7610a0b366004613af9565b611f8c565b6102f7610a1e36600461425a565b6121a2565b348015610a2f57600080fd5b506104e0610a3e36600461464f565b612217565b348015610a4f57600080fd5b5061055760115481565b348015610a6557600080fd5b506102f7610a743660046146ac565b6122e1565b348015610a8557600080fd5b50610319610a943660046146e8565b61234b565b348015610aa557600080fd5b506102f7610ab4366004613e7c565b612379565b348015610ac557600080fd5b506104e0610ad4366004614721565b6123c1565b348015610ae557600080fd5b506102f7610af436600461406a565b61248c565b348015610b0557600080fd5b50610343610b1436600461479a565b612502565b348015610b2557600080fd5b50610557610b34366004613c2a565b60096020526000908152604090205481565b337f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf626001600160a01b031614610bc35760405162461bcd60e51b815260206004820152601e60248201527f4c7a4170703a20696e76616c696420656e64706f696e742063616c6c6572000060448201526064015b60405180910390fd5b61ffff861660009081526001602052604081208054610be1906147e7565b80601f0160208091040260200160405190810160405280929190818152602001828054610c0d906147e7565b8015610c5a5780601f10610c2f57610100808354040283529160200191610c5a565b820191906000526020600020905b815481529060010190602001808311610c3d57829003601f168201915b50505050509050805186869050148015610c75575060008151115b8015610c9d575080516020820120604051610c939088908890614822565b6040518091039020145b610cf85760405162461bcd60e51b815260206004820152602660248201527f4c7a4170703a20696e76616c696420736f757263652073656e64696e6720636f6044820152651b9d1c9858dd60d21b6064820152608401610bba565b610d6e8787878080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f8a018190048102820181019092528881528a9350915088908890819084018382808284376000920191909152506125c492505050565b50505050505050565b60006001600160e01b031982161580610d945750610d948261263d565b92915050565b6060600b8054610da9906147e7565b80601f0160208091040260200160405190810160405280929190818152602001828054610dd5906147e7565b8015610e225780601f10610df757610100808354040283529160200191610e22565b820191906000526020600020905b815481529060010190602001808311610e0557829003601f168201915b5050505050905090565b610e3461267d565b6040516307e0db1760e01b815261ffff821660048201527f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf626001600160a01b0316906307e0db17906024015b600060405180830381600087803b158015610e9a57600080fd5b505af1158015610eae573d6000803e3d6000fd5b5050505050565b6000610ec0826126dc565b506000908152600f60205260409020546001600160a01b031690565b6000610ee7826113d8565b9050806001600160a01b0316836001600160a01b03161415610f555760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610bba565b336001600160a01b0382161480610f715750610f71813361234b565b610fe35760405162461bcd60e51b815260206004820152603d60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206f7220617070726f76656420666f7220616c6c0000006064820152608401610bba565b610fed8383612701565b505050565b610ffa61267d565b600081116110565760405162461bcd60e51b8152602060048201526024808201527f6d696e476173546f5472616e73666572416e6453746f7265206d7573742062656044820152630203e20360e41b6064820152608401610bba565b60078190556040518181527ffebbc4f8bb9ec2313950c718d43123124b15778efda4c1f1d529de2995b4f34d906020015b60405180910390a150565b61109a61267d565b61ffff909116600090815260036020526040902055565b6110b961267d565b6040516310ddb13760e01b815261ffff821660048201527f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf626001600160a01b0316906310ddb13790602401610e80565b611114335b8261276f565b6111305760405162461bcd60e51b8152600401610bba90614832565b610fed8383836127cd565b600080611153878761114c8861291f565b87876123c1565b915091509550959350505050565b61116961267d565b604051600090339047908381818185875af1925050503d80600081146111ab576040519150601f19603f3d011682016040523d82523d6000602084013e6111b0565b606091505b50509050806111be57600080fd5b50565b61ffff8316600090815260016020526040812080548291906111e2906147e7565b80601f016020809104026020016040519081016040528092919081815260200182805461120e906147e7565b801561125b5780601f106112305761010080835404028352916020019161125b565b820191906000526020600020905b81548152906001019060200180831161123e57829003601f168201915b505050505090508383604051611272929190614822565b60405180910390208180519060200120149150509392505050565b610fed83838360405180602001604052806000815250611d3f565b6112b061267d565b6040516342d65a8d60e01b81526001600160a01b037f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf6216906342d65a8d90611300908690869086906004016148a8565b600060405180830381600087803b15801561131a57600080fd5b505af1158015610d6e573d6000803e3d6000fd5b61ffff8416600090815260096020526040902054611352908590600190859061296a565b6113828433600060405160200161136a9291906148c6565b60405160208183030381529060405230868634612a3a565b7f5720f01742c072b3cf489909863e630a6bdead9fe5ff36bbadbfc6f442c928c681336040516113b39291906148e2565b60405180910390a150505050565b610d6e8787876113d08861291f565b878787612be0565b6000806113e483612db4565b90506001600160a01b038116610d945760405162461bcd60e51b8152600401610bba9061490c565b33301461146a5760405162461bcd60e51b815260206004820152602660248201527f4e6f6e626c6f636b696e674c7a4170703a2063616c6c6572206d7573742062656044820152650204c7a4170760d41b6064820152608401610bba565b6114e08686868080601f01602080910402602001604051908101604052809392919081815260200183838082843760009201919091525050604080516020601f890181900481028201810190925287815289935091508790879081908401838280828437600092019190915250612dcf92505050565b505050505050565b6114f061267d565b601155565b60006001600160a01b03821661155f5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b6064820152608401610bba565b506001600160a01b03166000908152600e602052604090205490565b61158361267d565b61158d6000612f26565b565b600160205260009081526040902080546115a8906147e7565b80601f01602080910402602001604051908101604052809291908181526020018280546115d4906147e7565b80156116215780601f106115f657610100808354040283529160200191611621565b820191906000526020600020905b81548152906001019060200180831161160457829003601f168201915b505050505081565b61163161267d565b80518251146116535760405163440de63f60e01b815260040160405180910390fd5b60005b8251811015610fed578181815181106116715761167161493e565b60200260200101516001600085848151811061168f5761168f61493e565b602002602001015161ffff1661ffff16815260200190815260200160002090805190602001906116c0929190613976565b50600080516020614f9f8339815191528382815181106116e2576116e261493e565b60200260200101518383815181106116fc576116fc61493e565b6020026020010151604051611712929190614954565b60405180910390a18061172481614987565b915050611656565b6000546001600160a01b031690565b611743612f76565b80516020808301919091206000818152600a90925260409091206002015460ff166117a45760405162461bcd60e51b81526020600482015260116024820152701b9bc818dc99591a5d1cc81cdd1bdc9959607a1b6044820152606401610bba565b6000828060200190518101906117ba91906149e7565b6000848152600a6020526040812080546001909101549294509092506117f69161ffff8216916201000090046001600160a01b03169085612fd0565b6000848152600a6020526040902060010154909150811161186b5760405162461bcd60e51b815260206004820152602960248201527f6e6f7420656e6f7567682067617320746f2070726f6365737320637265646974604482015268103a3930b739b332b960b91b6064820152608401610bba565b81518114156118e3576000838152600a602052604080822080546001600160b01b031916815560018101929092556002909101805460ff19169055517fd7be02b8dd0d27bd0517a9cb4d7469ce27df4313821ae5ec1ff69acc594ba233906118d69085815260200190565b60405180910390a1611977565b604080516080810182526000858152600a6020818152848320805461ffff80821687526001600160a01b03620100008084048216868a019081529989018b8152600160608b01818152998f90529790965297519851169096026001600160b01b03199091169690951695909517939093178455915191830191909155516002909101805491151560ff199092169190911790555b5050506111be6001600655565b6060600c8054610da9906147e7565b601380546115a8906147e7565b6119a861267d565b60008111611a035760405162461bcd60e51b815260206004820152602260248201527f647374436861696e4964546f42617463684c696d6974206d757374206265203e604482015261020360f41b6064820152608401610bba565b61ffff8216600081815260086020908152604091829020849055815192835282018390527f7315f7654d594ead24a30160ed9ba2d23247f543016b918343591e93d7afdb6d91015b60405180910390a15050565b61ffff8116600090815260016020526040812080546060929190611a7a906147e7565b80601f0160208091040260200160405190810160405280929190818152602001828054611aa6906147e7565b8015611af35780601f10611ac857610100808354040283529160200191611af3565b820191906000526020600020905b815481529060010190602001808311611ad657829003601f168201915b50505050509050805160001415611b4c5760405162461bcd60e51b815260206004820152601d60248201527f4c7a4170703a206e6f20747275737465642070617468207265636f72640000006044820152606401610bba565b611b67600060148351611b5f9190614aa1565b839190613022565b9392505050565b611b7661267d565b610fed601383836139fa565b611b8d33838361312f565b5050565b611b9961267d565b818130604051602001611bae93929190614ab8565b60408051601f1981840301815291815261ffff85166000908152600160209081529190208251611be393919290910190613976565b507f8c0400cfe2d1199b1a725c78960bcc2a344d869b80590d0f2bd005db15a572ce838383604051611c17939291906148a8565b60405180910390a1505050565b610d6e87878787878787612be0565b600081601154611c439190614ad9565b905080341015611c6f5760405163b99e2ab760e01b815260048101829052346024820152604401610bba565b60125460005b83811015611ca257611c9033611c8b8385614af8565b6131fa565b80611c9a81614987565b915050611c75565b508260126000828254611cb59190614af8565b9091555050604051600080516020614f7f83398151915290611cde908790879033908890614b10565b60405180910390a15050505050565b611cfc88888888888888612be0565b7f5ab1a06533ffe44ad2e290926a22350e1916f557908cef6b3c9debca9119287e8133604051611d2d9291906148e2565b60405180910390a15050505050505050565b611d49338361276f565b611d655760405162461bcd60e51b8152600401610bba90614832565b611d7184848484613214565b50505050565b611d7f61267d565b600480546001600160a01b0319166001600160a01b0383161790556040517f5db758e995a17ec1ad84bdef7e8c3293a0bd6179bcce400dff5d4c3d87db726b90611087908390613c5e565b611cfc888888611dd98961291f565b888888612be0565b6060611dec826126dc565b6000611df6613247565b90506000815111611e165760405180602001604052806000815250611b67565b80611e2084613256565b604051602001611e31929190614b40565b6040516020818303038152906040529392505050565b611e4f61267d565b6040516332fb62e760e21b81526001600160a01b037f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf62169063cbed8b9c90611ea39088908890889088908890600401614b6f565b600060405180830381600087803b158015611ebd57600080fd5b505af1158015611ed1573d6000803e3d6000fd5b505050505050505050565b611ee461267d565b60008111611f405760405162461bcd60e51b815260206004820152602360248201527f647374436861696e4964546f5472616e73666572476173206d7573742062652060448201526203e20360ec1b6064820152608401610bba565b61ffff8216600081815260096020908152604091829020849055815192835282018390527fc46df2983228ac2d9754e94a0d565e6671665dc8ad38602bc8e544f0685a29fb9101611a4b565b61ffff86166000908152600560205260408082209051611faf9088908890614822565b90815260408051602092819003830190206001600160401b0387166000908152925290205490508061202f5760405162461bcd60e51b815260206004820152602360248201527f4e6f6e626c6f636b696e674c7a4170703a206e6f2073746f726564206d65737360448201526261676560e81b6064820152608401610bba565b808383604051612040929190614822565b60405180910390201461209f5760405162461bcd60e51b815260206004820152602160248201527f4e6f6e626c6f636b696e674c7a4170703a20696e76616c6964207061796c6f616044820152601960fa1b6064820152608401610bba565b61ffff871660009081526005602052604080822090516120c29089908990614822565b90815260408051602092819003830181206001600160401b038916600090815290845282902093909355601f8801829004820283018201905286825261215a918991899089908190840183828082843760009201919091525050604080516020601f8a018190048102820181019092528881528a935091508890889081908401838280828437600092019190915250612dcf92505050565b7fc264d91f3adc5588250e1551f547752ca0cfa8f6b530d243b9f9f4cab10ea8e58787878785604051612191959493929190614ba8565b60405180910390a150505050505050565b6011543410156121d25760115460405163b99e2ab760e01b81526004810191909152346024820152604401610bba565b6012805490819060006121e483614987565b91905055506121f333826131fa565b600080516020614f7f8339815191528383336001604051611c179493929190614b10565b60008060003360006040516020016122309291906148c6565b60408051601f198184030181529082905263040a7bb160e41b825291506001600160a01b037f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf6216906340a7bb1090612294908990309086908b908b90600401614be3565b6040805180830381865afa1580156122b0573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906122d49190614c37565b9250925050935093915050565b6122e961267d565b61ffff83811660008181526002602090815260408083209487168084529482529182902085905581519283528201929092529081018290527f9d5c7c0b934da8fefa9c7760c98383778a12dfbfc0c3b3106518f43fb9508ac090606001611c17565b6001600160a01b03918216600090815260106020908152604080832093909416825291909152205460ff1690565b61238161267d565b61ffff8316600090815260016020526040902061239f9083836139fa565b50600080516020614f9f833981519152838383604051611c17939291906148a8565b600080600086866040516020016123d9929190614c96565b60408051601f198184030181529082905263040a7bb160e41b825291506001600160a01b037f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf6216906340a7bb109061243d908b90309086908b908b90600401614be3565b6040805180830381865afa158015612459573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061247d9190614c37565b92509250509550959350505050565b61249461267d565b6001600160a01b0381166124f95760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610bba565b6111be81612f26565b604051633d7b2f6f60e21b815261ffff808616600483015284166024820152306044820152606481018290526060907f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf626001600160a01b03169063f5ecbdbc90608401600060405180830381865afa158015612582573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f191682016040526125aa9190810190614cc4565b90505b949350505050565b6001600160a01b03163b151590565b6000806126275a60966366ad5c8a60e01b898989896040516024016125ec9493929190614cf8565b60408051601f198184030181529190526020810180516001600160e01b03166001600160e01b031990931692909217909152309291906132f2565b91509150816114e0576114e0868686868561337c565b60006001600160e01b031982166380ac58cd60e01b148061266e57506001600160e01b03198216635b5e139f60e01b145b80610d945750610d948261340a565b3361268661172c565b6001600160a01b03161461158d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726044820152606401610bba565b6126e58161343f565b6111be5760405162461bcd60e51b8152600401610bba9061490c565b6000818152600f6020526040902080546001600160a01b0319166001600160a01b0384169081179091558190612736826113d8565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008061277b836113d8565b9050806001600160a01b0316846001600160a01b031614806127a257506127a2818561234b565b806125ad5750836001600160a01b03166127bb84610eb5565b6001600160a01b031614949350505050565b826001600160a01b03166127e0826113d8565b6001600160a01b0316146128065760405162461bcd60e51b8152600401610bba90614d36565b6001600160a01b0382166128685760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610bba565b826001600160a01b031661287b826113d8565b6001600160a01b0316146128a15760405162461bcd60e51b8152600401610bba90614d36565b6000818152600f6020908152604080832080546001600160a01b03199081169091556001600160a01b03878116808652600e8552838620805460001901905590871680865283862080546001019055868652600d9094528285208054909216841790915590518493600080516020614f5f83398151915291a4505050565b604080516001808252818301909252606091600091906020808301908036833701905050905082816000815181106129595761295961493e565b602090810291909101015292915050565b60006129758361345c565b61ffff808716600090815260026020908152604080832093891683529290522054909150806129e35760405162461bcd60e51b815260206004820152601a602482015279131e905c1c0e881b5a5b91d85cd31a5b5a5d081b9bdd081cd95d60321b6044820152606401610bba565b6129ed8382614af8565b8210156114e05760405162461bcd60e51b815260206004820152601b60248201527a4c7a4170703a20676173206c696d697420697320746f6f206c6f7760281b6044820152606401610bba565b61ffff861660009081526001602052604081208054612a58906147e7565b80601f0160208091040260200160405190810160405280929190818152602001828054612a84906147e7565b8015612ad15780601f10612aa657610100808354040283529160200191612ad1565b820191906000526020600020905b815481529060010190602001808311612ab457829003601f168201915b50505050509050805160001415612b435760405162461bcd60e51b815260206004820152603060248201527f4c7a4170703a2064657374696e6174696f6e20636861696e206973206e6f742060448201526f61207472757374656420736f7572636560801b6064820152608401610bba565b612b4e8787516134b7565b60405162c5803160e81b81526001600160a01b037f0000000000000000000000003c2269811836af69497e5f486a85d7316753cf62169063c5803100908490612ba5908b9086908c908c908c908c90600401614d7b565b6000604051808303818588803b158015612bbe57600080fd5b505af1158015612bd2573d6000803e3d6000fd5b505050505050505050505050565b6000845111612c275760405162461bcd60e51b8152602060048201526013602482015272746f6b656e4964735b5d20697320656d70747960681b6044820152606401610bba565b835160011480612c4b575061ffff8616600090815260086020526040902054845111155b612ca25760405162461bcd60e51b815260206004820152602260248201527f62617463682073697a65206578636565647320647374206261746368206c696d6044820152611a5d60f21b6064820152608401610bba565b60005b8451811015612ce557612cd3888888888581518110612cc657612cc661493e565b6020026020010151613525565b80612cdd81614987565b915050612ca5565b5060008585604051602001612cfb929190614c96565b6040516020818303038152906040529050612d40876001848851600960008d61ffff1661ffff16815260200190815260200160002054612d3b9190614ad9565b61296a565b612d4e878286868634612a3a565b85604051612d5c9190614de2565b6040518091039020886001600160a01b03168861ffff167fe1b87c47fdeb4f9cbadbca9df3af7aba453bb6e501075d0440d88125b711522a88604051612da29190614dfe565b60405180910390a45050505050505050565b6000908152600d60205260409020546001600160a01b031690565b60008082806020019051810190612de691906149e7565b601482015191935091506000612dfe88838386612fd0565b90508251811015612ed25784516020808701919091206040805160808101825261ffff808d1682526001600160a01b038088168387019081528385018881526001606086018181526000898152600a909a529887902095518654935190941662010000026001600160b01b03199093169390941692909217178355519082015592516002909301805493151560ff199094169390931790925590517f10e0b70d256bccc84b7027506978bd8b68984a870788b93b479def144c839ad790612ec89083908990614e11565b60405180910390a1505b816001600160a01b031687604051612eea9190614de2565b60405180910390208961ffff167f5b821db8a46f8ecbe1941ba2f51cfeea9643268b56631f70d45e2a745d99026586604051612da29190614dfe565b600080546001600160a01b038381166001600160a01b0319831681178455604051919092169283917f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e09190a35050565b60026006541415612fc95760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c006044820152606401610bba565b6002600655565b6000825b82518110156125aa576007545a1015612fec576125aa565b61301086868584815181106130035761300361493e565b6020026020010151613610565b8061301a81614987565b915050612fd4565b60608161303081601f614af8565b101561306f5760405162461bcd60e51b815260206004820152600e60248201526d736c6963655f6f766572666c6f7760901b6044820152606401610bba565b6130798284614af8565b845110156130bd5760405162461bcd60e51b8152602060048201526011602482015270736c6963655f6f75744f66426f756e647360781b6044820152606401610bba565b6060821580156130dc5760405191506000825260208201604052613126565b6040519150601f8416801560200281840101858101878315602002848b0101015b818310156131155780518352602092830192016130fd565b5050858452601f01601f1916604052505b50949350505050565b816001600160a01b0316836001600160a01b0316141561318d5760405162461bcd60e51b815260206004820152601960248201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b6044820152606401610bba565b6001600160a01b03838116600081815260106020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611b8d828260405180602001604052806000815250613670565b61321f8484846127cd565b61322b848484846136a3565b611d715760405162461bcd60e51b8152600401610bba90614e2a565b606060138054610da9906147e7565b60606000613263836137a5565b60010190506000816001600160401b0381111561328257613282613d1b565b6040519080825280601f01601f1916602001820160405280156132ac576020820181803683370190505b5090508181016020015b600019016f181899199a1a9b1b9c1cb0b131b232b360811b600a86061a8153600a85049450846132e5576132ea565b6132b6565b509392505050565b6000606060008060008661ffff166001600160401b0381111561331757613317613d1b565b6040519080825280601f01601f191660200182016040528015613341576020820181803683370190505b50905060008087516020890160008d8df191503d925086831115613363578692505b828152826000602083013e909890975095505050505050565b8180519060200120600560008761ffff1661ffff168152602001908152602001600020856040516133ad9190614de2565b9081526040805191829003602090810183206001600160401b0388166000908152915220919091557fe183f33de2837795525b4792ca4cd60535bd77c53b7e7030060bfcf5734d6b0c90611cde9087908790879087908790614e7c565b60006001600160e01b031982166322bac5d960e01b1480610d9457506301ffc9a760e01b6001600160e01b0319831614610d94565b60008061344b83612db4565b6001600160a01b0316141592915050565b60006022825110156134af5760405162461bcd60e51b815260206004820152601c60248201527b4c7a4170703a20696e76616c69642061646170746572506172616d7360201b6044820152606401610bba565b506022015190565b61ffff8216600090815260036020526040902054806134d557506127105b80821115610fed5760405162461bcd60e51b815260206004820181905260248201527f4c7a4170703a207061796c6f61642073697a6520697320746f6f206c617267656044820152606401610bba565b61352e3361110e565b6135915760405162461bcd60e51b815260206004820152602e60248201527f4f4e46543732313a2073656e642063616c6c6572206973206e6f74206f776e6560448201526d1c881b9bdc88185c1c1c9bdd995960921b6064820152608401610bba565b836001600160a01b03166135a4826113d8565b6001600160a01b0316146136055760405162461bcd60e51b815260206004820152602260248201527f4f4e46543732313a2073656e642066726f6d20696e636f7272656374206f776e60448201526132b960f11b6064820152608401610bba565b611d718430836127cd565b6136198161343f565b158061364557506136298161343f565b801561364557503061363a826113d8565b6001600160a01b0316145b61364e57600080fd5b6136578161343f565b61366557610fed82826131fa565b610fed3083836127cd565b61367a838361387b565b61368760008484846136a3565b610fed5760405162461bcd60e51b8152600401610bba90614e2a565b60006136b7846001600160a01b03166125b5565b1561379d57604051630a85bd0160e11b81526001600160a01b0385169063150b7a02906136ee903390899088908890600401614ece565b6020604051808303816000875af1925050508015613729575060408051601f3d908101601f1916820190925261372691810190614f0b565b60015b613783573d808015613757576040519150601f19603f3d011682016040523d82523d6000602084013e61375c565b606091505b50805161377b5760405162461bcd60e51b8152600401610bba90614e2a565b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490506125ad565b5060016125ad565b60008072184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b83106137e45772184f03e93ff9f4daa797ed6e38ed64bf6a1f0160401b830492506040015b6904ee2d6d415b85acef8160201b831061380e576904ee2d6d415b85acef8160201b830492506020015b662386f26fc10000831061382c57662386f26fc10000830492506010015b6305f5e1008310613844576305f5e100830492506008015b612710831061385857612710830492506004015b6064831061386a576064830492506002015b600a8310610d945760010192915050565b6001600160a01b0382166138d15760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610bba565b6138da8161343f565b156138f75760405162461bcd60e51b8152600401610bba90614f28565b6139008161343f565b1561391d5760405162461bcd60e51b8152600401610bba90614f28565b6001600160a01b0382166000818152600e6020908152604080832080546001019055848352600d90915280822080546001600160a01b031916841790555183929190600080516020614f5f833981519152908290a45050565b828054613982906147e7565b90600052602060002090601f0160209004810192826139a457600085556139ea565b82601f106139bd57805160ff19168380011785556139ea565b828001600101855582156139ea579182015b828111156139ea5782518255916020019190600101906139cf565b506139f6929150613a6e565b5090565b828054613a06906147e7565b90600052602060002090601f016020900481019282613a2857600085556139ea565b82601f10613a415782800160ff198235161785556139ea565b828001600101855582156139ea579182015b828111156139ea578235825591602001919060010190613a53565b5b808211156139f65760008155600101613a6f565b803561ffff81168114613a9557600080fd5b919050565b60008083601f840112613aac57600080fd5b5081356001600160401b03811115613ac357600080fd5b602083019150836020828501011115613adb57600080fd5b9250929050565b80356001600160401b0381168114613a9557600080fd5b60008060008060008060808789031215613b1257600080fd5b613b1b87613a83565b955060208701356001600160401b0380821115613b3757600080fd5b613b438a838b01613a9a565b9097509550859150613b5760408a01613ae2565b94506060890135915080821115613b6d57600080fd5b50613b7a89828a01613a9a565b979a9699509497509295939492505050565b6001600160e01b0319811681146111be57600080fd5b600060208284031215613bb457600080fd5b8135611b6781613b8c565b60005b83811015613bda578181015183820152602001613bc2565b83811115611d715750506000910152565b60008151808452613c03816020860160208601613bbf565b601f01601f19169290920160200192915050565b602081526000611b676020830184613beb565b600060208284031215613c3c57600080fd5b611b6782613a83565b600060208284031215613c5757600080fd5b5035919050565b6001600160a01b0391909116815260200190565b6001600160a01b03811681146111be57600080fd5b8035613a9581613c72565b60008060408385031215613ca557600080fd5b8235613cb081613c72565b946020939093013593505050565b60008060408385031215613cd157600080fd5b613cb083613a83565b600080600060608486031215613cef57600080fd5b8335613cfa81613c72565b92506020840135613d0a81613c72565b929592945050506040919091013590565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b0381118282101715613d5957613d59613d1b565b604052919050565b60006001600160401b03821115613d7a57613d7a613d1b565b50601f01601f191660200190565b600082601f830112613d9957600080fd5b8135613dac613da782613d61565b613d31565b818152846020838601011115613dc157600080fd5b816020850160208301376000918101602001919091529392505050565b80358015158114613a9557600080fd5b600080600080600060a08688031215613e0657600080fd5b613e0f86613a83565b945060208601356001600160401b0380821115613e2b57600080fd5b613e3789838a01613d88565b955060408801359450613e4c60608901613dde565b93506080880135915080821115613e6257600080fd5b50613e6f88828901613d88565b9150509295509295909350565b600080600060408486031215613e9157600080fd5b613e9a84613a83565b925060208401356001600160401b03811115613eb557600080fd5b613ec186828701613a9a565b9497909650939450505050565b60008060008060808587031215613ee457600080fd5b613eed85613a83565b93506020850135613efd81613c72565b925060408501356001600160401b0380821115613f1957600080fd5b613f2588838901613d88565b93506060870135915080821115613f3b57600080fd5b50613f4887828801613d88565b91505092959194509250565b600080600080600080600060e0888a031215613f6f57600080fd5b8735613f7a81613c72565b9650613f8860208901613a83565b955060408801356001600160401b0380821115613fa457600080fd5b613fb08b838c01613d88565b965060608a0135955060808a01359150613fc982613c72565b90935060a089013590613fdb82613c72565b90925060c08901359080821115613ff157600080fd5b50613ffe8a828b01613d88565b91505092959891949750929550565b60008060006060848603121561402257600080fd5b61402b84613a83565b925060208401356001600160401b0381111561404657600080fd5b61405286828701613d88565b92505061406160408501613ae2565b90509250925092565b60006020828403121561407c57600080fd5b8135611b6781613c72565b60006001600160401b038211156140a0576140a0613d1b565b5060051b60200190565b600082601f8301126140bb57600080fd5b813560206140cb613da783614087565b82815260059290921b840181019181810190868411156140ea57600080fd5b8286015b848110156141295780356001600160401b0381111561410d5760008081fd5b61411b8986838b0101613d88565b8452509183019183016140ee565b509695505050505050565b6000806040838503121561414757600080fd5b82356001600160401b038082111561415e57600080fd5b818501915085601f83011261417257600080fd5b81356020614182613da783614087565b82815260059290921b840181019181810190898411156141a157600080fd5b948201945b838610156141c6576141b786613a83565b825294820194908201906141a6565b965050860135925050808211156141dc57600080fd5b506141e9858286016140aa565b9150509250929050565b6000806040838503121561420657600080fd5b61420f83613a83565b915061421d60208401613a83565b90509250929050565b60006020828403121561423857600080fd5b81356001600160401b0381111561424e57600080fd5b6125ad84828501613d88565b6000806020838503121561426d57600080fd5b82356001600160401b0381111561428357600080fd5b61428f85828601613a9a565b90969095509350505050565b600080604083850312156142ae57600080fd5b82356142b981613c72565b915061421d60208401613dde565b600082601f8301126142d857600080fd5b813560206142e8613da783614087565b82815260059290921b8401810191818101908684111561430757600080fd5b8286015b84811015614129578035835291830191830161430b565b600080600080600080600060e0888a03121561433d57600080fd5b873561434881613c72565b965061435660208901613a83565b955060408801356001600160401b038082111561437257600080fd5b61437e8b838c01613d88565b965060608a013591508082111561439457600080fd5b6143a08b838c016142c7565b955060808a013591506143b282613c72565b8194506143c160a08b01613c87565b935060c08a0135915080821115613ff157600080fd5b6000806000604084860312156143ec57600080fd5b83356001600160401b0381111561440257600080fd5b61440e86828701613a9a565b909790965060209590950135949350505050565b600080600080600080600080610100898b03121561443f57600080fd5b61444889613c87565b975061445660208a01613a83565b965060408901356001600160401b038082111561447257600080fd5b61447e8c838d01613d88565b975060608b013591508082111561449457600080fd5b6144a08c838d016142c7565b96506144ae60808c01613c87565b95506144bc60a08c01613c87565b945060c08b01359150808211156144d257600080fd5b6144de8c838d01613d88565b935060e08b01359150808211156144f457600080fd5b506145018b828c01613d88565b9150509295985092959890939650565b6000806000806080858703121561452757600080fd5b843561453281613c72565b9350602085013561454281613c72565b92506040850135915060608501356001600160401b0381111561456457600080fd5b613f4887828801613d88565b600080600080600080600080610100898b03121561458d57600080fd5b61459689613c87565b97506145a460208a01613a83565b965060408901356001600160401b03808211156145c057600080fd5b6145cc8c838d01613d88565b975060608b013596506144ae60808c01613c87565b6000806000806000608086880312156145f957600080fd5b61460286613a83565b945061461060208701613a83565b93506040860135925060608601356001600160401b0381111561463257600080fd5b61463e88828901613a9a565b969995985093965092949392505050565b60008060006060848603121561466457600080fd5b61466d84613a83565b925061467b60208501613dde565b915060408401356001600160401b0381111561469657600080fd5b6146a286828701613d88565b9150509250925092565b6000806000606084860312156146c157600080fd5b6146ca84613a83565b92506146d860208501613a83565b9150604084013590509250925092565b600080604083850312156146fb57600080fd5b823561470681613c72565b9150602083013561471681613c72565b809150509250929050565b600080600080600060a0868803121561473957600080fd5b61474286613a83565b945060208601356001600160401b038082111561475e57600080fd5b61476a89838a01613d88565b9550604088013591508082111561478057600080fd5b61478c89838a016142c7565b9450613e4c60608901613dde565b600080600080608085870312156147b057600080fd5b6147b985613a83565b93506147c760208601613a83565b925060408501356147d781613c72565b9396929550929360600135925050565b600181811c908216806147fb57607f821691505b6020821081141561481c57634e487b7160e01b600052602260045260246000fd5b50919050565b8183823760009101908152919050565b6020808252602d908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526c1c881bdc88185c1c1c9bdd9959609a1b606082015260800190565b81835281816020850137506000828201602090810191909152601f909101601f19169091010190565b61ffff841681526040602082015260006125aa60408301848661487f565b6001600160a01b0392909216825260ff16602082015260400190565b6040815260006148f56040830185613beb565b905060018060a01b03831660208301529392505050565b602080825260189082015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b604082015260600190565b634e487b7160e01b600052603260045260246000fd5b61ffff831681526040602082015260006125ad6040830184613beb565b634e487b7160e01b600052601160045260246000fd5b600060001982141561499b5761499b614971565b5060010190565b600082601f8301126149b357600080fd5b81516149c1613da782613d61565b8181528460208386010111156149d657600080fd5b6125ad826020830160208701613bbf565b600080604083850312156149fa57600080fd5b82516001600160401b0380821115614a1157600080fd5b614a1d868387016149a2565b9350602091508185015181811115614a3457600080fd5b85019050601f81018613614a4757600080fd5b8051614a55613da782614087565b81815260059190911b82018301908381019088831115614a7457600080fd5b928401925b82841015614a9257835182529284019290840190614a79565b80955050505050509250929050565b600082821015614ab357614ab3614971565b500390565b8284823760609190911b6001600160601b0319169101908152601401919050565b6000816000190483118215151615614af357614af3614971565b500290565b60008219821115614b0b57614b0b614971565b500190565b606081526000614b2460608301868861487f565b6001600160a01b03949094166020830152506040015292915050565b60008351614b52818460208801613bbf565b835190830190614b66818360208801613bbf565b01949350505050565b600061ffff808816835280871660208401525084604083015260806060830152614b9d60808301848661487f565b979650505050505050565b61ffff86168152608060208201526000614bc660808301868861487f565b6001600160401b0394909416604083015250606001529392505050565b61ffff861681526001600160a01b038516602082015260a060408201819052600090614c1190830186613beb565b84151560608401528281036080840152614c2b8185613beb565b98975050505050505050565b60008060408385031215614c4a57600080fd5b505080516020909101519092909150565b600081518084526020808501945080840160005b83811015614c8b57815187529582019590820190600101614c6f565b509495945050505050565b604081526000614ca96040830185613beb565b8281036020840152614cbb8185614c5b565b95945050505050565b600060208284031215614cd657600080fd5b81516001600160401b03811115614cec57600080fd5b6125ad848285016149a2565b61ffff85168152608060208201526000614d156080830186613beb565b6001600160401b03851660408401528281036060840152614b9d8185613beb565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b61ffff8716815260c060208201526000614d9860c0830188613beb565b8281036040840152614daa8188613beb565b6001600160a01b0387811660608601528616608085015283810360a08501529050614dd58185613beb565b9998505050505050505050565b60008251614df4818460208701613bbf565b9190910192915050565b602081526000611b676020830184614c5b565b8281526040602082015260006125ad6040830184613beb565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b61ffff8616815260a060208201526000614e9960a0830187613beb565b6001600160401b03861660408401528281036060840152614eba8186613beb565b90508281036080840152614c2b8185613beb565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090614f0190830184613beb565b9695505050505050565b600060208284031215614f1d57600080fd5b8151611b6781613b8c565b6020808252601c908201527b115490cdcc8c4e881d1bdad95b88185b1c9958591e481b5a5b9d195960221b60408201526060019056feddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3efa0d28d8d5b183af824884dfca74f986a6a5d684d9c4af1621f0d0754fb54887bfa41487ad5d6728f0b19276fa1eddc16558578f5109fc39d2dc33c3230470daba2646970667358221220f45c480028e65d4db9530ecb63865b2b72186e5df1833e5bfac2082c826785ed64736f6c634300080c0033

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

0000000000000000000000000000000000000000000000000000000000000120000000000000000000000000000000000000000000000000000000000000016000000000000000000000000000000000000000000000000000000000000001a000000000000000000000000000000000000000000000000000000000000186a00000000000000000000000003c2269811836af69497e5f486a85d7316753cf62000000000000000000000000000000000000000000000000000028048c5ec000000000000000000000000000000000000000000000000000000000000000006f000000000000000000000000000000000000000000000000000000000000020000000000000000000000000000000000000000000000000000000000000186a0000000000000000000000000000000000000000000000000000000000000000a43727970746f72616e6b00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000343524b0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000002d68747470733a2f2f6170692e63727970746f72616e6b2e696f2f6465646963617465642f776562332f6e66742f0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000270000000000000000000000000000000000000000000000000000000000000066000000000000000000000000000000000000000000000000000000000000006e000000000000000000000000000000000000000000000000000000000000006d000000000000000000000000000000000000000000000000000000000000006a000000000000000000000000000000000000000000000000000000000000007000000000000000000000000000000000000000000000000000000000000000af00000000000000000000000000000000000000000000000000000000000000b8000000000000000000000000000000000000000000000000000000000000009e0000000000000000000000000000000000000000000000000000000000000091000000000000000000000000000000000000000000000000000000000000006f00000000000000000000000000000000000000000000000000000000000000d6000000000000000000000000000000000000000000000000000000000000007e00000000000000000000000000000000000000000000000000000000000000a7000000000000000000000000000000000000000000000000000000000000007d00000000000000000000000000000000000000000000000000000000000000b1000000000000000000000000000000000000000000000000000000000000008a00000000000000000000000000000000000000000000000000000000000000b500000000000000000000000000000000000000000000000000000000000000b70000000000000000000000000000000000000000000000000000000000000096000000000000000000000000000000000000000000000000000000000000009900000000000000000000000000000000000000000000000000000000000000d300000000000000000000000000000000000000000000000000000000000000ca000000000000000000000000000000000000000000000000000000000000009f000000000000000000000000000000000000000000000000000000000000007400000000000000000000000000000000000000000000000000000000000000c300000000000000000000000000000000000000000000000000000000000000a5000000000000000000000000000000000000000000000000000000000000009700000000000000000000000000000000000000000000000000000000000000d400000000000000000000000000000000000000000000000000000000000000b000000000000000000000000000000000000000000000000000000000000000ad00000000000000000000000000000000000000000000000000000000000000c7000000000000000000000000000000000000000000000000000000000000009b00000000000000000000000000000000000000000000000000000000000000d200000000000000000000000000000000000000000000000000000000000000d800000000000000000000000000000000000000000000000000000000000000d900000000000000000000000000000000000000000000000000000000000000e600000000000000000000000000000000000000000000000000000000000000ff00000000000000000000000000000000000000000000000000000000000000f30000000000000000000000000000000000000000000000000000000000000101

-----Decoded View---------------
Arg [0] : name (string): Cryptorank
Arg [1] : symbol (string): CRK
Arg [2] : baseUri_ (string): https://api.cryptorank.io/dedicated/web3/nft/
Arg [3] : _minGasToTransfer (uint256): 100000
Arg [4] : _layerZeroEndpoint (address): 0x3c2269811836af69497E5F486A85D7316753cf62
Arg [5] : fee_ (uint256): 44000000000000
Arg [6] : chainId_ (uint128): 111
Arg [7] : _remoteChainIds (uint16[]): 102,110,109,106,112,175,184,158,145,111,214,126,167,125,177,138,181,183,150,153,211,202,159,116,195,165,151,212,176,173,199,155,210,216,217,230,255,243,257
Arg [8] : minDstGas (uint256): 100000

-----Encoded View---------------
56 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [2] : 00000000000000000000000000000000000000000000000000000000000001a0
Arg [3] : 00000000000000000000000000000000000000000000000000000000000186a0
Arg [4] : 0000000000000000000000003c2269811836af69497e5f486a85d7316753cf62
Arg [5] : 000000000000000000000000000000000000000000000000000028048c5ec000
Arg [6] : 000000000000000000000000000000000000000000000000000000000000006f
Arg [7] : 0000000000000000000000000000000000000000000000000000000000000200
Arg [8] : 00000000000000000000000000000000000000000000000000000000000186a0
Arg [9] : 000000000000000000000000000000000000000000000000000000000000000a
Arg [10] : 43727970746f72616e6b00000000000000000000000000000000000000000000
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000003
Arg [12] : 43524b0000000000000000000000000000000000000000000000000000000000
Arg [13] : 000000000000000000000000000000000000000000000000000000000000002d
Arg [14] : 68747470733a2f2f6170692e63727970746f72616e6b2e696f2f646564696361
Arg [15] : 7465642f776562332f6e66742f00000000000000000000000000000000000000
Arg [16] : 0000000000000000000000000000000000000000000000000000000000000027
Arg [17] : 0000000000000000000000000000000000000000000000000000000000000066
Arg [18] : 000000000000000000000000000000000000000000000000000000000000006e
Arg [19] : 000000000000000000000000000000000000000000000000000000000000006d
Arg [20] : 000000000000000000000000000000000000000000000000000000000000006a
Arg [21] : 0000000000000000000000000000000000000000000000000000000000000070
Arg [22] : 00000000000000000000000000000000000000000000000000000000000000af
Arg [23] : 00000000000000000000000000000000000000000000000000000000000000b8
Arg [24] : 000000000000000000000000000000000000000000000000000000000000009e
Arg [25] : 0000000000000000000000000000000000000000000000000000000000000091
Arg [26] : 000000000000000000000000000000000000000000000000000000000000006f
Arg [27] : 00000000000000000000000000000000000000000000000000000000000000d6
Arg [28] : 000000000000000000000000000000000000000000000000000000000000007e
Arg [29] : 00000000000000000000000000000000000000000000000000000000000000a7
Arg [30] : 000000000000000000000000000000000000000000000000000000000000007d
Arg [31] : 00000000000000000000000000000000000000000000000000000000000000b1
Arg [32] : 000000000000000000000000000000000000000000000000000000000000008a
Arg [33] : 00000000000000000000000000000000000000000000000000000000000000b5
Arg [34] : 00000000000000000000000000000000000000000000000000000000000000b7
Arg [35] : 0000000000000000000000000000000000000000000000000000000000000096
Arg [36] : 0000000000000000000000000000000000000000000000000000000000000099
Arg [37] : 00000000000000000000000000000000000000000000000000000000000000d3
Arg [38] : 00000000000000000000000000000000000000000000000000000000000000ca
Arg [39] : 000000000000000000000000000000000000000000000000000000000000009f
Arg [40] : 0000000000000000000000000000000000000000000000000000000000000074
Arg [41] : 00000000000000000000000000000000000000000000000000000000000000c3
Arg [42] : 00000000000000000000000000000000000000000000000000000000000000a5
Arg [43] : 0000000000000000000000000000000000000000000000000000000000000097
Arg [44] : 00000000000000000000000000000000000000000000000000000000000000d4
Arg [45] : 00000000000000000000000000000000000000000000000000000000000000b0
Arg [46] : 00000000000000000000000000000000000000000000000000000000000000ad
Arg [47] : 00000000000000000000000000000000000000000000000000000000000000c7
Arg [48] : 000000000000000000000000000000000000000000000000000000000000009b
Arg [49] : 00000000000000000000000000000000000000000000000000000000000000d2
Arg [50] : 00000000000000000000000000000000000000000000000000000000000000d8
Arg [51] : 00000000000000000000000000000000000000000000000000000000000000d9
Arg [52] : 00000000000000000000000000000000000000000000000000000000000000e6
Arg [53] : 00000000000000000000000000000000000000000000000000000000000000ff
Arg [54] : 00000000000000000000000000000000000000000000000000000000000000f3
Arg [55] : 0000000000000000000000000000000000000000000000000000000000000101


Deployed Bytecode Sourcemap

119469:5127:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;99566:842;;;;;;;;;;-1:-1:-1;99566:842:0;;;;;:::i;:::-;;:::i;:::-;;118289:228;;;;;;;;;;-1:-1:-1;118289:228:0;;;;;:::i;:::-;;:::i;:::-;;;2124:14:1;;2117:22;2099:41;;2087:2;2072:18;118289:228:0;;;;;;;;42539:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;103190:123::-;;;;;;;;;;-1:-1:-1;103190:123:0;;;;;:::i;:::-;;:::i;44051:171::-;;;;;;;;;;-1:-1:-1;44051:171:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;43569:416::-;;;;;;;;;;-1:-1:-1;43569:416:0;;;;;:::i;:::-;;:::i;116078:318::-;;;;;;;;;;-1:-1:-1;116078:318:0;;;;;:::i;:::-;;:::i;105093:142::-;;;;;;;;;;-1:-1:-1;105093:142:0;;;;;:::i;:::-;;:::i;103321:129::-;;;;;;;;;;-1:-1:-1;103321:129:0;;;;;:::i;:::-;;:::i;109754:53::-;;;;;;;;;;-1:-1:-1;109754:53:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;109754:53:0;;;;;;;;;;;4774:6:1;4762:19;;;4744:38;;-1:-1:-1;;;;;4818:32:1;;;4813:2;4798:18;;4791:60;4867:18;;;4860:34;4937:14;4930:22;4925:2;4910:18;;4903:50;4731:3;4716:19;109754:53:0;4521:438:1;44751:301:0;;;;;;;;;;-1:-1:-1;44751:301:0;;;;;:::i;:::-;;:::i;110306:372::-;;;;;;;;;;-1:-1:-1;110306:372:0;;;;;:::i;:::-;;:::i;:::-;;;;7588:25:1;;;7644:2;7629:18;;7622:34;;;;7561:18;110306:372:0;7414:248:1;124325:160:0;;;;;;;;;;;;;:::i;105333:250::-;;;;;;;;;;-1:-1:-1;105333:250:0;;;;;:::i;:::-;;:::i;99108:53::-;;;;;;;;;;-1:-1:-1;99108:53:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;8299:25:1;;;8287:2;8272:18;99108:53:0;8153:177:1;45123:151:0;;;;;;;;;;-1:-1:-1;45123:151:0;;;;;:::i;:::-;;:::i;103458:178::-;;;;;;;;;;-1:-1:-1;103458:178:0;;;;;:::i;:::-;;:::i;122826:476::-;;;;;;:::i;:::-;;:::i;109453:36::-;;;;;;;;;;;;;;;;109566:53;;;;;;;;;;-1:-1:-1;109566:53:0;;;;;:::i;:::-;;;;;;;;;;;;;;111134:421;;;;;;:::i;:::-;;:::i;106226:85::-;;;;;;;;;;-1:-1:-1;106226:85:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42249:223;;;;;;;;;;-1:-1:-1;42249:223:0;;;;;:::i;:::-;;:::i;107549:389::-;;;;;;;;;;-1:-1:-1;107549:389:0;;;;;:::i;:::-;;:::i;121522:75::-;;;;;;;;;;-1:-1:-1;121522:75:0;;;;;:::i;:::-;;:::i;119885:22::-;;;;;;;;;;;;;;;;41980:207;;;;;;;;;;-1:-1:-1;41980:207:0;;;;;:::i;:::-;;:::i;3067:103::-;;;;;;;;;;;;;:::i;98978:51::-;;;;;;;;;;-1:-1:-1;98978:51:0;;;;;:::i;:::-;;:::i;120747:406::-;;;;;;;;;;-1:-1:-1;120747:406:0;;;;;:::i;:::-;;:::i;99036:65::-;;;;;;;;;;-1:-1:-1;99036:65:0;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;2426:87;;;;;;;;;;;;;:::i;114101:1155::-;;;;;;;;;;-1:-1:-1;114101:1155:0;;;;;:::i;:::-;;:::i;99168:23::-;;;;;;;;;;-1:-1:-1;99168:23:0;;;;-1:-1:-1;;;;;99168:23:0;;;42708:104;;;;;;;;;;;;;:::i;119914:21::-;;;;;;;;;;;;;:::i;116917:348::-;;;;;;;;;;-1:-1:-1;116917:348:0;;;;;:::i;:::-;;:::i;104287:330::-;;;;;;;;;;-1:-1:-1;104287:330:0;;;;;:::i;:::-;;:::i;121605:102::-;;;;;;;;;;-1:-1:-1;121605:102:0;;;;;:::i;:::-;;:::i;44294:155::-;;;;;;;;;;-1:-1:-1;44294:155:0;;;;;:::i;:::-;;:::i;103998:281::-;;;;;;;;;;-1:-1:-1;103998:281:0;;;;;:::i;:::-;;:::i;111563:418::-;;;;;;:::i;:::-;;:::i;121715:431::-;;;;;;:::i;:::-;;:::i;109219:45::-;;;;;;;;;;;;109263:1;109219:45;;;;;17407:6:1;17395:19;;;17377:38;;17365:2;17350:18;109219:45:0;17233:188:1;98925:46:0;;;;;;;;;;;;;;;123819:498;;;;;;:::i;:::-;;:::i;45345:279::-;;;;;;;;;;-1:-1:-1;45345:279:0;;;;;:::i;:::-;;:::i;104625:136::-;;;;;;;;;;-1:-1:-1;104625:136:0;;;;;:::i;:::-;;:::i;98861:55::-;;;;;;;;;;;;98911:5;98861:55;;123310:501;;;;;;:::i;:::-;;:::i;42883:281::-;;;;;;;;;;-1:-1:-1;42883:281:0;;;;;:::i;:::-;;:::i;102935:247::-;;;;;;;;;;-1:-1:-1;102935:247:0;;;;;:::i;:::-;;:::i;116497:356::-;;;;;;;;;;-1:-1:-1;116497:356:0;;;;;:::i;:::-;;:::i;108167:810::-;;;;;;:::i;:::-;;:::i;122154:292::-;;;;;;:::i;:::-;;:::i;122454:364::-;;;;;;;;;;-1:-1:-1;122454:364:0;;;;;:::i;:::-;;:::i;119863:15::-;;;;;;;;;;;;;;;;104769:262;;;;;;;;;;-1:-1:-1;104769:262:0;;;;;:::i;:::-;;:::i;44520:164::-;;;;;;;;;;-1:-1:-1;44520:164:0;;;;;:::i;:::-;;:::i;103783:207::-;;;;;;;;;;-1:-1:-1;103783:207:0;;;;;:::i;:::-;;:::i;110686:440::-;;;;;;;;;;-1:-1:-1;110686:440:0;;;;;:::i;:::-;;:::i;3325:201::-;;;;;;;;;;-1:-1:-1;3325:201:0;;;;;:::i;:::-;;:::i;102619:254::-;;;;;;;;;;-1:-1:-1;102619:254:0;;;;;:::i;:::-;;:::i;109626:54::-;;;;;;;;;;-1:-1:-1;109626:54:0;;;;;:::i;:::-;;;;;;;;;;;;;;99566:842;1002:10;99849;-1:-1:-1;;;;;99825:35:0;;99817:78;;;;-1:-1:-1;;;99817:78:0;;24118:2:1;99817:78:0;;;24100:21:1;24157:2;24137:18;;;24130:30;24196:32;24176:18;;;24169:60;24246:18;;99817:78:0;;;;;;;;;99937:32;;;99908:26;99937:32;;;:19;:32;;;;;99908:61;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;100157:13;:20;100135:11;;:18;;:42;:70;;;;;100204:1;100181:13;:20;:24;100135:70;:124;;;;-1:-1:-1;100235:24:0;;;;;;100209:22;;;;100219:11;;;;100209:22;:::i;:::-;;;;;;;;:50;100135:124;100113:212;;;;-1:-1:-1;;;100113:212:0;;25138:2:1;100113:212:0;;;25120:21:1;25177:2;25157:18;;;25150:30;25216:34;25196:18;;;25189:62;-1:-1:-1;;;25267:18:1;;;25260:36;25313:19;;100113:212:0;24936:402:1;100113:212:0;100338:62;100357:11;100370;;100338:62;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;100338:62:0;;;;;;;;;;;;;;;;;;;;;;100383:6;;-1:-1:-1;100338:62:0;-1:-1:-1;100391:8:0;;;;;;100338:62;;100391:8;;;;100338:62;;;;;;;;;-1:-1:-1;100338:18:0;;-1:-1:-1;;;100338:62:0:i;:::-;99740:668;99566:842;;;;;;:::o;118289:228::-;118404:4;-1:-1:-1;;;;;;118428:41:0;;;;:81;;;118473:36;118497:11;118473:23;:36::i;:::-;118421:88;118289:228;-1:-1:-1;;118289:228:0:o;42539:100::-;42593:13;42626:5;42619:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42539:100;:::o;103190:123::-;2312:13;:11;:13::i;:::-;103270:35:::1;::::0;-1:-1:-1;;;103270:35:0;;17407:6:1;17395:19;;103270:35:0::1;::::0;::::1;17377:38:1::0;103270:10:0::1;-1:-1:-1::0;;;;;103270:25:0::1;::::0;::::1;::::0;17350:18:1;;103270:35:0::1;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;103190:123:::0;:::o;44051:171::-;44127:7;44147:23;44162:7;44147:14;:23::i;:::-;-1:-1:-1;44190:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;44190:24:0;;44051:171::o;43569:416::-;43650:13;43666:23;43681:7;43666:14;:23::i;:::-;43650:39;;43714:5;-1:-1:-1;;;;;43708:11:0;:2;-1:-1:-1;;;;;43708:11:0;;;43700:57;;;;-1:-1:-1;;;43700:57:0;;25545:2:1;43700:57:0;;;25527:21:1;25584:2;25564:18;;;25557:30;25623:34;25603:18;;;25596:62;-1:-1:-1;;;25674:18:1;;;25667:31;25715:19;;43700:57:0;25343:397:1;43700:57:0;1002:10;-1:-1:-1;;;;;43792:21:0;;;;:62;;-1:-1:-1;43817:37:0;43834:5;1002:10;44520:164;:::i;43817:37::-;43770:173;;;;-1:-1:-1;;;43770:173:0;;25947:2:1;43770:173:0;;;25929:21:1;25986:2;25966:18;;;25959:30;26025:34;26005:18;;;25998:62;26096:31;26076:18;;;26069:59;26145:19;;43770:173:0;25745:425:1;43770:173:0;43956:21;43965:2;43969:7;43956:8;:21::i;:::-;43639:346;43569:416;;:::o;116078:318::-;2312:13;:11;:13::i;:::-;116213:1:::1;116185:25;:29;116177:78;;;::::0;-1:-1:-1;;;116177:78:0;;26377:2:1;116177:78:0::1;::::0;::::1;26359:21:1::0;26416:2;26396:18;;;26389:30;26455:34;26435:18;;;26428:62;-1:-1:-1;;;26506:18:1;;;26499:34;26550:19;;116177:78:0::1;26175:400:1::0;116177:78:0::1;116266:24;:52:::0;;;116334:54:::1;::::0;8299:25:1;;;116334:54:0::1;::::0;8287:2:1;8272:18;116334:54:0::1;;;;;;;;116078:318:::0;:::o;105093:142::-;2312:13;:11;:13::i;:::-;105184:35:::1;::::0;;::::1;;::::0;;;:22:::1;:35;::::0;;;;:43;105093:142::o;103321:129::-;2312:13;:11;:13::i;:::-;103404:38:::1;::::0;-1:-1:-1;;;103404:38:0;;17407:6:1;17395:19;;103404:38:0::1;::::0;::::1;17377::1::0;103404:10:0::1;-1:-1:-1::0;;;;;103404:28:0::1;::::0;::::1;::::0;17350:18:1;;103404:38:0::1;17233:188:1::0;44751:301:0;44912:41;1002:10;44931:12;44945:7;44912:18;:41::i;:::-;44904:99;;;;-1:-1:-1;;;44904:99:0;;;;;;;:::i;:::-;45016:28;45026:4;45032:2;45036:7;45016:9;:28::i;110306:372::-;110524:14;110540:11;110571:99;110592:11;110605:10;110617:27;110635:8;110617:17;:27::i;:::-;110646:7;110655:14;110571:20;:99::i;:::-;110564:106;;;;110306:372;;;;;;;;:::o;124325:160::-;2312:13;:11;:13::i;:::-;124392:58:::1;::::0;124374:12:::1;::::0;124400:10:::1;::::0;124424:21:::1;::::0;124374:12;124392:58;124374:12;124392:58;124424:21;124400:10;124392:58:::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;124373:77;;;124469:7;124461:16;;;::::0;::::1;;124362:123;124325:160::o:0;105333:250::-;105475:32;;;105429:4;105475:32;;;:19;:32;;;;;105446:61;;105429:4;;105475:32;105446:61;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;105563:11;;105553:22;;;;;;;:::i;:::-;;;;;;;;105535:13;105525:24;;;;;;:50;105518:57;;;105333:250;;;;;:::o;45123:151::-;45227:39;45244:4;45250:2;45254:7;45227:39;;;;;;;;;;;;:16;:39::i;103458:178::-;2312:13;:11;:13::i;:::-;103573:55:::1;::::0;-1:-1:-1;;;103573:55:0;;-1:-1:-1;;;;;103573:10:0::1;:29;::::0;::::1;::::0;:55:::1;::::0;103603:11;;103616;;;;103573:55:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;122826:476:::0;123079:36;;;;;;;:23;:36;;;;;;123015:101;;123030:11;;109263:1;;123063:14;;123015;:101::i;:::-;123127:118;123135:11;123159:10;123171:1;123148:25;;;;;;;;;:::i;:::-;;;;;;;;;;;;;123191:4;123199:18;123219:14;123235:9;123127:7;:118::i;:::-;123261:33;123273:8;123283:10;123261:33;;;;;;;:::i;:::-;;;;;;;;122826:476;;;;:::o;111134:421::-;111429:118;111435:5;111442:11;111455:10;111467:27;111485:8;111467:17;:27::i;:::-;111496:14;111512:18;111532:14;111429:5;:118::i;42249:223::-;42321:7;42341:13;42357:17;42366:7;42357:8;:17::i;:::-;42341:33;-1:-1:-1;;;;;;42393:19:0;;42385:56;;;;-1:-1:-1;;;42385:56:0;;;;;;;:::i;107549:389::-;1002:10;107806:4;107782:29;107774:80;;;;-1:-1:-1;;;107774:80:0;;28979:2:1;107774:80:0;;;28961:21:1;29018:2;28998:18;;;28991:30;29057:34;29037:18;;;29030:62;-1:-1:-1;;;29108:18:1;;;29101:36;29154:19;;107774:80:0;28777:402:1;107774:80:0;107865:65;107887:11;107900;;107865:65;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;107865:65:0;;;;;;;;;;;;;;;;;;;;;;107913:6;;-1:-1:-1;107865:65:0;-1:-1:-1;107921:8:0;;;;;;107865:65;;107921:8;;;;107865:65;;;;;;;;;-1:-1:-1;107865:21:0;;-1:-1:-1;;;107865:65:0:i;:::-;107549:389;;;;;;:::o;121522:75::-;2312:13;:11;:13::i;:::-;121579:3:::1;:10:::0;121522:75::o;41980:207::-;42052:7;-1:-1:-1;;;;;42080:19:0;;42072:73;;;;-1:-1:-1;;;42072:73:0;;29386:2:1;42072:73:0;;;29368:21:1;29425:2;29405:18;;;29398:30;29464:34;29444:18;;;29437:62;-1:-1:-1;;;29515:18:1;;;29508:39;29564:19;;42072:73:0;29184:405:1;42072:73:0;-1:-1:-1;;;;;;42163:16:0;;;;;:9;:16;;;;;;;41980:207::o;3067:103::-;2312:13;:11;:13::i;:::-;3132:30:::1;3159:1;3132:18;:30::i;:::-;3067:103::o:0;98978:51::-;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;120747:406::-;2312:13;:11;:13::i;:::-;120894:6:::1;:13;120868:15;:22;:39;120864:74;;120916:22;;-1:-1:-1::0;;;120916:22:0::1;;;;;;;;;;;120864:74;120956:6;120951:195;120972:15;:22;120968:1;:26;120951:195;;;121058:6;121065:1;121058:9;;;;;;;;:::i;:::-;;;;;;;121016:19;:39;121036:15;121052:1;121036:18;;;;;;;;:::i;:::-;;;;;;;121016:39;;;;;;;;;;;;;;;:51;;;;;;;;;;;;:::i;:::-;;-1:-1:-1::0;;;;;;;;;;;121104:15:0::1;121120:1;121104:18;;;;;;;;:::i;:::-;;;;;;;121124:6;121131:1;121124:9;;;;;;;;:::i;:::-;;;;;;;121087:47;;;;;;;:::i;:::-;;;;;;;;120996:3:::0;::::1;::::0;::::1;:::i;:::-;;;;120951:195;;2426:87:::0;2472:7;2499:6;-1:-1:-1;;;;;2499:6:0;;2426:87::o;114101:1155::-;64048:21;:19;:21::i;:::-;114211:19;;::::1;::::0;;::::1;::::0;;;;114187:21:::1;114249:28:::0;;;:13:::1;:28:::0;;;;;;;:42:::1;;::::0;::::1;;114241:72;;;::::0;-1:-1:-1;;;114241:72:0;;30505:2:1;114241:72:0::1;::::0;::::1;30487:21:1::0;30544:2;30524:18;;;30517:30;-1:-1:-1;;;30563:18:1;;;30556:47;30620:18;;114241:72:0::1;30303:341:1::0;114241:72:0::1;114329:22;114366:8;114355:37;;;;;;;;;;;;:::i;:::-;114405:14;114448:28:::0;;;:13:::1;:28;::::0;;;;:39;;;114555:34;;::::1;::::0;114326:66;;-1:-1:-1;114405:14:0;;-1:-1:-1;114422:201:0::1;::::0;114448:39:::1;::::0;::::1;::::0;114502:38;;::::1;-1:-1:-1::0;;;;;114502:38:0::1;::::0;114326:66;114422:11:::1;:201::i;:::-;114654:28;::::0;;;:13:::1;:28;::::0;;;;:34:::1;;::::0;114405:218;;-1:-1:-1;114642:46:0;::::1;114634:100;;;::::0;-1:-1:-1;;;114634:100:0;;32392:2:1;114634:100:0::1;::::0;::::1;32374:21:1::0;32431:2;32411:18;;;32404:30;32470:34;32450:18;;;32443:62;-1:-1:-1;;;32521:18:1;;;32514:39;32570:19;;114634:100:0::1;32190:405:1::0;114634:100:0::1;114764:8;:15;114751:9;:28;114747:502;;;114859:28;::::0;;;:13:::1;:28;::::0;;;;;114852:35;;-1:-1:-1;;;;;;114852:35:0;;;;;::::1;::::0;;;;::::1;::::0;;::::1;::::0;;-1:-1:-1;;114852:35:0::1;::::0;;114907:28;::::1;::::0;::::1;::::0;114873:13;8299:25:1;;8287:2;8272:18;;8153:177;114907:28:0::1;;;;;;;;114747:502;;;115044:193;::::0;;::::1;::::0;::::1;::::0;;-1:-1:-1;115075:28:0;;;:13:::1;:28;::::0;;;;;;:39;;::::1;::::0;;::::1;115044:193:::0;;-1:-1:-1;;;;;115133:38:0;;;::::1;::::0;::::1;115044:193:::0;;::::1;::::0;;;;;;;;;115075:39;115044:193;;;;;;115013:28;;;;;;;;:224;;;;::::1;::::0;;::::1;-1:-1:-1::0;;;;;;115013:224:0;;;;;;::::1;::::0;;;;;;;::::1;::::0;;;;;;::::1;::::0;;;;;115133:38:::1;115013:224:::0;;::::1;::::0;;;::::1;;-1:-1:-1::0;;115013:224:0;;::::1;::::0;;;::::1;::::0;;114747:502:::1;114176:1080;;;64092:20:::0;63486:1;64612:7;:22;64429:213;42708:104;42764:13;42797:7;42790:14;;;;;:::i;119914:21::-;;;;;;;:::i;116917:348::-;2312:13;:11;:13::i;:::-;117066:1:::1;117040:23;:27;117032:74;;;::::0;-1:-1:-1;;;117032:74:0;;32802:2:1;117032:74:0::1;::::0;::::1;32784:21:1::0;32841:2;32821:18;;;32814:30;32880:34;32860:18;;;32853:62;-1:-1:-1;;;32931:18:1;;;32924:32;32973:19;;117032:74:0::1;32600:398:1::0;117032:74:0::1;117117:35;::::0;::::1;;::::0;;;:22:::1;:35;::::0;;;;;;;;:61;;;117194:63;;33175:38:1;;;33229:18;;33222:34;;;117194:63:0::1;::::0;33148:18:1;117194:63:0::1;;;;;;;;116917:348:::0;;:::o;104287:330::-;104411:35;;;104391:17;104411:35;;;:19;:35;;;;;104391:55;;104366:12;;104391:17;104411:35;104391:55;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;104465:4;:11;104480:1;104465:16;;104457:58;;;;-1:-1:-1;;;104457:58:0;;33469:2:1;104457:58:0;;;33451:21:1;33508:2;33488:18;;;33481:30;33547:31;33527:18;;;33520:59;33596:18;;104457:58:0;33267:353:1;104457:58:0;104533:31;104544:1;104561:2;104547:4;:11;:16;;;;:::i;:::-;104533:4;;:31;:10;:31::i;:::-;104526:38;104287:330;-1:-1:-1;;;104287:330:0:o;121605:102::-;2312:13;:11;:13::i;:::-;121681:18:::1;:7;121691:8:::0;;121681:18:::1;:::i;44294:155::-:0;44389:52;1002:10;44422:8;44432;44389:18;:52::i;:::-;44294:155;;:::o;103998:281::-;2312:13;:11;:13::i;:::-;104170:14:::1;;104194:4;104153:47;;;;;;;;;;:::i;:::-;;::::0;;-1:-1:-1;;104153:47:0;;::::1;::::0;;;;;;104115:35:::1;::::0;::::1;;::::0;;;:19:::1;104153:47;104115:35:::0;;;;;;:85;;::::1;::::0;:35;;:85;;::::1;::::0;::::1;:::i;:::-;;104216:55;104240:14;104256;;104216:55;;;;;;;;:::i;:::-;;;;;;;;103998:281:::0;;;:::o;111563:418::-;111873:100;111879:5;111886:11;111899:10;111911:9;111922:14;111938:18;111958:14;111873:5;:100::i;121715:431::-;121800:13;121822:5;121816:3;;:11;;;;:::i;:::-;121800:27;;121854:8;121842:9;:20;121838:73;;;121871:40;;-1:-1:-1;;;121871:40:0;;;;;7588:25:1;;;121901:9:0;7629:18:1;;;7622:34;7561:18;;121871:40:0;7414:248:1;121838:73:0;121935:10;;121922;121958:92;121979:5;121975:1;:9;121958:92;;;122006:32;122016:10;122028:9;122036:1;122028:5;:9;:::i;:::-;122006;:32::i;:::-;121986:3;;;;:::i;:::-;;;;121958:92;;;;122076:5;122062:10;;:19;;;;;;;:::i;:::-;;;;-1:-1:-1;;122097:41:0;;-1:-1:-1;;;;;;;;;;;122097:41:0;;;122110:8;;;;122120:10;;122132:5;;122097:41;:::i;:::-;;;;;;;;121789:357;;121715:431;;;:::o;123819:498::-;124157:100;124163:5;124170:11;124183:10;124195:9;124206:14;124222:18;124242:14;124157:5;:100::i;:::-;124273:36;124288:8;124298:10;124273:36;;;;;;;:::i;:::-;;;;;;;;123819:498;;;;;;;;:::o;45345:279::-;45476:41;1002:10;45509:7;45476:18;:41::i;:::-;45468:99;;;;-1:-1:-1;;;45468:99:0;;;;;;;:::i;:::-;45578:38;45592:4;45598:2;45602:7;45611:4;45578:13;:38::i;:::-;45345:279;;;;:::o;104625:136::-;2312:13;:11;:13::i;:::-;104695:8:::1;:20:::0;;-1:-1:-1;;;;;;104695:20:0::1;-1:-1:-1::0;;;;;104695:20:0;::::1;;::::0;;104731:22:::1;::::0;::::1;::::0;::::1;::::0;104695:20;;104731:22:::1;:::i;123310:501::-:0;123633:118;123639:5;123646:11;123659:10;123671:27;123689:8;123671:17;:27::i;:::-;123700:14;123716:18;123736:14;123633:5;:118::i;42883:281::-;42956:13;42982:23;42997:7;42982:14;:23::i;:::-;43018:21;43042:10;:8;:10::i;:::-;43018:34;;43094:1;43076:7;43070:21;:25;:86;;;;;;;;;;;;;;;;;43122:7;43131:18;:7;:16;:18::i;:::-;43105:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;43063:93;42883:281;-1:-1:-1;;;42883:281:0:o;102935:247::-;2312:13;:11;:13::i;:::-;103112:62:::1;::::0;-1:-1:-1;;;103112:62:0;;-1:-1:-1;;;;;103112:10:0::1;:20;::::0;::::1;::::0;:62:::1;::::0;103133:8;;103143;;103153:11;;103166:7;;;;103112:62:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;102935:247:::0;;;;;:::o;116497:356::-;2312:13;:11;:13::i;:::-;116649:1:::1;116622:24;:28;116614:76;;;::::0;-1:-1:-1;;;116614:76:0;;36039:2:1;116614:76:0::1;::::0;::::1;36021:21:1::0;36078:2;36058:18;;;36051:30;36117:34;36097:18;;;36090:62;-1:-1:-1;;;36168:18:1;;;36161:33;36211:19;;116614:76:0::1;35837:399:1::0;116614:76:0::1;116701:36;::::0;::::1;;::::0;;;:23:::1;:36;::::0;;;;;;;;:63;;;116780:65;;33175:38:1;;;33229:18;;33222:34;;;116780:65:0::1;::::0;33148:18:1;116780:65:0::1;33003:259:1::0;108167:810:0;108421:27;;;108399:19;108421:27;;;:14;:27;;;;;;:40;;;;108449:11;;;;108421:40;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;108421:48:0;;;;;;;;;;;;-1:-1:-1;108421:48:0;108480:73;;;;-1:-1:-1;;;108480:73:0;;36443:2:1;108480:73:0;;;36425:21:1;36482:2;36462:18;;;36455:30;36521:34;36501:18;;;36494:62;-1:-1:-1;;;36572:18:1;;;36565:33;36615:19;;108480:73:0;36241:399:1;108480:73:0;108595:11;108582:8;;108572:19;;;;;;;:::i;:::-;;;;;;;;:34;108564:80;;;;-1:-1:-1;;;108564:80:0;;36847:2:1;108564:80:0;;;36829:21:1;36886:2;36866:18;;;36859:30;36925:34;36905:18;;;36898:62;-1:-1:-1;;;36976:18:1;;;36969:31;37017:19;;108564:80:0;36645:397:1;108564:80:0;108692:27;;;108751:1;108692:27;;;:14;:27;;;;;;:40;;;;108720:11;;;;108692:40;:::i;:::-;;;;;;;;;;;;;;;;-1:-1:-1;;;;;108692:48:0;;;;;;;;;;;;:61;;;;108822:65;;;;;;;;;;;;;;;;;;;108844:11;;108857;;108822:65;;;;;;108857:11;108822:65;;108857:11;108822:65;;;;;;;;;-1:-1:-1;;108822:65:0;;;;;;;;;;;;;;;;;;;;;;108870:6;;-1:-1:-1;108822:65:0;-1:-1:-1;108878:8:0;;;;;;108822:65;;108878:8;;;;108822:65;;;;;;;;;-1:-1:-1;108822:21:0;;-1:-1:-1;;;108822:65:0:i;:::-;108903:66;108923:11;108936;;108949:6;108957:11;108903:66;;;;;;;;;;:::i;:::-;;;;;;;;108343:634;108167:810;;;;;;:::o;122154:292::-;122238:3;;122226:9;:15;122222:63;;;122270:3;;122250:35;;-1:-1:-1;;;122250:35:0;;;;;7588:25:1;;;;122275:9:0;7629:18:1;;;7622:34;7561:18;;122250:35:0;7414:248:1;122222:63:0;122311:10;;;;;;122298;122332:12;122311:10;122332:12;:::i;:::-;;;;;;122357:28;122367:10;122379:5;122357:9;:28::i;:::-;-1:-1:-1;;;;;;;;;;;122414:8:0;;122424:10;122436:1;122401:37;;;;;;;;;:::i;122454:364::-;122610:14;122626:11;122650:20;122684:10;122696:1;122673:25;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;122673:25:0;;;;;;;;;;-1:-1:-1;;;122716:94:0;;122673:25;-1:-1:-1;;;;;;122716:10:0;:23;;;;:94;;122740:11;;122769:4;;122673:25;;122786:7;;122795:14;;122716:94;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;122709:101;;;;;122454:364;;;;;;:::o;104769:262::-;2312:13;:11;:13::i;:::-;104909:28:::1;::::0;;::::1;;::::0;;;:15:::1;:28;::::0;;;;;;;:41;;::::1;::::0;;;;;;;;;;:51;;;104976:47;;39100:34:1;;;39150:18;;39143:43;;;;39202:18;;;39195:34;;;104976:47:0::1;::::0;39063:2:1;39048:18;104976:47:0::1;38877:358:1::0;44520:164:0;-1:-1:-1;;;;;44641:25:0;;;44617:4;44641:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;44520:164::o;103783:207::-;2312:13;:11;:13::i;:::-;103884:35:::1;::::0;::::1;;::::0;;;:19:::1;:35;::::0;;;;:43:::1;::::0;103922:5;;103884:43:::1;:::i;:::-;;-1:-1:-1::0;;;;;;;;;;;103960:14:0::1;103976:5;;103943:39;;;;;;;;:::i;110686:440::-:0;110919:14;110935:11;110959:20;110993:10;111005:9;110982:33;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;110982:33:0;;;;;;;;;;-1:-1:-1;;;111033:85:0;;110982:33;-1:-1:-1;;;;;;111033:10:0;:23;;;;:85;;111057:11;;111078:4;;110982:33;;111094:7;;111103:14;;111033:85;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;111026:92;;;;;110686:440;;;;;;;;:::o;3325:201::-;2312:13;:11;:13::i;:::-;-1:-1:-1;;;;;3414:22:0;::::1;3406:73;;;::::0;-1:-1:-1;;;3406:73:0;;40956:2:1;3406:73:0::1;::::0;::::1;40938:21:1::0;40995:2;40975:18;;;40968:30;41034:34;41014:18;;;41007:62;-1:-1:-1;;;41085:18:1;;;41078:36;41131:19;;3406:73:0::1;40754:402:1::0;3406:73:0::1;3490:28;3509:8;3490:18;:28::i;102619:254::-:0;102797:68;;-1:-1:-1;;;102797:68:0;;41398:6:1;41431:15;;;102797:68:0;;;41413:34:1;41483:15;;41463:18;;;41456:43;102846:4:0;41515:18:1;;;41508:60;41584:18;;;41577:34;;;102765:12:0;;102797:10;-1:-1:-1;;;;;102797:20:0;;;;41360:19:1;;102797:68:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;102797:68:0;;;;;;;;;;;;:::i;:::-;102790:75;;102619:254;;;;;;;:::o;13415:326::-;-1:-1:-1;;;;;13710:19:0;;:23;;;13415:326::o;106595:563::-;106788:12;106802:19;106825:203;106873:9;106897:3;106938:34;;;106974:11;106987;107000:6;107008:8;106915:102;;;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;106915:102:0;;;;;;;;;;;;;;-1:-1:-1;;;;;106915:102:0;-1:-1:-1;;;;;;106915:102:0;;;;;;;;;;106833:4;;106825:203;;:33;:203::i;:::-;106787:241;;;;107044:7;107039:112;;107068:71;107088:11;107101;107114:6;107122:8;107132:6;107068:19;:71::i;41611:305::-;41713:4;-1:-1:-1;;;;;;41750:40:0;;-1:-1:-1;;;41750:40:0;;:105;;-1:-1:-1;;;;;;;41807:48:0;;-1:-1:-1;;;41807:48:0;41750:105;:158;;;;41872:36;41896:11;41872:23;:36::i;2591:132::-;1002:10;2655:7;:5;:7::i;:::-;-1:-1:-1;;;;;2655:23:0;;2647:68;;;;-1:-1:-1;;;2647:68:0;;42726:2:1;2647:68:0;;;42708:21:1;;;42745:18;;;42738:30;42804:34;42784:18;;;42777:62;42856:18;;2647:68:0;42524:356:1;53614:135:0;53696:16;53704:7;53696;:16::i;:::-;53688:53;;;;-1:-1:-1;;;53688:53:0;;;;;;;:::i;52927:174::-;53002:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;53002:29:0;-1:-1:-1;;;;;53002:29:0;;;;;;;;:24;;53056:23;53002:24;53056:14;:23::i;:::-;-1:-1:-1;;;;;53047:46:0;;;;;;;;;;;52927:174;;:::o;47614:264::-;47707:4;47724:13;47740:23;47755:7;47740:14;:23::i;:::-;47724:39;;47793:5;-1:-1:-1;;;;;47782:16:0;:7;-1:-1:-1;;;;;47782:16:0;;:52;;;;47802:32;47819:5;47826:7;47802:16;:32::i;:::-;47782:87;;;;47862:7;-1:-1:-1;;;;;47838:31:0;:20;47850:7;47838:11;:20::i;:::-;-1:-1:-1;;;;;47838:31:0;;47774:96;47614:264;-1:-1:-1;;;;47614:264:0:o;51579:1229::-;51704:4;-1:-1:-1;;;;;51677:31:0;:23;51692:7;51677:14;:23::i;:::-;-1:-1:-1;;;;;51677:31:0;;51669:81;;;;-1:-1:-1;;;51669:81:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;51769:16:0;;51761:65;;;;-1:-1:-1;;;51761:65:0;;43493:2:1;51761:65:0;;;43475:21:1;43532:2;43512:18;;;43505:30;43571:34;43551:18;;;43544:62;-1:-1:-1;;;43622:18:1;;;43615:34;43666:19;;51761:65:0;43291:400:1;51761:65:0;52011:4;-1:-1:-1;;;;;51984:31:0;:23;51999:7;51984:14;:23::i;:::-;-1:-1:-1;;;;;51984:31:0;;51976:81;;;;-1:-1:-1;;;51976:81:0;;;;;;;:::i;:::-;52129:24;;;;:15;:24;;;;;;;;52122:31;;-1:-1:-1;;;;;;52122:31:0;;;;;;-1:-1:-1;;;;;52605:15:0;;;;;;:9;:15;;;;;:20;;-1:-1:-1;;52605:20:0;;;52640:13;;;;;;;;;:18;;52122:31;52640:18;;;52680:16;;;:7;:16;;;;;;:21;;;;;;;;;;52719:27;;52145:7;;-1:-1:-1;;;;;;;;;;;52719:27:0;;43639:346;43569:416;;:::o;117569:185::-;117681:13;;;117692:1;117681:13;;;;;;;;;117633;;117659:19;;117681:13;;;;;;;;;;;;-1:-1:-1;117681:13:0;117659:35;;117716:7;117705:5;117711:1;117705:8;;;;;;;;:::i;:::-;;;;;;;;;;:18;117741:5;117569:185;-1:-1:-1;;117569:185:0:o;101362:463::-;101541:21;101565:28;101578:14;101565:12;:28::i;:::-;101623;;;;101604:16;101623:28;;;:15;:28;;;;;;;;:35;;;;;;;;;;101541:52;;-1:-1:-1;101677:15:0;101669:54;;;;-1:-1:-1;;;101669:54:0;;43898:2:1;101669:54:0;;;43880:21:1;43937:2;43917:18;;;43910:30;-1:-1:-1;;;43956:18:1;;;43949:56;44022:18;;101669:54:0;43696:350:1;101669:54:0;101762:23;101776:9;101762:11;:23;:::i;:::-;101742:16;:43;;101734:83;;;;-1:-1:-1;;;101734:83:0;;44253:2:1;101734:83:0;;;44235:21:1;44292:2;44272:18;;;44265:30;-1:-1:-1;;;44311:18:1;;;44304:57;44378:18;;101734:83:0;44051:351:1;100740:614:0;101024:32;;;100995:26;101024:32;;;:19;:32;;;;;100995:61;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;101075:13;:20;101099:1;101075:25;;101067:86;;;;-1:-1:-1;;;101067:86:0;;44609:2:1;101067:86:0;;;44591:21:1;44648:2;44628:18;;;44621:30;44687:34;44667:18;;;44660:62;-1:-1:-1;;;44738:18:1;;;44731:46;44794:19;;101067:86:0;44407:412:1;101067:86:0;101164:47;101182:11;101195:8;:15;101164:17;:47::i;:::-;101222:124;;-1:-1:-1;;;101222:124:0;;-1:-1:-1;;;;;101222:10:0;:15;;;;101245:10;;101222:124;;101257:11;;101270:13;;101285:8;;101295:14;;101311:18;;101331:14;;101222:124;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;100984:370;100740:614;;;;;;:::o;111989:1030::-;112334:1;112315:9;:16;:20;112307:52;;;;-1:-1:-1;;;112307:52:0;;45871:2:1;112307:52:0;;;45853:21:1;45910:2;45890:18;;;45883:30;-1:-1:-1;;;45929:18:1;;;45922:49;45988:18;;112307:52:0;45669:343:1;112307:52:0;112378:9;:16;112398:1;112378:21;:80;;;-1:-1:-1;112423:35:0;;;;;;;:22;:35;;;;;;112403:16;;:55;;112378:80;112370:127;;;;-1:-1:-1;;;112370:127:0;;46219:2:1;112370:127:0;;;46201:21:1;46258:2;46238:18;;;46231:30;46297:34;46277:18;;;46270:62;-1:-1:-1;;;46348:18:1;;;46341:32;46390:19;;112370:127:0;46017:398:1;112370:127:0;112515:6;112510:127;112531:9;:16;112527:1;:20;112510:127;;;112569:56;112580:5;112587:11;112600:10;112612:9;112622:1;112612:12;;;;;;;;:::i;:::-;;;;;;;112569:10;:56::i;:::-;112549:3;;;;:::i;:::-;;;;112510:127;;;;112649:20;112683:10;112695:9;112672:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;112649:56;;112718:120;112733:11;109263:1;112766:14;112821:9;:16;112782:23;:36;112806:11;112782:36;;;;;;;;;;;;;;;;:55;;;;:::i;:::-;112718:14;:120::i;:::-;112849:92;112857:11;112870:7;112879:14;112895:18;112915:14;112931:9;112849:7;:92::i;:::-;112989:10;112957:54;;;;;;:::i;:::-;;;;;;;;112982:5;-1:-1:-1;;;;;112957:54:0;112969:11;112957:54;;;113001:9;112957:54;;;;;;:::i;:::-;;;;;;;;112265:754;111989:1030;;;;;;;:::o;46889:117::-;46955:7;46982:16;;;:7;:16;;;;;;-1:-1:-1;;;;;46982:16:0;;46889:117::o;113027:976::-;113269:27;113298:22;113335:8;113324:37;;;;;;;;;;;;:::i;:::-;113465:2;113445:23;;113439:30;113268:93;;-1:-1:-1;113268:93:0;-1:-1:-1;113374:17:0;113509:48;113521:11;113439:30;113374:17;113268:93;113509:11;:48::i;:::-;113492:65;;113584:8;:15;113572:9;:27;113568:347;;;113728:19;;;;;;;;;;113793:53;;;;;;;;;;;;;;-1:-1:-1;;;;;113793:53:0;;;;;;;;;;;;;;;113841:4;113793:53;;;;;;113704:21;113762:28;;;:13;:28;;;;;;;:84;;;;;;;;;;;-1:-1:-1;;;;;;113762:84:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;113762:84:0;;;;;;;;;;113866:37;;;;;;113728:19;;113738:8;;113866:37;:::i;:::-;;;;;;;;113601:314;113568:347;113975:9;-1:-1:-1;;;;;113932:63:0;113962:11;113932:63;;;;;;:::i;:::-;;;;;;;;113949:11;113932:63;;;113986:8;113932:63;;;;;;:::i;3686:191::-;3760:16;3779:6;;-1:-1:-1;;;;;3796:17:0;;;-1:-1:-1;;;;;;3796:17:0;;;;;;3829:40;;3779:6;;;;;;;3829:40;;3760:16;3829:40;3749:128;3686:191;:::o;64128:293::-;63530:1;64262:7;;:19;;64254:63;;;;-1:-1:-1;;;64254:63:0;;47461:2:1;64254:63:0;;;47443:21:1;47500:2;47480:18;;;47473:30;47539:33;47519:18;;;47512:61;47590:18;;64254:63:0;47259:355:1;64254:63:0;63530:1;64395:7;:18;64128:293::o;115455:615::-;115620:4;115646:11;115668:263;115679:9;:16;115675:1;:20;115668:263;;;115805:24;;115793:9;:36;115789:47;;;115831:5;;115789:47;115853:48;115863:11;115876:10;115888:9;115898:1;115888:12;;;;;;;;:::i;:::-;;;;;;;115853:9;:48::i;:::-;115916:3;;;;:::i;:::-;;;;115668:263;;80133:2833;80253:12;80302:7;80286:12;80302:7;80296:2;80286:12;:::i;:::-;:23;;80278:50;;;;-1:-1:-1;;;80278:50:0;;47821:2:1;80278:50:0;;;47803:21:1;47860:2;47840:18;;;47833:30;-1:-1:-1;;;47879:18:1;;;47872:44;47933:18;;80278:50:0;47619:338:1;80278:50:0;80364:16;80373:7;80364:6;:16;:::i;:::-;80347:6;:13;:33;;80339:63;;;;-1:-1:-1;;;80339:63:0;;48164:2:1;80339:63:0;;;48146:21:1;48203:2;48183:18;;;48176:30;-1:-1:-1;;;48222:18:1;;;48215:47;48279:18;;80339:63:0;47962:341:1;80339:63:0;80415:22;80481:15;;80510:2005;;;;82659:4;82653:11;82640:24;;82848:1;82837:9;82830:20;82898:4;82887:9;82883:20;82877:4;82870:34;80474:2445;;80510:2005;80695:4;80689:11;80676:24;;81364:2;81355:7;81351:16;81752:9;81745:17;81739:4;81735:28;81723:9;81712;81708:25;81704:60;81801:7;81797:2;81793:16;82058:6;82044:9;82037:17;82031:4;82027:28;82015:9;82007:6;82003:22;81999:57;81995:70;81829:434;82092:3;82088:2;82085:11;81829:434;;;82234:9;;82223:21;;82134:4;82126:13;;;;82167;81829:434;;;-1:-1:-1;;82283:26:0;;;82495:2;82478:11;-1:-1:-1;;82474:25:0;82468:4;82461:39;-1:-1:-1;80474:2445:0;-1:-1:-1;82949:9:0;80133:2833;-1:-1:-1;;;;80133:2833:0:o;53244:281::-;53365:8;-1:-1:-1;;;;;53356:17:0;:5;-1:-1:-1;;;;;53356:17:0;;;53348:55;;;;-1:-1:-1;;;53348:55:0;;48510:2:1;53348:55:0;;;48492:21:1;48549:2;48529:18;;;48522:30;-1:-1:-1;;;48568:18:1;;;48561:55;48633:18;;53348:55:0;48308:349:1;53348:55:0;-1:-1:-1;;;;;53414:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;53414:46:0;;;;;;;;;;53476:41;;2099::1;;;53476::0;;2072:18:1;53476:41:0;;;;;;;53244:281;;;:::o;48220:110::-;48296:26;48306:2;48310:7;48296:26;;;;;;;;;;;;:9;:26::i;46505:270::-;46618:28;46628:4;46634:2;46638:7;46618:9;:28::i;:::-;46665:47;46688:4;46694:2;46698:7;46707:4;46665:22;:47::i;:::-;46657:110;;;;-1:-1:-1;;;46657:110:0;;;;;;;:::i;124493:100::-;124545:13;124578:7;124571:14;;;;;:::i;37747:716::-;37803:13;37854:14;37871:17;37882:5;37871:10;:17::i;:::-;37891:1;37871:21;37854:38;;37907:20;37941:6;-1:-1:-1;;;;;37930:18:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;37930:18:0;-1:-1:-1;37907:41:0;-1:-1:-1;38072:28:0;;;38088:2;38072:28;38129:288;-1:-1:-1;;38161:5:0;-1:-1:-1;;;38298:2:0;38287:14;;38282:30;38161:5;38269:44;38359:2;38350:11;;;-1:-1:-1;38384:10:0;38380:21;;38396:5;;38380:21;38129:288;;;-1:-1:-1;38438:6:0;37747:716;-1:-1:-1;;;37747:716:0:o;66136:1309::-;66295:4;66301:12;66363;66386:13;66410:24;66447:8;66437:19;;-1:-1:-1;;;;;66437:19:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;66437:19:0;;66410:46;;66966:1;66936;66898:9;66892:16;66859:4;66848:9;66844:20;66809:1;66770:7;66740:4;66717:275;66705:287;;67061:16;67050:27;;67106:8;67097:7;67094:21;67091:78;;;67146:8;67135:19;;67091:78;67256:7;67243:11;67236:28;67378:7;67375:1;67368:4;67355:11;67351:22;67336:50;67415:8;;;;-1:-1:-1;66136:1309:0;-1:-1:-1;;;;;;66136:1309:0:o;107166:375::-;107442:8;107432:19;;;;;;107381:14;:27;107396:11;107381:27;;;;;;;;;;;;;;;107409:11;107381:40;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;107381:48:0;;;;;;;;;:70;;;;107467:66;;;;107481:11;;107494;;107422:6;;107515:8;;107525:7;;107467:66;:::i;110079:219::-;110181:4;-1:-1:-1;;;;;;110205:45:0;;-1:-1:-1;;;110205:45:0;;:85;;-1:-1:-1;;;;;;;;;;22603:40:0;;;110254:36;22494:157;47319:128;47384:4;;47408:17;47417:7;47408:8;:17::i;:::-;-1:-1:-1;;;;;47408:31:0;;;;47319:128;-1:-1:-1;;47319:128:0:o;101833:271::-;101915:13;101974:2;101949:14;:21;:27;;101941:68;;;;-1:-1:-1;;;101941:68:0;;50139:2:1;101941:68:0;;;50121:21:1;50178:2;50158:18;;;50151:30;-1:-1:-1;;;50197:18:1;;;50190:58;50265:18;;101941:68:0;49937:352:1;101941:68:0;-1:-1:-1;102082:2:0;102062:23;102056:30;;101833:271::o;102112:402::-;102235:35;;;102211:21;102235:35;;;:22;:35;;;;;;102285:21;102281:138;;-1:-1:-1;98911:5:0;102281:138;102453:16;102437:12;:32;;102429:77;;;;-1:-1:-1;;;102429:77:0;;50496:2:1;102429:77:0;;;50478:21:1;;;50515:18;;;50508:30;50574:34;50554:18;;;50547:62;50626:18;;102429:77:0;50294:356:1;118525:404:0;118685:42;1002:10;118704:12;922:98;118685:42;118677:101;;;;-1:-1:-1;;;118677:101:0;;50857:2:1;118677:101:0;;;50839:21:1;50896:2;50876:18;;;50869:30;50935:34;50915:18;;;50908:62;-1:-1:-1;;;50986:18:1;;;50979:44;51040:19;;118677:101:0;50655:410:1;118677:101:0;118825:5;-1:-1:-1;;;;;118797:33:0;:24;118812:8;118797:14;:24::i;:::-;-1:-1:-1;;;;;118797:33:0;;118789:80;;;;-1:-1:-1;;;118789:80:0;;51272:2:1;118789:80:0;;;51254:21:1;51311:2;51291:18;;;51284:30;51350:34;51330:18;;;51323:62;-1:-1:-1;;;51401:18:1;;;51394:32;51443:19;;118789:80:0;51070:398:1;118789:80:0;118880:41;118890:5;118905:4;118912:8;118880:9;:41::i;118937:407::-;119079:17;119087:8;119079:7;:17::i;:::-;119078:18;:86;;;;119101:17;119109:8;119101:7;:17::i;:::-;:62;;;;-1:-1:-1;119158:4:0;119122:24;119137:8;119122:14;:24::i;:::-;-1:-1:-1;;;;;119122:41:0;;119101:62;119070:95;;;;;;119181:17;119189:8;119181:7;:17::i;:::-;119176:161;;119215:31;119225:10;119237:8;119215:9;:31::i;119176:161::-;119279:46;119297:4;119304:10;119316:8;119279:9;:46::i;48557:285::-;48652:18;48658:2;48662:7;48652:5;:18::i;:::-;48703:53;48734:1;48738:2;48742:7;48751:4;48703:22;:53::i;:::-;48681:153;;;;-1:-1:-1;;;48681:153:0;;;;;;;:::i;54313:853::-;54467:4;54488:15;:2;-1:-1:-1;;;;;54488:13:0;;:15::i;:::-;54484:675;;;54524:71;;-1:-1:-1;;;54524:71:0;;-1:-1:-1;;;;;54524:36:0;;;;;:71;;1002:10;;54575:4;;54581:7;;54590:4;;54524:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;-1:-1:-1;54524:71:0;;;;;;;;-1:-1:-1;;54524:71:0;;;;;;;;;;;;:::i;:::-;;;54520:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;54765:13:0;;54761:328;;54808:60;;-1:-1:-1;;;54808:60:0;;;;;;;:::i;54761:328::-;55039:6;55033:13;55024:6;55020:2;55016:15;55009:38;54520:584;-1:-1:-1;;;;;;54646:51:0;-1:-1:-1;;;54646:51:0;;-1:-1:-1;54639:58:0;;54484:675;-1:-1:-1;55143:4:0;55136:11;;33130:948;33183:7;;-1:-1:-1;;;33261:17:0;;33257:106;;-1:-1:-1;;;33299:17:0;;;-1:-1:-1;33345:2:0;33335:12;33257:106;-1:-1:-1;;;33381:5:0;:17;33377:106;;-1:-1:-1;;;33419:17:0;;;-1:-1:-1;33465:2:0;33455:12;33377:106;33510:8;33501:5;:17;33497:106;;33548:8;33539:17;;;-1:-1:-1;33585:2:0;33575:12;33497:106;33630:7;33621:5;:16;33617:103;;33667:7;33658:16;;;-1:-1:-1;33703:1:0;33693:11;33617:103;33747:7;33738:5;:16;33734:103;;33784:7;33775:16;;;-1:-1:-1;33820:1:0;33810:11;33734:103;33864:7;33855:5;:16;33851:103;;33901:7;33892:16;;;-1:-1:-1;33937:1:0;33927:11;33851:103;33981:7;33972:5;:16;33968:68;;34019:1;34009:11;34064:6;33130:948;-1:-1:-1;;33130:948:0:o;49178:942::-;-1:-1:-1;;;;;49258:16:0;;49250:61;;;;-1:-1:-1;;;49250:61:0;;52423:2:1;49250:61:0;;;52405:21:1;;;52442:18;;;52435:30;52501:34;52481:18;;;52474:62;52553:18;;49250:61:0;52221:356:1;49250:61:0;49331:16;49339:7;49331;:16::i;:::-;49330:17;49322:58;;;;-1:-1:-1;;;49322:58:0;;;;;;;:::i;:::-;49540:16;49548:7;49540;:16::i;:::-;49539:17;49531:58;;;;-1:-1:-1;;;49531:58:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;49938:13:0;;;;;;:9;:13;;;;;;;;:18;;49955:1;49938:18;;;49980:16;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;49980:21:0;;;;;50019:33;49988:7;;49938:13;;-1:-1:-1;;;;;;;;;;;50019:33:0;49938:13;;50019:33;44294:155;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:159:1;81:20;;141:6;130:18;;120:29;;110:57;;163:1;160;153:12;110:57;14:159;;;:::o;178:347::-;229:8;239:6;293:3;286:4;278:6;274:17;270:27;260:55;;311:1;308;301:12;260:55;-1:-1:-1;334:20:1;;-1:-1:-1;;;;;366:30:1;;363:50;;;409:1;406;399:12;363:50;446:4;438:6;434:17;422:29;;498:3;491:4;482:6;474;470:19;466:30;463:39;460:59;;;515:1;512;505:12;460:59;178:347;;;;;:::o;530:171::-;597:20;;-1:-1:-1;;;;;646:30:1;;636:41;;626:69;;691:1;688;681:12;706:862;812:6;820;828;836;844;852;905:3;893:9;884:7;880:23;876:33;873:53;;;922:1;919;912:12;873:53;945:28;963:9;945:28;:::i;:::-;935:38;-1:-1:-1;1024:2:1;1009:18;;996:32;-1:-1:-1;;;;;1077:14:1;;;1074:34;;;1104:1;1101;1094:12;1074:34;1143:58;1193:7;1184:6;1173:9;1169:22;1143:58;:::i;:::-;1220:8;;-1:-1:-1;1117:84:1;-1:-1:-1;1117:84:1;;-1:-1:-1;1274:37:1;1307:2;1292:18;;1274:37;:::i;:::-;1264:47;;1364:2;1353:9;1349:18;1336:32;1320:48;;1393:2;1383:8;1380:16;1377:36;;;1409:1;1406;1399:12;1377:36;;1448:60;1500:7;1489:8;1478:9;1474:24;1448:60;:::i;:::-;706:862;;;;-1:-1:-1;706:862:1;;-1:-1:-1;706:862:1;;1527:8;;706:862;-1:-1:-1;;;706:862:1:o;1573:131::-;-1:-1:-1;;;;;;1647:32:1;;1637:43;;1627:71;;1694:1;1691;1684:12;1709:245;1767:6;1820:2;1808:9;1799:7;1795:23;1791:32;1788:52;;;1836:1;1833;1826:12;1788:52;1875:9;1862:23;1894:30;1918:5;1894:30;:::i;2151:258::-;2223:1;2233:113;2247:6;2244:1;2241:13;2233:113;;;2323:11;;;2317:18;2304:11;;;2297:39;2269:2;2262:10;2233:113;;;2364:6;2361:1;2358:13;2355:48;;;-1:-1:-1;;2399:1:1;2381:16;;2374:27;2151:258::o;2414:::-;2456:3;2494:5;2488:12;2521:6;2516:3;2509:19;2537:63;2593:6;2586:4;2581:3;2577:14;2570:4;2563:5;2559:16;2537:63;:::i;:::-;2654:2;2633:15;-1:-1:-1;;2629:29:1;2620:39;;;;2661:4;2616:50;;2414:258;-1:-1:-1;;2414:258:1:o;2677:220::-;2826:2;2815:9;2808:21;2789:4;2846:45;2887:2;2876:9;2872:18;2864:6;2846:45;:::i;2902:184::-;2960:6;3013:2;3001:9;2992:7;2988:23;2984:32;2981:52;;;3029:1;3026;3019:12;2981:52;3052:28;3070:9;3052:28;:::i;3091:180::-;3150:6;3203:2;3191:9;3182:7;3178:23;3174:32;3171:52;;;3219:1;3216;3209:12;3171:52;-1:-1:-1;3242:23:1;;3091:180;-1:-1:-1;3091:180:1:o;3276:203::-;-1:-1:-1;;;;;3440:32:1;;;;3422:51;;3410:2;3395:18;;3276:203::o;3484:131::-;-1:-1:-1;;;;;3559:31:1;;3549:42;;3539:70;;3605:1;3602;3595:12;3620:134;3688:20;;3717:31;3688:20;3717:31;:::i;3759:315::-;3827:6;3835;3888:2;3876:9;3867:7;3863:23;3859:32;3856:52;;;3904:1;3901;3894:12;3856:52;3943:9;3930:23;3962:31;3987:5;3962:31;:::i;:::-;4012:5;4064:2;4049:18;;;;4036:32;;-1:-1:-1;;;3759:315:1:o;4079:252::-;4146:6;4154;4207:2;4195:9;4186:7;4182:23;4178:32;4175:52;;;4223:1;4220;4213:12;4175:52;4246:28;4264:9;4246:28;:::i;4964:456::-;5041:6;5049;5057;5110:2;5098:9;5089:7;5085:23;5081:32;5078:52;;;5126:1;5123;5116:12;5078:52;5165:9;5152:23;5184:31;5209:5;5184:31;:::i;:::-;5234:5;-1:-1:-1;5291:2:1;5276:18;;5263:32;5304:33;5263:32;5304:33;:::i;:::-;4964:456;;5356:7;;-1:-1:-1;;;5410:2:1;5395:18;;;;5382:32;;4964:456::o;5425:127::-;5486:10;5481:3;5477:20;5474:1;5467:31;5517:4;5514:1;5507:15;5541:4;5538:1;5531:15;5557:275;5628:2;5622:9;5693:2;5674:13;;-1:-1:-1;;5670:27:1;5658:40;;-1:-1:-1;;;;;5713:34:1;;5749:22;;;5710:62;5707:88;;;5775:18;;:::i;:::-;5811:2;5804:22;5557:275;;-1:-1:-1;5557:275:1:o;5837:186::-;5885:4;-1:-1:-1;;;;;5907:30:1;;5904:56;;;5940:18;;:::i;:::-;-1:-1:-1;6006:2:1;5985:15;-1:-1:-1;;5981:29:1;6012:4;5977:40;;5837:186::o;6028:462::-;6070:5;6123:3;6116:4;6108:6;6104:17;6100:27;6090:55;;6141:1;6138;6131:12;6090:55;6177:6;6164:20;6208:48;6224:31;6252:2;6224:31;:::i;:::-;6208:48;:::i;:::-;6281:2;6272:7;6265:19;6327:3;6320:4;6315:2;6307:6;6303:15;6299:26;6296:35;6293:55;;;6344:1;6341;6334:12;6293:55;6409:2;6402:4;6394:6;6390:17;6383:4;6374:7;6370:18;6357:55;6457:1;6432:16;;;6450:4;6428:27;6421:38;;;;6436:7;6028:462;-1:-1:-1;;;6028:462:1:o;6495:160::-;6560:20;;6616:13;;6609:21;6599:32;;6589:60;;6645:1;6642;6635:12;6660:749;6769:6;6777;6785;6793;6801;6854:3;6842:9;6833:7;6829:23;6825:33;6822:53;;;6871:1;6868;6861:12;6822:53;6894:28;6912:9;6894:28;:::i;:::-;6884:38;-1:-1:-1;6973:2:1;6958:18;;6945:32;-1:-1:-1;;;;;7026:14:1;;;7023:34;;;7053:1;7050;7043:12;7023:34;7076:49;7117:7;7108:6;7097:9;7093:22;7076:49;:::i;:::-;7066:59;;7172:2;7161:9;7157:18;7144:32;7134:42;;7195:35;7226:2;7215:9;7211:18;7195:35;:::i;:::-;7185:45;;7283:3;7272:9;7268:19;7255:33;7239:49;;7313:2;7303:8;7300:16;7297:36;;;7329:1;7326;7319:12;7297:36;;7352:51;7395:7;7384:8;7373:9;7369:24;7352:51;:::i;:::-;7342:61;;;6660:749;;;;;;;;:::o;7667:481::-;7745:6;7753;7761;7814:2;7802:9;7793:7;7789:23;7785:32;7782:52;;;7830:1;7827;7820:12;7782:52;7853:28;7871:9;7853:28;:::i;:::-;7843:38;-1:-1:-1;7932:2:1;7917:18;;7904:32;-1:-1:-1;;;;;7948:30:1;;7945:50;;;7991:1;7988;7981:12;7945:50;8030:58;8080:7;8071:6;8060:9;8056:22;8030:58;:::i;:::-;7667:481;;8107:8;;-1:-1:-1;8004:84:1;;-1:-1:-1;;;;7667:481:1:o;8335:748::-;8439:6;8447;8455;8463;8516:3;8504:9;8495:7;8491:23;8487:33;8484:53;;;8533:1;8530;8523:12;8484:53;8556:28;8574:9;8556:28;:::i;:::-;8546:38;;8634:2;8623:9;8619:18;8606:32;8647:31;8672:5;8647:31;:::i;:::-;8697:5;-1:-1:-1;8753:2:1;8738:18;;8725:32;-1:-1:-1;;;;;8806:14:1;;;8803:34;;;8833:1;8830;8823:12;8803:34;8856:49;8897:7;8888:6;8877:9;8873:22;8856:49;:::i;:::-;8846:59;;8958:2;8947:9;8943:18;8930:32;8914:48;;8987:2;8977:8;8974:16;8971:36;;;9003:1;9000;8993:12;8971:36;;9026:51;9069:7;9058:8;9047:9;9043:24;9026:51;:::i;:::-;9016:61;;;8335:748;;;;;;;:::o;9088:1108::-;9226:6;9234;9242;9250;9258;9266;9274;9327:3;9315:9;9306:7;9302:23;9298:33;9295:53;;;9344:1;9341;9334:12;9295:53;9383:9;9370:23;9402:31;9427:5;9402:31;:::i;:::-;9452:5;-1:-1:-1;9476:37:1;9509:2;9494:18;;9476:37;:::i;:::-;9466:47;-1:-1:-1;9564:2:1;9549:18;;9536:32;-1:-1:-1;;;;;9617:14:1;;;9614:34;;;9644:1;9641;9634:12;9614:34;9667:49;9708:7;9699:6;9688:9;9684:22;9667:49;:::i;:::-;9657:59;;9763:2;9752:9;9748:18;9735:32;9725:42;;9819:3;9808:9;9804:19;9791:33;9776:48;;9833:33;9858:7;9833:33;:::i;:::-;9885:7;;-1:-1:-1;9944:3:1;9929:19;;9916:33;;9958;9916;9958;:::i;:::-;10010:7;;-1:-1:-1;10070:3:1;10055:19;;10042:33;;10087:16;;;10084:36;;;10116:1;10113;10106:12;10084:36;;10139:51;10182:7;10171:8;10160:9;10156:24;10139:51;:::i;:::-;10129:61;;;9088:1108;;;;;;;;;;:::o;10201:464::-;10285:6;10293;10301;10354:2;10342:9;10333:7;10329:23;10325:32;10322:52;;;10370:1;10367;10360:12;10322:52;10393:28;10411:9;10393:28;:::i;:::-;10383:38;-1:-1:-1;10472:2:1;10457:18;;10444:32;-1:-1:-1;;;;;10488:30:1;;10485:50;;;10531:1;10528;10521:12;10485:50;10554:49;10595:7;10586:6;10575:9;10571:22;10554:49;:::i;:::-;10544:59;;;10622:37;10655:2;10644:9;10640:18;10622:37;:::i;:::-;10612:47;;10201:464;;;;;:::o;10852:247::-;10911:6;10964:2;10952:9;10943:7;10939:23;10935:32;10932:52;;;10980:1;10977;10970:12;10932:52;11019:9;11006:23;11038:31;11063:5;11038:31;:::i;11327:182::-;11386:4;-1:-1:-1;;;;;11408:30:1;;11405:56;;;11441:18;;:::i;:::-;-1:-1:-1;11486:1:1;11482:14;11498:4;11478:25;;11327:182::o;11514:885::-;11566:5;11619:3;11612:4;11604:6;11600:17;11596:27;11586:55;;11637:1;11634;11627:12;11586:55;11673:6;11660:20;11699:4;11723:59;11739:42;11778:2;11739:42;:::i;11723:59::-;11816:15;;;11902:1;11898:10;;;;11886:23;;11882:32;;;11847:12;;;;11926:15;;;11923:35;;;11954:1;11951;11944:12;11923:35;11990:2;11982:6;11978:15;12002:368;12018:6;12013:3;12010:15;12002:368;;;12091:17;;-1:-1:-1;;;;;12124:35:1;;12121:125;;;12200:1;12229:2;12225;12218:14;12121:125;12271:56;12323:3;12318:2;12304:11;12296:6;12292:24;12288:33;12271:56;:::i;:::-;12259:69;;-1:-1:-1;12348:12:1;;;;12035;;12002:368;;;-1:-1:-1;12388:5:1;11514:885;-1:-1:-1;;;;;;11514:885:1:o;12404:1150::-;12530:6;12538;12591:2;12579:9;12570:7;12566:23;12562:32;12559:52;;;12607:1;12604;12597:12;12559:52;12634:23;;-1:-1:-1;;;;;12706:14:1;;;12703:34;;;12733:1;12730;12723:12;12703:34;12771:6;12760:9;12756:22;12746:32;;12816:7;12809:4;12805:2;12801:13;12797:27;12787:55;;12838:1;12835;12828:12;12787:55;12874:2;12861:16;12896:4;12920:59;12936:42;12975:2;12936:42;:::i;12920:59::-;13013:15;;;13095:1;13091:10;;;;13083:19;;13079:28;;;13044:12;;;;13119:19;;;13116:39;;;13151:1;13148;13141:12;13116:39;13175:11;;;;13195:147;13211:6;13206:3;13203:15;13195:147;;;13277:22;13295:3;13277:22;:::i;:::-;13265:35;;13228:12;;;;13320;;;;13195:147;;;13361:5;-1:-1:-1;;13404:18:1;;13391:32;;-1:-1:-1;;13435:16:1;;;13432:36;;;13464:1;13461;13454:12;13432:36;;13487:61;13540:7;13529:8;13518:9;13514:24;13487:61;:::i;:::-;13477:71;;;12404:1150;;;;;:::o;13559:256::-;13625:6;13633;13686:2;13674:9;13665:7;13661:23;13657:32;13654:52;;;13702:1;13699;13692:12;13654:52;13725:28;13743:9;13725:28;:::i;:::-;13715:38;;13772:37;13805:2;13794:9;13790:18;13772:37;:::i;:::-;13762:47;;13559:256;;;;;:::o;13820:320::-;13888:6;13941:2;13929:9;13920:7;13916:23;13912:32;13909:52;;;13957:1;13954;13947:12;13909:52;13984:23;;-1:-1:-1;;;;;14019:30:1;;14016:50;;;14062:1;14059;14052:12;14016:50;14085:49;14126:7;14117:6;14106:9;14102:22;14085:49;:::i;14145:410::-;14216:6;14224;14277:2;14265:9;14256:7;14252:23;14248:32;14245:52;;;14293:1;14290;14283:12;14245:52;14320:23;;-1:-1:-1;;;;;14355:30:1;;14352:50;;;14398:1;14395;14388:12;14352:50;14437:58;14487:7;14478:6;14467:9;14463:22;14437:58;:::i;:::-;14514:8;;14411:84;;-1:-1:-1;14145:410:1;-1:-1:-1;;;;14145:410:1:o;14560:315::-;14625:6;14633;14686:2;14674:9;14665:7;14661:23;14657:32;14654:52;;;14702:1;14699;14692:12;14654:52;14741:9;14728:23;14760:31;14785:5;14760:31;:::i;:::-;14810:5;-1:-1:-1;14834:35:1;14865:2;14850:18;;14834:35;:::i;14880:661::-;14934:5;14987:3;14980:4;14972:6;14968:17;14964:27;14954:55;;15005:1;15002;14995:12;14954:55;15041:6;15028:20;15067:4;15091:59;15107:42;15146:2;15107:42;:::i;15091:59::-;15184:15;;;15270:1;15266:10;;;;15254:23;;15250:32;;;15215:12;;;;15294:15;;;15291:35;;;15322:1;15319;15312:12;15291:35;15358:2;15350:6;15346:15;15370:142;15386:6;15381:3;15378:15;15370:142;;;15452:17;;15440:30;;15490:12;;;;15403;;15370:142;;15546:1199;15709:6;15717;15725;15733;15741;15749;15757;15810:3;15798:9;15789:7;15785:23;15781:33;15778:53;;;15827:1;15824;15817:12;15778:53;15866:9;15853:23;15885:31;15910:5;15885:31;:::i;:::-;15935:5;-1:-1:-1;15959:37:1;15992:2;15977:18;;15959:37;:::i;:::-;15949:47;-1:-1:-1;16047:2:1;16032:18;;16019:32;-1:-1:-1;;;;;16100:14:1;;;16097:34;;;16127:1;16124;16117:12;16097:34;16150:49;16191:7;16182:6;16171:9;16167:22;16150:49;:::i;:::-;16140:59;;16252:2;16241:9;16237:18;16224:32;16208:48;;16281:2;16271:8;16268:16;16265:36;;;16297:1;16294;16287:12;16265:36;16320:63;16375:7;16364:8;16353:9;16349:24;16320:63;:::i;:::-;16310:73;;16435:3;16424:9;16420:19;16407:33;16392:48;;16449:33;16474:7;16449:33;:::i;:::-;16501:7;16491:17;;16527:39;16561:3;16550:9;16546:19;16527:39;:::i;:::-;16517:49;;16619:3;16608:9;16604:19;16591:33;16575:49;;16649:2;16639:8;16636:16;16633:36;;;16665:1;16662;16655:12;16750:478;16830:6;16838;16846;16899:2;16887:9;16878:7;16874:23;16870:32;16867:52;;;16915:1;16912;16905:12;16867:52;16942:23;;-1:-1:-1;;;;;16977:30:1;;16974:50;;;17020:1;17017;17010:12;16974:50;17059:58;17109:7;17100:6;17089:9;17085:22;17059:58;:::i;:::-;17136:8;;17033:84;;-1:-1:-1;17218:2:1;17203:18;;;;17190:32;;16750:478;-1:-1:-1;;;;16750:478:1:o;17661:1271::-;17843:6;17851;17859;17867;17875;17883;17891;17899;17952:3;17940:9;17931:7;17927:23;17923:33;17920:53;;;17969:1;17966;17959:12;17920:53;17992:29;18011:9;17992:29;:::i;:::-;17982:39;;18040:37;18073:2;18062:9;18058:18;18040:37;:::i;:::-;18030:47;-1:-1:-1;18128:2:1;18113:18;;18100:32;-1:-1:-1;;;;;18181:14:1;;;18178:34;;;18208:1;18205;18198:12;18178:34;18231:49;18272:7;18263:6;18252:9;18248:22;18231:49;:::i;:::-;18221:59;;18333:2;18322:9;18318:18;18305:32;18289:48;;18362:2;18352:8;18349:16;18346:36;;;18378:1;18375;18368:12;18346:36;18401:63;18456:7;18445:8;18434:9;18430:24;18401:63;:::i;:::-;18391:73;;18483:39;18517:3;18506:9;18502:19;18483:39;:::i;:::-;18473:49;;18541:39;18575:3;18564:9;18560:19;18541:39;:::i;:::-;18531:49;;18633:3;18622:9;18618:19;18605:33;18589:49;;18663:2;18653:8;18650:16;18647:36;;;18679:1;18676;18669:12;18647:36;18702:51;18745:7;18734:8;18723:9;18719:24;18702:51;:::i;:::-;18692:61;;18806:3;18795:9;18791:19;18778:33;18762:49;;18836:2;18826:8;18823:16;18820:36;;;18852:1;18849;18842:12;18820:36;;18875:51;18918:7;18907:8;18896:9;18892:24;18875:51;:::i;:::-;18865:61;;;17661:1271;;;;;;;;;;;:::o;18937:665::-;19032:6;19040;19048;19056;19109:3;19097:9;19088:7;19084:23;19080:33;19077:53;;;19126:1;19123;19116:12;19077:53;19165:9;19152:23;19184:31;19209:5;19184:31;:::i;:::-;19234:5;-1:-1:-1;19291:2:1;19276:18;;19263:32;19304:33;19263:32;19304:33;:::i;:::-;19356:7;-1:-1:-1;19410:2:1;19395:18;;19382:32;;-1:-1:-1;19465:2:1;19450:18;;19437:32;-1:-1:-1;;;;;19481:30:1;;19478:50;;;19524:1;19521;19514:12;19478:50;19547:49;19588:7;19579:6;19568:9;19564:22;19547:49;:::i;19607:1113::-;19764:6;19772;19780;19788;19796;19804;19812;19820;19873:3;19861:9;19852:7;19848:23;19844:33;19841:53;;;19890:1;19887;19880:12;19841:53;19913:29;19932:9;19913:29;:::i;:::-;19903:39;;19961:37;19994:2;19983:9;19979:18;19961:37;:::i;:::-;19951:47;-1:-1:-1;20049:2:1;20034:18;;20021:32;-1:-1:-1;;;;;20102:14:1;;;20099:34;;;20129:1;20126;20119:12;20099:34;20152:49;20193:7;20184:6;20173:9;20169:22;20152:49;:::i;:::-;20142:59;;20248:2;20237:9;20233:18;20220:32;20210:42;;20271:39;20305:3;20294:9;20290:19;20271:39;:::i;20725:622::-;20820:6;20828;20836;20844;20852;20905:3;20893:9;20884:7;20880:23;20876:33;20873:53;;;20922:1;20919;20912:12;20873:53;20945:28;20963:9;20945:28;:::i;:::-;20935:38;;20992:37;21025:2;21014:9;21010:18;20992:37;:::i;:::-;20982:47;-1:-1:-1;21076:2:1;21061:18;;21048:32;;-1:-1:-1;21131:2:1;21116:18;;21103:32;-1:-1:-1;;;;;21147:30:1;;21144:50;;;21190:1;21187;21180:12;21144:50;21229:58;21279:7;21270:6;21259:9;21255:22;21229:58;:::i;:::-;20725:622;;;;-1:-1:-1;20725:622:1;;-1:-1:-1;21306:8:1;;21203:84;20725:622;-1:-1:-1;;;20725:622:1:o;21352:460::-;21434:6;21442;21450;21503:2;21491:9;21482:7;21478:23;21474:32;21471:52;;;21519:1;21516;21509:12;21471:52;21542:28;21560:9;21542:28;:::i;:::-;21532:38;;21589:35;21620:2;21609:9;21605:18;21589:35;:::i;:::-;21579:45;-1:-1:-1;21675:2:1;21660:18;;21647:32;-1:-1:-1;;;;;21691:30:1;;21688:50;;;21734:1;21731;21724:12;21688:50;21757:49;21798:7;21789:6;21778:9;21774:22;21757:49;:::i;:::-;21747:59;;;21352:460;;;;;:::o;21817:324::-;21892:6;21900;21908;21961:2;21949:9;21940:7;21936:23;21932:32;21929:52;;;21977:1;21974;21967:12;21929:52;22000:28;22018:9;22000:28;:::i;:::-;21990:38;;22047:37;22080:2;22069:9;22065:18;22047:37;:::i;:::-;22037:47;;22131:2;22120:9;22116:18;22103:32;22093:42;;21817:324;;;;;:::o;22146:388::-;22214:6;22222;22275:2;22263:9;22254:7;22250:23;22246:32;22243:52;;;22291:1;22288;22281:12;22243:52;22330:9;22317:23;22349:31;22374:5;22349:31;:::i;:::-;22399:5;-1:-1:-1;22456:2:1;22441:18;;22428:32;22469:33;22428:32;22469:33;:::i;:::-;22521:7;22511:17;;;22146:388;;;;;:::o;22539:907::-;22673:6;22681;22689;22697;22705;22758:3;22746:9;22737:7;22733:23;22729:33;22726:53;;;22775:1;22772;22765:12;22726:53;22798:28;22816:9;22798:28;:::i;:::-;22788:38;-1:-1:-1;22877:2:1;22862:18;;22849:32;-1:-1:-1;;;;;22930:14:1;;;22927:34;;;22957:1;22954;22947:12;22927:34;22980:49;23021:7;23012:6;23001:9;22997:22;22980:49;:::i;:::-;22970:59;;23082:2;23071:9;23067:18;23054:32;23038:48;;23111:2;23101:8;23098:16;23095:36;;;23127:1;23124;23117:12;23095:36;23150:63;23205:7;23194:8;23183:9;23179:24;23150:63;:::i;:::-;23140:73;;23232:35;23263:2;23252:9;23248:18;23232:35;:::i;23451:460::-;23535:6;23543;23551;23559;23612:3;23600:9;23591:7;23587:23;23583:33;23580:53;;;23629:1;23626;23619:12;23580:53;23652:28;23670:9;23652:28;:::i;:::-;23642:38;;23699:37;23732:2;23721:9;23717:18;23699:37;:::i;:::-;23689:47;;23786:2;23775:9;23771:18;23758:32;23799:31;23824:5;23799:31;:::i;:::-;23451:460;;;;-1:-1:-1;23849:5:1;;23901:2;23886:18;23873:32;;-1:-1:-1;;23451:460:1:o;24275:380::-;24354:1;24350:12;;;;24397;;;24418:61;;24472:4;24464:6;24460:17;24450:27;;24418:61;24525:2;24517:6;24514:14;24494:18;24491:38;24488:161;;;24571:10;24566:3;24562:20;24559:1;24552:31;24606:4;24603:1;24596:15;24634:4;24631:1;24624:15;24488:161;;24275:380;;;:::o;24660:271::-;24843:6;24835;24830:3;24817:33;24799:3;24869:16;;24894:13;;;24869:16;24660:271;-1:-1:-1;24660:271:1:o;26580:409::-;26782:2;26764:21;;;26821:2;26801:18;;;26794:30;26860:34;26855:2;26840:18;;26833:62;-1:-1:-1;;;26926:2:1;26911:18;;26904:43;26979:3;26964:19;;26580:409::o;27204:266::-;27292:6;27287:3;27280:19;27344:6;27337:5;27330:4;27325:3;27321:14;27308:43;-1:-1:-1;27396:1:1;27371:16;;;27389:4;27367:27;;;27360:38;;;;27452:2;27431:15;;;-1:-1:-1;;27427:29:1;27418:39;;;27414:50;;27204:266::o;27475:326::-;27670:6;27662;27658:19;27647:9;27640:38;27714:2;27709;27698:9;27694:18;27687:30;27621:4;27734:61;27791:2;27780:9;27776:18;27768:6;27760;27734:61;:::i;27806:291::-;-1:-1:-1;;;;;28004:32:1;;;;27986:51;;28085:4;28073:17;28068:2;28053:18;;28046:45;27974:2;27959:18;;27806:291::o;28102:317::-;28279:2;28268:9;28261:21;28242:4;28299:45;28340:2;28329:9;28325:18;28317:6;28299:45;:::i;:::-;28291:53;;28409:1;28405;28400:3;28396:11;28392:19;28384:6;28380:32;28375:2;28364:9;28360:18;28353:60;28102:317;;;;;:::o;28424:348::-;28626:2;28608:21;;;28665:2;28645:18;;;28638:30;-1:-1:-1;;;28699:2:1;28684:18;;28677:54;28763:2;28748:18;;28424:348::o;29594:127::-;29655:10;29650:3;29646:20;29643:1;29636:31;29686:4;29683:1;29676:15;29710:4;29707:1;29700:15;29726:300;29911:6;29903;29899:19;29888:9;29881:38;29955:2;29950;29939:9;29935:18;29928:30;29862:4;29975:45;30016:2;30005:9;30001:18;29993:6;29975:45;:::i;30031:127::-;30092:10;30087:3;30083:20;30080:1;30073:31;30123:4;30120:1;30113:15;30147:4;30144:1;30137:15;30163:135;30202:3;-1:-1:-1;;30223:17:1;;30220:43;;;30243:18;;:::i;:::-;-1:-1:-1;30290:1:1;30279:13;;30163:135::o;30649:428::-;30702:5;30755:3;30748:4;30740:6;30736:17;30732:27;30722:55;;30773:1;30770;30763:12;30722:55;30802:6;30796:13;30833:48;30849:31;30877:2;30849:31;:::i;30833:48::-;30906:2;30897:7;30890:19;30952:3;30945:4;30940:2;30932:6;30928:15;30924:26;30921:35;30918:55;;;30969:1;30966;30959:12;30918:55;30982:64;31043:2;31036:4;31027:7;31023:18;31016:4;31008:6;31004:17;30982:64;:::i;31082:1103::-;31195:6;31203;31256:2;31244:9;31235:7;31231:23;31227:32;31224:52;;;31272:1;31269;31262:12;31224:52;31299:16;;-1:-1:-1;;;;;31364:14:1;;;31361:34;;;31391:1;31388;31381:12;31361:34;31414:60;31466:7;31457:6;31446:9;31442:22;31414:60;:::i;:::-;31404:70;;31493:2;31483:12;;31541:2;31530:9;31526:18;31520:25;31570:2;31560:8;31557:16;31554:36;;;31586:1;31583;31576:12;31554:36;31609:24;;;-1:-1:-1;31664:4:1;31656:13;;31652:27;-1:-1:-1;31642:55:1;;31693:1;31690;31683:12;31642:55;31722:2;31716:9;31745:59;31761:42;31800:2;31761:42;:::i;31745:59::-;31838:15;;;31920:1;31916:10;;;;31908:19;;31904:28;;;31869:12;;;;31944:19;;;31941:39;;;31976:1;31973;31966:12;31941:39;32000:11;;;;32020:135;32036:6;32031:3;32028:15;32020:135;;;32102:10;;32090:23;;32053:12;;;;32133;;;;32020:135;;;32174:5;32164:15;;;;;;;31082:1103;;;;;:::o;33625:125::-;33665:4;33693:1;33690;33687:8;33684:34;;;33698:18;;:::i;:::-;-1:-1:-1;33735:9:1;;33625:125::o;33755:374::-;33966:6;33958;33953:3;33940:33;34083:2;34054:15;;;;-1:-1:-1;;;;;;34050:45:1;33992:16;;34039:57;;;34120:2;34112:11;;33755:374;-1:-1:-1;33755:374:1:o;34134:168::-;34174:7;34240:1;34236;34232:6;34228:14;34225:1;34222:21;34217:1;34210:9;34203:17;34199:45;34196:71;;;34247:18;;:::i;:::-;-1:-1:-1;34287:9:1;;34134:168::o;34307:128::-;34347:3;34378:1;34374:6;34371:1;34368:13;34365:39;;;34384:18;;:::i;:::-;-1:-1:-1;34420:9:1;;34307:128::o;34440:414::-;34655:2;34644:9;34637:21;34618:4;34675:61;34732:2;34721:9;34717:18;34709:6;34701;34675:61;:::i;:::-;-1:-1:-1;;;;;34772:32:1;;;;34767:2;34752:18;;34745:60;-1:-1:-1;34836:2:1;34821:18;34814:34;34667:69;34440:414;-1:-1:-1;;34440:414:1:o;34859:470::-;35038:3;35076:6;35070:13;35092:53;35138:6;35133:3;35126:4;35118:6;35114:17;35092:53;:::i;:::-;35208:13;;35167:16;;;;35230:57;35208:13;35167:16;35264:4;35252:17;;35230:57;:::i;:::-;35303:20;;34859:470;-1:-1:-1;;;;34859:470:1:o;35334:498::-;35534:4;35563:6;35608:2;35600:6;35596:15;35585:9;35578:34;35660:2;35652:6;35648:15;35643:2;35632:9;35628:18;35621:43;;35700:6;35695:2;35684:9;35680:18;35673:34;35743:3;35738:2;35727:9;35723:18;35716:31;35764:62;35821:3;35810:9;35806:19;35798:6;35790;35764:62;:::i;:::-;35756:70;35334:498;-1:-1:-1;;;;;;;35334:498:1:o;37047:493::-;37296:6;37288;37284:19;37273:9;37266:38;37340:3;37335:2;37324:9;37320:18;37313:31;37247:4;37361:62;37418:3;37407:9;37403:19;37395:6;37387;37361:62;:::i;:::-;-1:-1:-1;;;;;37459:31:1;;;;37479:2;37439:18;;37432:59;-1:-1:-1;37522:2:1;37507:18;37500:34;37353:70;37047:493;-1:-1:-1;;;37047:493:1:o;37972:650::-;38261:6;38249:19;;38231:38;;-1:-1:-1;;;;;38305:32:1;;38300:2;38285:18;;38278:60;38325:3;38369:2;38354:18;;38347:31;;;-1:-1:-1;;38401:46:1;;38427:19;;38419:6;38401:46;:::i;:::-;38497:6;38490:14;38483:22;38478:2;38467:9;38463:18;38456:50;38555:9;38547:6;38543:22;38537:3;38526:9;38522:19;38515:51;38583:33;38609:6;38601;38583:33;:::i;:::-;38575:41;37972:650;-1:-1:-1;;;;;;;;37972:650:1:o;38627:245::-;38706:6;38714;38767:2;38755:9;38746:7;38742:23;38738:32;38735:52;;;38783:1;38780;38773:12;38735:52;-1:-1:-1;;38806:16:1;;38862:2;38847:18;;;38841:25;38806:16;;38841:25;;-1:-1:-1;38627:245:1:o;39240:435::-;39293:3;39331:5;39325:12;39358:6;39353:3;39346:19;39384:4;39413:2;39408:3;39404:12;39397:19;;39450:2;39443:5;39439:14;39471:1;39481:169;39495:6;39492:1;39489:13;39481:169;;;39556:13;;39544:26;;39590:12;;;;39625:15;;;;39517:1;39510:9;39481:169;;;-1:-1:-1;39666:3:1;;39240:435;-1:-1:-1;;;;;39240:435:1:o;39680:422::-;39905:2;39894:9;39887:21;39868:4;39931:45;39972:2;39961:9;39957:18;39949:6;39931:45;:::i;:::-;40024:9;40016:6;40012:22;40007:2;39996:9;39992:18;39985:50;40052:44;40089:6;40081;40052:44;:::i;:::-;40044:52;39680:422;-1:-1:-1;;;;;39680:422:1:o;41622:335::-;41701:6;41754:2;41742:9;41733:7;41729:23;41725:32;41722:52;;;41770:1;41767;41760:12;41722:52;41797:16;;-1:-1:-1;;;;;41825:30:1;;41822:50;;;41868:1;41865;41858:12;41822:50;41891:60;41943:7;41934:6;41923:9;41919:22;41891:60;:::i;41962:557::-;42219:6;42211;42207:19;42196:9;42189:38;42263:3;42258:2;42247:9;42243:18;42236:31;42170:4;42290:46;42331:3;42320:9;42316:19;42308:6;42290:46;:::i;:::-;-1:-1:-1;;;;;42372:31:1;;42392:2;42352:18;;42345:59;42440:22;;;42435:2;42420:18;;42413:50;42480:33;42444:6;42498;42480:33;:::i;42885:401::-;43087:2;43069:21;;;43126:2;43106:18;;;43099:30;43165:34;43160:2;43145:18;;43138:62;-1:-1:-1;;;43231:2:1;43216:18;;43209:35;43276:3;43261:19;;42885:401::o;44824:840::-;45173:6;45165;45161:19;45150:9;45143:38;45217:3;45212:2;45201:9;45197:18;45190:31;45124:4;45244:46;45285:3;45274:9;45270:19;45262:6;45244:46;:::i;:::-;45338:9;45330:6;45326:22;45321:2;45310:9;45306:18;45299:50;45372:33;45398:6;45390;45372:33;:::i;:::-;-1:-1:-1;;;;;45479:15:1;;;45474:2;45459:18;;45452:43;45532:15;;45526:3;45511:19;;45504:44;45585:22;;;45432:3;45564:19;;45557:51;45358:47;-1:-1:-1;45625:33:1;45358:47;45643:6;45625:33;:::i;:::-;45617:41;44824:840;-1:-1:-1;;;;;;;;;44824:840:1:o;46420:274::-;46549:3;46587:6;46581:13;46603:53;46649:6;46644:3;46637:4;46629:6;46625:17;46603:53;:::i;:::-;46672:16;;;;;46420:274;-1:-1:-1;;46420:274:1:o;46699:261::-;46878:2;46867:9;46860:21;46841:4;46898:56;46950:2;46939:9;46935:18;46927:6;46898:56;:::i;46965:289::-;47140:6;47129:9;47122:25;47183:2;47178;47167:9;47163:18;47156:30;47103:4;47203:45;47244:2;47233:9;47229:18;47221:6;47203:45;:::i;48662:414::-;48864:2;48846:21;;;48903:2;48883:18;;;48876:30;48942:34;48937:2;48922:18;;48915:62;-1:-1:-1;;;49008:2:1;48993:18;;48986:48;49066:3;49051:19;;48662:414::o;49213:719::-;49516:6;49508;49504:19;49493:9;49486:38;49560:3;49555:2;49544:9;49540:18;49533:31;49467:4;49587:46;49628:3;49617:9;49613:19;49605:6;49587:46;:::i;:::-;-1:-1:-1;;;;;49669:31:1;;49689:2;49649:18;;49642:59;49737:22;;;49732:2;49717:18;;49710:50;49783:33;49741:6;49801;49783:33;:::i;:::-;49769:47;;49865:9;49857:6;49853:22;49847:3;49836:9;49832:19;49825:51;49893:33;49919:6;49911;49893:33;:::i;51473:489::-;-1:-1:-1;;;;;51742:15:1;;;51724:34;;51794:15;;51789:2;51774:18;;51767:43;51841:2;51826:18;;51819:34;;;51889:3;51884:2;51869:18;;51862:31;;;51667:4;;51910:46;;51936:19;;51928:6;51910:46;:::i;:::-;51902:54;51473:489;-1:-1:-1;;;;;;51473:489:1:o;51967:249::-;52036:6;52089:2;52077:9;52068:7;52064:23;52060:32;52057:52;;;52105:1;52102;52095:12;52057:52;52137:9;52131:16;52156:30;52180:5;52156:30;:::i;52582:352::-;52784:2;52766:21;;;52823:2;52803:18;;;52796:30;-1:-1:-1;;;52857:2:1;52842:18;;52835:58;52925:2;52910:18;;52582:352::o

Swarm Source

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