ETH Price: $2,431.97 (-2.31%)

Token

Psyche.Art (PSY)
 

Overview

Max Total Supply

47 PSY

Holders

15

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
15151515151515.eth
Balance
1 PSY
0x531CDf82e7A2826259D8c8F95429c07764e33aDE
Loading...
Loading
Loading...
Loading
Loading...
Loading

Click here to update the token information / general information
# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
PsycheArt

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 300000 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-12-20
*/

// SPDX-License-Identifier: MIT

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



pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    bytes16 private constant _HEX_SYMBOLS = "0123456789abcdef";

    /**
     * @dev Converts a `uint256` to its ASCII `string` decimal representation.
     */
    function toString(uint256 value) internal pure returns (string memory) {
        // Inspired by OraclizeAPI's implementation - MIT licence
        // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }

    /**
     * @dev Converts a `uint256` to its ASCII `string` hexadecimal representation.
     */
    function toHexString(uint256 value) internal pure returns (string memory) {
        if (value == 0) {
            return "0x00";
        }
        uint256 temp = value;
        uint256 length = 0;
        while (temp != 0) {
            length++;
            temp >>= 8;
        }
        return toHexString(value, length);
    }

    /**
     * @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] = _HEX_SYMBOLS[value & 0xf];
            value >>= 4;
        }
        require(value == 0, "Strings: hex length insufficient");
        return string(buffer);
    }
}

// File: @openzeppelin/contracts/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/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() {
        _setOwner(_msgSender());
    }

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        require(owner() == _msgSender(), "Ownable: caller is not the owner");
        _;
    }

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        _setOwner(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");
        _setOwner(newOwner);
    }

    function _setOwner(address newOwner) private {
        address oldOwner = _owner;
        _owner = newOwner;
        emit OwnershipTransferred(oldOwner, newOwner);
    }
}

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



pragma solidity ^0.8.0;

/**
 * @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
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

        uint256 size;
        assembly {
            size := extcodesize(account)
        }
        return size > 0;
    }

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

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

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

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(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) {
        require(isContract(target), "Address: static call to non-contract");

        (bool success, bytes memory returndata) = target.staticcall(data);
        return verifyCallResult(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) {
        require(isContract(target), "Address: delegate call to non-contract");

        (bool success, bytes memory returndata) = target.delegatecall(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason 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 {
            // 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

                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

// File: @openzeppelin/contracts/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 `IERC721.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

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



pragma solidity ^0.8.0;

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

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



pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

// File: @openzeppelin/contracts/token/ERC721/extensions/IERC721Enumerable.sol



pragma solidity ^0.8.0;


/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {
    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

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

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

// File: @openzeppelin/contracts/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/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: balance query for the zero address");
        return _balances[owner];
    }

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        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) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

        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 overriden 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 owner nor approved for all"
        );

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        require(_exists(tokenId), "ERC721: approved query for nonexistent token");

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        require(operator != _msgSender(), "ERC721: approve to caller");

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_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: transfer caller is not owner nor 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: transfer caller is not owner nor 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 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 _owners[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) {
        require(_exists(tokenId), "ERC721: operator query for nonexistent token");
        address owner = ERC721.ownerOf(tokenId);
        return (spender == owner || getApproved(tokenId) == spender || isApprovedForAll(owner, 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);

        _balances[to] += 1;
        _owners[tokenId] = to;

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

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

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

        // Clear approvals
        _approve(address(0), tokenId);

        _balances[owner] -= 1;
        delete _owners[tokenId];

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

    /**
     * @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 of token that is not own");
        require(to != address(0), "ERC721: transfer to the zero address");

        _beforeTokenTransfer(from, to, tokenId);

        // Clear approvals from the previous owner
        _approve(address(0), tokenId);

        _balances[from] -= 1;
        _balances[to] += 1;
        _owners[tokenId] = to;

        emit Transfer(from, to, tokenId);
    }

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

    /**
     * @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 {
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}

// File: @openzeppelin/contracts/token/ERC721/extensions/ERC721Enumerable.sol



pragma solidity ^0.8.0;



/**
 * @dev This implements an optional extension of {ERC721} defined in the EIP that adds
 * enumerability of all the token ids in the contract as well as all token ids owned by each
 * account.
 */
abstract contract ERC721Enumerable is ERC721, IERC721Enumerable {
    // Mapping from owner to list of owned token IDs
    mapping(address => mapping(uint256 => uint256)) private _ownedTokens;

    // Mapping from token ID to index of the owner tokens list
    mapping(uint256 => uint256) private _ownedTokensIndex;

    // Array with all token ids, used for enumeration
    uint256[] private _allTokens;

    // Mapping from token id to position in the allTokens array
    mapping(uint256 => uint256) private _allTokensIndex;

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

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721.balanceOf(owner), "ERC721Enumerable: owner index out of bounds");
        return _ownedTokens[owner][index];
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        return _allTokens.length;
    }

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        require(index < ERC721Enumerable.totalSupply(), "ERC721Enumerable: global index out of bounds");
        return _allTokens[index];
    }

    /**
     * @dev Hook that is called before any token transfer. This includes minting
     * and burning.
     *
     * Calling conditions:
     *
     * - When `from` and `to` are both non-zero, ``from``'s `tokenId` will be
     * transferred to `to`.
     * - When `from` is zero, `tokenId` will be minted for `to`.
     * - When `to` is zero, ``from``'s `tokenId` will be burned.
     * - `from` cannot be the zero address.
     * - `to` cannot be the zero address.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, tokenId);

        if (from == address(0)) {
            _addTokenToAllTokensEnumeration(tokenId);
        } else if (from != to) {
            _removeTokenFromOwnerEnumeration(from, tokenId);
        }
        if (to == address(0)) {
            _removeTokenFromAllTokensEnumeration(tokenId);
        } else if (to != from) {
            _addTokenToOwnerEnumeration(to, tokenId);
        }
    }

    /**
     * @dev Private function to add a token to this extension's ownership-tracking data structures.
     * @param to address representing the new owner of the given token ID
     * @param tokenId uint256 ID of the token to be added to the tokens list of the given address
     */
    function _addTokenToOwnerEnumeration(address to, uint256 tokenId) private {
        uint256 length = ERC721.balanceOf(to);
        _ownedTokens[to][length] = tokenId;
        _ownedTokensIndex[tokenId] = length;
    }

    /**
     * @dev Private function to add a token to this extension's token tracking data structures.
     * @param tokenId uint256 ID of the token to be added to the tokens list
     */
    function _addTokenToAllTokensEnumeration(uint256 tokenId) private {
        _allTokensIndex[tokenId] = _allTokens.length;
        _allTokens.push(tokenId);
    }

    /**
     * @dev Private function to remove a token from this extension's ownership-tracking data structures. Note that
     * while the token is not assigned a new owner, the `_ownedTokensIndex` mapping is _not_ updated: this allows for
     * gas optimizations e.g. when performing a transfer operation (avoiding double writes).
     * This has O(1) time complexity, but alters the order of the _ownedTokens array.
     * @param from address representing the previous owner of the given token ID
     * @param tokenId uint256 ID of the token to be removed from the tokens list of the given address
     */
    function _removeTokenFromOwnerEnumeration(address from, uint256 tokenId) private {
        // To prevent a gap in from's tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = ERC721.balanceOf(from) - 1;
        uint256 tokenIndex = _ownedTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary
        if (tokenIndex != lastTokenIndex) {
            uint256 lastTokenId = _ownedTokens[from][lastTokenIndex];

            _ownedTokens[from][tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
            _ownedTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index
        }

        // This also deletes the contents at the last position of the array
        delete _ownedTokensIndex[tokenId];
        delete _ownedTokens[from][lastTokenIndex];
    }

    /**
     * @dev Private function to remove a token from this extension's token tracking data structures.
     * This has O(1) time complexity, but alters the order of the _allTokens array.
     * @param tokenId uint256 ID of the token to be removed from the tokens list
     */
    function _removeTokenFromAllTokensEnumeration(uint256 tokenId) private {
        // To prevent a gap in the tokens array, we store the last token in the index of the token to delete, and
        // then delete the last slot (swap and pop).

        uint256 lastTokenIndex = _allTokens.length - 1;
        uint256 tokenIndex = _allTokensIndex[tokenId];

        // When the token to delete is the last token, the swap operation is unnecessary. However, since this occurs so
        // rarely (when the last minted token is burnt) that we still do the swap here to avoid the gas cost of adding
        // an 'if' statement (like in _removeTokenFromOwnerEnumeration)
        uint256 lastTokenId = _allTokens[lastTokenIndex];

        _allTokens[tokenIndex] = lastTokenId; // Move the last token to the slot of the to-delete token
        _allTokensIndex[lastTokenId] = tokenIndex; // Update the moved token's index

        // This also deletes the contents at the last position of the array
        delete _allTokensIndex[tokenId];
        _allTokens.pop();
    }
}

// File: contracts/PsycheArt.sol


pragma solidity ^0.8.7;




/*
 🦋 PsycheArt - algorithm art butterflies.
*/

contract PsycheArt is ERC721Enumerable, Ownable {
    using Address for address;
    // consts define
    uint256 private constant SEX_FEMALE = 1;
    uint256 private constant SEX_MALE = 2;
    uint256 private constant SEX_BOTH = 3;
    
    uint256 private constant DATA_GEN = 0;
    uint256 private constant DATA_SEX = 1;
    uint256 private constant DATA_BREED_COUNT = 2;
    
    // 888 butterflies of 1st generation 
    uint256 private constant _maxSupply1stGen = 888;
    
    // max count per wallet addr.
    uint256 private constant _addressMaxMint = 5;
    
    // price will be
    uint256 private constant _price = 0.09 ether; 
    
    // breed price
    uint256 private constant _breedPrice = 0.02 ether;
    
    // token counter
    uint256 public nextTokenId = 1;
    
    // time
    uint256 public lastBreedTime;
    
    // ending time 12 hours
    uint256 private constant BREED_ENDING_TIME = 12 * 60 * 60;

    // sale time 
    uint256 public publicTime;
    
    // breed bonus value
    uint256 public currentBonus;

    // stored generation 5st tokenIds
    uint256[] private _tokensOf5thGen;

    // bred bonus records
    uint256[] private _bredBonusValues;

    // wallet
    address private walletAddr = 0xFdCEce98151bAd94001788E0b023201d0A33eDd7;
    
    // _lastBreedAddress 
    address[10] private _lastBreedAddress;

    // bred bonus records
    address[] private _bredBonusAddrs;
    
    // wallet adopt count
    mapping(address => uint256) private _addressAdopted;

    // white list
    mapping(address => uint256) private _whiteList;
    
    // butterflies generation info
    mapping(uint256 => uint256) private _butterfliesInfo;
    
    // butterflies images stored on ipfs
    string private _ipfsImageBaseURI;

    bool private _whiteListStarted;
    bool public revealed;

    event BreedEvent(address owner, uint256 childToken, uint256 info, uint256 bonus, bool feeback);
    event BonusEvent(uint256 eachBonus);
    event MintEvent(uint256 nextTokenId);

    constructor() ERC721("Psyche.Art", "PSY") {
    }

    function setWhiteListStarted(bool _isActive) external onlyOwner{
        _whiteListStarted = _isActive;
    }

    function whiteListStarted() public view returns(bool) {
        return _whiteListStarted;
    }

    function addToAllowList(address[] calldata addresses, uint256[] calldata counts) external onlyOwner {
        require(addresses.length == counts.length);

        for (uint256 i = 0; i < addresses.length; i++) {
            require(addresses[i] != address(0));
            _whiteList[addresses[i]] += counts[i];
        }
    }

    function getAllowListCount(address addr) external view returns (uint256) {
        return _whiteList[addr];
    }

    function removeFromAllowList(address[] calldata addresses) external onlyOwner {
        for (uint256 i = 0; i < addresses.length; i++) {
            require(addresses[i] != address(0));
            _whiteList[addresses[i]] = 0;
        }
    }

    function adoptWhitelist(uint256 quantity) external payable {
        require(_whiteListStarted);
        require(!msg.sender.isContract(), 'contract not allowed');
        uint256 supply = nextTokenId;
        require(quantity > 0 && supply + quantity - 1 <= _maxSupply1stGen);
        require(_whiteList[msg.sender] > 0 && quantity <= _whiteList[msg.sender]);
        require(quantity * _price <= msg.value,'Inconsistent eth sent');
        
        // deposite 20% of minting price to contract for bonus.
        // 10% for startup, 10% for the continue adding.
        currentBonus += msg.value / 10;
        payable(walletAddr).transfer(msg.value * 4 / 5);

        for (uint256 i; i < quantity; i++) {
            _safeMint(msg.sender, supply + i);
            _generateInfo(supply + i, 1);
        }
        nextTokenId += quantity;
        _whiteList[msg.sender] -= quantity;

        if (nextTokenId > _maxSupply1stGen) {
            revealed = true;
        }
        emit MintEvent(nextTokenId);
    }

    function adopt(uint256 quantity) external payable {
        require(publicTime > 0 && block.timestamp >= publicTime);
        require(!msg.sender.isContract(), 'contract not allowed');
        uint256 supply = nextTokenId;
        require(quantity > 0 && supply + quantity - 1 <= _maxSupply1stGen);
        require(_addressAdopted[msg.sender] + quantity <= _addressMaxMint);
        require(quantity * _price <= msg.value,'Inconsistent eth sent');

        _addressAdopted[msg.sender] += quantity;
        
        // deposite 20% of minting price to contract for bonus.
        // 10% for startup, 10% for the continue adding.
        currentBonus += msg.value / 10;
        payable(walletAddr).transfer(msg.value * 4 / 5);

        for (uint256 i; i < quantity; i++) {
            _safeMint(msg.sender, supply + i);
            _generateInfo(supply + i, 1);
        }
        nextTokenId += quantity;
        
        if (nextTokenId > _maxSupply1stGen) {
            revealed = true;
        }
        emit MintEvent(nextTokenId);
    }
    
    function breed(uint256 tokenId1, uint256 tokenId2) external payable {
        require(publicTime > 0 && block.timestamp >= publicTime);
        require(revealed, "Not revealed");
        require(lastBreedTime <= 0 || block.timestamp - lastBreedTime < BREED_ENDING_TIME);
        require(!msg.sender.isContract());
        require(ownerOf(tokenId1) == address(msg.sender) && ownerOf(tokenId2) == address(msg.sender));
        require(_breedPrice <= msg.value, 'Inconsistent eth sent');
        
        uint256 parentInfo1 = _butterfliesInfo[tokenId1];
        uint256 parentInfo2 = _butterfliesInfo[tokenId2];
        
        // require breed state, make sure the parent can breed
        uint256 parentBreedcount1 = uint8a32.get(parentInfo1, DATA_BREED_COUNT);
        require(parentBreedcount1 > 0, 'Parent1 cannot breed');
        
        uint256 parentBreedcount2 = uint8a32.get(parentInfo2, DATA_BREED_COUNT);
        require(parentBreedcount2 > 0, 'Parent2 cannot breed');
        
        require(uint8a32.get(parentInfo1, DATA_SEX) != uint8a32.get(parentInfo2, DATA_SEX), 'Gender dismatch');
        
        uint256 parentGen1 = uint8a32.get(parentInfo1, DATA_GEN);
        uint256 parentGen2 = uint8a32.get(parentInfo2, DATA_GEN);
        // the next generation depends on the older generation
        uint256 childGeneration = parentGen1 < parentGen2 ? parentGen1 + 1: parentGen2 + 1;

        _butterfliesInfo[tokenId1] = uint8a32.set(parentInfo1, DATA_BREED_COUNT, parentBreedcount1 - 1);
        _butterfliesInfo[tokenId2] = uint8a32.set(parentInfo2, DATA_BREED_COUNT, parentBreedcount2 - 1);
        
        // generate child info
        (uint256 sex, uint256 seed) = _generateInfo(nextTokenId, childGeneration);
        // mint the child
        _safeMint(msg.sender, nextTokenId);
        
        // add breed fee
        currentBonus += _breedPrice;

        // update nextToken
        nextTokenId ++;
        
        // update breed record
        address sender = address(msg.sender);
        uint256 src;
        for (uint256 i; i < 10; i ++) {
            if (_lastBreedAddress[i] == sender) {
                src = i;
                break;
            }
        }
        for (uint256 j = src; j < 9; j ++) {
            _lastBreedAddress[j] = _lastBreedAddress[j + 1];
        }
        _lastBreedAddress[9] = sender;
        lastBreedTime = block.timestamp;

        // holding 5st generation has 50% chance to get breed fee back
        bool feeback;
        if (random(seed, 0) % 2 == 0) {
            uint256 len = _tokensOf5thGen.length;
            if (len > 0) {
                for (uint256 m; m < len; m++) {
                    address holder = ownerOf(_tokensOf5thGen[m]);
                    if (holder == sender) { 
                        payable(sender).transfer(_breedPrice);
                        currentBonus -= _breedPrice;
                        feeback = true;
                        break;
                    }
                }
            }
        }
        // 5st generation add to list
        if (childGeneration > 4) {
            _tokensOf5thGen.push(childGeneration);
        }

        // address who bred Androgynous one may get the 50% of current bonus value
        if (sex == SEX_BOTH && currentBonus <= address(this).balance) {
            uint256 bredBonus = currentBonus / 2;
            currentBonus = currentBonus - bredBonus;
            
            payable(sender).transfer(bredBonus);

            // add 1eth to current bonus when 500 increased
            fillBonusEvery500();
            // emit event
            emit BreedEvent(msg.sender, nextTokenId-1, _butterfliesInfo[nextTokenId-1], bredBonus, feeback);

            // store bonus records
            uint256 cnt = _bredBonusAddrs.length;
            for (uint256 n; n < cnt; n ++) {
                if (_bredBonusAddrs[n] == sender){
                    _bredBonusValues[n] += bredBonus;
                    return;
                }
            }
            _bredBonusAddrs.push(sender);
            _bredBonusValues.push(bredBonus);
            return;
        }
        // add 1eth to current bonus when 500 increased
        fillBonusEvery500();
        // emit event
        emit BreedEvent(msg.sender, nextTokenId-1, _butterfliesInfo[nextTokenId-1], 0, feeback);
    }

    function fillBonusEvery500() internal {
        // add 1eth to current bonus when 500 increased
        if ((nextTokenId - _maxSupply1stGen) % 500 == 1) {
            if (address(this).balance > currentBonus + 1 ether) {
                currentBonus += 1 ether;
            } else {
                currentBonus = address(this).balance;
            }
        }
    }
    
    // distribute bonus to the last 10 addresses.
    function distributeBonus() external onlyOwner {
        require(lastBreedTime > 0 && block.timestamp - lastBreedTime >= BREED_ENDING_TIME, 'still breeding');

        uint256 breedAddressCount;
        for (uint256 i = 0; i < 10; i ++) {
            if (_lastBreedAddress[i] != address(0)) {
                breedAddressCount ++;
            }
        }

        if (currentBonus > address(this).balance) {
            currentBonus = address(this).balance;
        }
        // cut to equal pieces
        uint256 eachBonus = currentBonus / breedAddressCount;
        for (uint256 i = 0; i < 10; i ++) {
            if (_lastBreedAddress[i] != address(0)) {
                payable(_lastBreedAddress[i]).transfer(eachBonus);
            }
        }
        currentBonus = 0;
        // if balance left , return to creator.
        if (address(this).balance > 0) {
            payable(walletAddr).transfer(address(this).balance);
        }
        
        // emit event
        emit BonusEvent(eachBonus);
    }
   
    function getTokensOfOwner(address addr) external view returns (uint256[] memory) {
        uint256 amount = balanceOf(addr);
        uint256[] memory tokens = new uint256[](amount);
        for (uint256 i; i < amount; i ++) {
            tokens[i] = tokenOfOwnerByIndex(addr, i);
        }
        return tokens;
    }

    function getBredRecords() external view returns(address[] memory, uint256[] memory, address[10] memory) {
        return (_bredBonusAddrs, _bredBonusValues, _lastBreedAddress);
    }
    
    function setPublicTime(uint256 _publicTime) external onlyOwner { 
        publicTime = _publicTime;
    }

    function saleStarted() external view returns(bool) {
        return publicTime > 0 && block.timestamp >= publicTime;
    }

    function setRevealed() external onlyOwner {
        revealed = true;
    }

    function getBreedStatus() external view returns(uint256) {
        if (!revealed) {
            return 1;
        }
        if (lastBreedTime > 0 && block.timestamp - lastBreedTime >= BREED_ENDING_TIME) {
            return 2;
        }
        return 0;
    }
    
    function setImageBaseURI(string calldata baseUri) external onlyOwner {
        _ipfsImageBaseURI = baseUri;
    }
    
    function tokenURI(uint256 tokenId) override public view returns (string memory) {
        require(_exists(tokenId));
        string memory json;
        if (!revealed) {
            json = Base64.encode(bytes(string(abi.encodePacked('{"name": "ButterFly #', Base64.toString(tokenId), description, _ipfsImageBaseURI, '"}'))));
        } else {
            uint256 butterflyInfo = _butterfliesInfo[tokenId];
            uint256 sex = uint8a32.get(butterflyInfo, DATA_SEX);
            uint256 generation = uint8a32.get(butterflyInfo, DATA_GEN);
            uint256 breedcount = uint8a32.get(butterflyInfo, DATA_BREED_COUNT);

            string memory szTokenId = Base64.toString(tokenId);
            string memory szGender;
            if (sex == SEX_FEMALE) {
                szGender = "Female";
            } else if (sex == SEX_MALE) {
                szGender = "Male";
            } else {
                szGender = "Androgynous";
            }
            
            uint256 breedMaxcount;
            // the max generation and Androgynous butterfly cannot breed next child
            if (sex != SEX_BOTH) {
                if (generation < 4) {
                    breedMaxcount = 4 - generation;
                } else if (generation == 4) {
                    breedMaxcount = 1;
                }
            }
            
            string memory breedstate = string(abi.encodePacked(Base64.toString(breedcount), "/", Base64.toString(breedMaxcount)));
            string memory attributes = string(abi.encodePacked('"attributes": [{"trait_type":"Gender","value": "', szGender,'"}, {"trait_type":"Breedable","value": "', breedcount > 0 ? "True" : "False",'"}, {"trait_type":"BreedCount","value": "', breedstate,'"}, {"trait_type":"Generation","value": "', Base64.toString(generation),'"}]'));
            json = Base64.encode(bytes(string(abi.encodePacked('{"name": "', sex == SEX_BOTH ? 'Ghost #' : 'ButterFly #', szTokenId, description, _ipfsImageBaseURI, szTokenId, sex == SEX_BOTH ? '10.png",' : '00.png",', attributes, '}'))));
        }
        string memory output = string(abi.encodePacked('data:application/json;base64,', json));
        return output;
    }
    
    function random(uint256 seed1, uint256 seed2) internal view returns(uint256) {
        return uint256(keccak256(abi.encodePacked(tx.origin, blockhash(block.number - 1), block.timestamp, seed1, seed2)));
    }

    function _generateInfo(uint256 tokenId, uint256 generation) internal returns(uint256, uint256){
        //random sex
        uint256 rand = random(generation, tokenId);
        uint256 sex;
        if (generation <= 1) {
            if (rand % 2 == 0) {
                // 50% for female
                sex = SEX_FEMALE;
            } else {
                sex = SEX_MALE;
            }
        } else {
            // 0.5% for Androgynous
            if (rand % 1000 < 5) { 
                sex = SEX_BOTH;
            // 49.75% for female
            } else if (rand % 2 == 0) {
                sex = SEX_FEMALE;
            } else { 
                sex = SEX_MALE;
            }
        }
        
        uint256 info; // uint32 generation, uint32 sex, uint32 breedcount
        info = uint8a32.set(info, DATA_GEN, generation);
        info = uint8a32.set(info, DATA_SEX, sex);
        
        uint256 breedcount;
        // the max generation and Androgynous butterfly cannot breed next child
        if (sex != SEX_BOTH) {
            if (generation < 4) {
                breedcount = 4 - generation;
            } else if (generation == 4) {
                breedcount = 1;
            }
        }
        
        _butterfliesInfo[tokenId] = uint8a32.set(info, DATA_BREED_COUNT, breedcount);

        return (sex, rand);
    }
    
    function getButterflyInfo(uint256[] memory tokenId) external view returns(uint32[] memory) {
        uint256 count = tokenId.length;
        uint32[] memory infos = new uint32[](count);
        uint256 id;
        for (uint256 i; i < count; i++) {
            id = tokenId[i];
            require(_exists(id));
            infos[i] = uint32(_butterfliesInfo[id]);
        }
        return infos;
    }

    string private constant description = '", "description": "Psyche.Art is an algorithm art collection of 888 OG on-chain butterflies. All the metadata are stored on the smart contract and images are stored on IPFS.","image": "';
}

library Base64 {
    bytes internal constant TABLE = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";

    /// @notice Encodes some bytes to the base64 representation
    function encode(bytes memory data) internal pure returns (string memory) {
        uint256 len = data.length;
        if (len == 0) return "";

        // multiply by 4/3 rounded up
        uint256 encodedLen = 4 * ((len + 2) / 3);

        // Add some extra buffer at the end
        bytes memory result = new bytes(encodedLen + 32);

        bytes memory table = TABLE;

        assembly {
            let tablePtr := add(table, 1)
            let resultPtr := add(result, 32)

            for {
                let i := 0
            } lt(i, len) {

            } {
                i := add(i, 3)
                let input := and(mload(add(data, i)), 0xffffff)

                let out := mload(add(tablePtr, and(shr(18, input), 0x3F)))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(shr(12, input), 0x3F))), 0xFF))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(shr(6, input), 0x3F))), 0xFF))
                out := shl(8, out)
                out := add(out, and(mload(add(tablePtr, and(input, 0x3F))), 0xFF))
                out := shl(224, out)

                mstore(resultPtr, out)

                resultPtr := add(resultPtr, 4)
            }

            switch mod(len, 3)
            case 1 {
                mstore(sub(resultPtr, 2), shl(240, 0x3d3d))
            }
            case 2 {
                mstore(sub(resultPtr, 1), shl(248, 0x3d))
            }

            mstore(result, encodedLen)
        }

        return string(result);
    }
    
    function toString(uint256 value) internal pure returns (string memory) {
    // Inspired by OraclizeAPI's implementation - MIT license
    // https://github.com/oraclize/ethereum-api/blob/b42146b063c7d6ee1358846c198246239e9360e8/oraclizeAPI_0.4.25.sol

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }
}

// uint8[32]
library uint8a32 { 
    uint256 constant bits = 8;
    uint256 constant elements = 32;
    uint256 constant range = 1 << bits;
    uint256 constant max = range - 1;

    // get value
    function get(uint256 srcValue, uint256 index) internal pure returns (uint256) {
        require(index < elements, 'idx oor');
        return ((srcValue >> (bits * index)) & (max));
    }
    
    // set value
    function set(uint256 srcValue, uint256 index, uint256 value) internal pure returns (uint256) {
        require(index < elements, 'idx oor');
        require(value < range, 'val oor');
        index *= bits;
        return (srcValue & ~(max << index)) | (value << index);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"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":"uint256","name":"eachBonus","type":"uint256"}],"name":"BonusEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"owner","type":"address"},{"indexed":false,"internalType":"uint256","name":"childToken","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"info","type":"uint256"},{"indexed":false,"internalType":"uint256","name":"bonus","type":"uint256"},{"indexed":false,"internalType":"bool","name":"feeback","type":"bool"}],"name":"BreedEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"uint256","name":"nextTokenId","type":"uint256"}],"name":"MintEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address[]","name":"addresses","type":"address[]"},{"internalType":"uint256[]","name":"counts","type":"uint256[]"}],"name":"addToAllowList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"adopt","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"adoptWhitelist","outputs":[],"stateMutability":"payable","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":[{"internalType":"uint256","name":"tokenId1","type":"uint256"},{"internalType":"uint256","name":"tokenId2","type":"uint256"}],"name":"breed","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"currentBonus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"distributeBonus","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getAllowListCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBredRecords","outputs":[{"internalType":"address[]","name":"","type":"address[]"},{"internalType":"uint256[]","name":"","type":"uint256[]"},{"internalType":"address[10]","name":"","type":"address[10]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getBreedStatus","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenId","type":"uint256[]"}],"name":"getButterflyInfo","outputs":[{"internalType":"uint32[]","name":"","type":"uint32[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"addr","type":"address"}],"name":"getTokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"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":[],"name":"lastBreedTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextTokenId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"publicTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"addresses","type":"address[]"}],"name":"removeFromAllowList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"revealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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":[],"name":"saleStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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":"setImageBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_publicTime","type":"uint256"}],"name":"setPublicTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setRevealed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_isActive","type":"bool"}],"name":"setWhiteListStarted","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"whiteListStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]

60806040526001600b55601180546001600160a01b03191673fdcece98151bad94001788e0b023201d0a33edd71790553480156200003c57600080fd5b50604080518082018252600a815269141cde58da194b905c9d60b21b60208083019182528351808501909452600384526250535960e81b9084015281519192916200008a9160009162000119565b508051620000a090600190602084019062000119565b505050620000bd620000b7620000c360201b60201c565b620000c7565b620001fc565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b8280546200012790620001bf565b90600052602060002090601f0160209004810192826200014b576000855562000196565b82601f106200016657805160ff191683800117855562000196565b8280016001018555821562000196579182015b828111156200019657825182559160200191906001019062000179565b50620001a4929150620001a8565b5090565b5b80821115620001a45760008155600101620001a9565b600181811c90821680620001d457607f821691505b60208210811415620001f657634e487b7160e01b600052602260045260246000fd5b50919050565b615534806200020c6000396000f3fe6080604052600436106102c65760003560e01c8063715018a611610179578063a22cb465116100d6578063d9ecad7b1161008a578063eca73f6411610064578063eca73f64146107ba578063f1088700146107d0578063f2fde38b146107f057600080fd5b8063d9ecad7b1461073e578063e985e9c514610751578063eaa5bea0146107a757600080fd5b8063b88d4fde116100bb578063b88d4fde146106da578063c87b56dd146106fa578063d69d0d001461071a57600080fd5b8063a22cb4651461069a578063a51312c8146106ba57600080fd5b80638588b2c51161012d5780638e2ffd63116101125780638e2ffd631461062d57806395d89b41146106705780639a35646f1461068557600080fd5b80638588b2c5146105ef5780638da5cb5b1461060257600080fd5b806375794a3c1161015e57806375794a3c146105945780637fd705ba146105aa578063824553cc146105c257600080fd5b8063715018a61461056a57806373630c651461057f57600080fd5b80633bd64968116102275780635c474f9e116101db5780636352211e116101c05780636352211e1461050a5780636cfa24cc1461052a57806370a082311461054a57600080fd5b80635c474f9e146104c85780635de6dc55146104dd57600080fd5b806342842e0e1161020c57806342842e0e146104695780634f6ccce71461048957806351830227146104a957600080fd5b80633bd649681461043e578063416e39e71461045357600080fd5b806318160ddd1161027e578063218f197e11610263578063218f197e146103de57806323b872dd146103fe5780632f745c591461041e57600080fd5b806318160ddd146103a95780631bdc608e146103c857600080fd5b8063081812fc116102af578063081812fc14610322578063095ea7b314610367578063150c5c261461038957600080fd5b806301ffc9a7146102cb57806306fdde0314610300575b600080fd5b3480156102d757600080fd5b506102eb6102e63660046149e7565b610810565b60405190151581526020015b60405180910390f35b34801561030c57600080fd5b5061031561086c565b6040516102f7919061513d565b34801561032e57600080fd5b5061034261033d366004614a93565b6108fe565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102f7565b34801561037357600080fd5b50610387610382366004614847565b6109dd565b005b34801561039557600080fd5b506103876103a4366004614a93565b610b6a565b3480156103b557600080fd5b506008545b6040519081526020016102f7565b3480156103d457600080fd5b506103ba600d5481565b3480156103ea57600080fd5b506103876103f93660046148b3565b610bf0565b34801561040a57600080fd5b50610387610419366004614703565b610d7e565b34801561042a57600080fd5b506103ba610439366004614847565b610e1f565b34801561044a57600080fd5b50610387610eee565b34801561045f57600080fd5b506103ba600c5481565b34801561047557600080fd5b50610387610484366004614703565b610f9d565b34801561049557600080fd5b506103ba6104a4366004614a93565b610fb8565b3480156104b557600080fd5b506021546102eb90610100900460ff1681565b3480156104d457600080fd5b506102eb611076565b3480156104e957600080fd5b506104fd6104f83660046146ae565b611090565b6040516102f791906150e0565b34801561051657600080fd5b50610342610525366004614a93565b611132565b34801561053657600080fd5b50610387610545366004614a21565b6111e4565b34801561055657600080fd5b506103ba6105653660046146ae565b611271565b34801561057657600080fd5b5061038761133f565b34801561058b57600080fd5b506103ba6113cc565b3480156105a057600080fd5b506103ba600b5481565b3480156105b657600080fd5b5060215460ff166102eb565b3480156105ce57600080fd5b506105e26105dd36600461491f565b611416565b6040516102f791906150f3565b6103876105fd366004614a93565b611515565b34801561060e57600080fd5b50600a5473ffffffffffffffffffffffffffffffffffffffff16610342565b34801561063957600080fd5b506103ba6106483660046146ae565b73ffffffffffffffffffffffffffffffffffffffff166000908152601e602052604090205490565b34801561067c57600080fd5b506103156117ea565b34801561069157600080fd5b506103876117f9565b3480156106a657600080fd5b506103876106b536600461481d565b611ab1565b3480156106c657600080fd5b506103876106d5366004614871565b611bc8565b3480156106e657600080fd5b506103876106f536600461473f565b611d04565b34801561070657600080fd5b50610315610715366004614a93565b611dac565b34801561072657600080fd5b5061072f6121dc565b6040516102f793929190615030565b61038761074c366004614aac565b6122fb565b34801561075d57600080fd5b506102eb61076c3660046146d0565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260056020908152604080832093909416825291909152205460ff1690565b6103876107b5366004614a93565b612cd5565b3480156107c657600080fd5b506103ba600e5481565b3480156107dc57600080fd5b506103876107eb3660046149cc565b612f1f565b3480156107fc57600080fd5b5061038761080b3660046146ae565b612fd1565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f780e9d63000000000000000000000000000000000000000000000000000000001480610866575061086682613101565b92915050565b60606000805461087b9061524b565b80601f01602080910402602001604051908101604052809291908181526020018280546108a79061524b565b80156108f45780601f106108c9576101008083540402835291602001916108f4565b820191906000526020600020905b8154815290600101906020018083116108d757829003601f168201915b5050505050905090565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff166109b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5060009081526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60006109e882611132565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610aa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f720000000000000000000000000000000000000000000000000000000000000060648201526084016109ab565b3373ffffffffffffffffffffffffffffffffffffffff82161480610acf5750610acf813361076c565b610b5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016109ab565b610b6583836131e4565b505050565b600a5473ffffffffffffffffffffffffffffffffffffffff163314610beb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109ab565b600d55565b600a5473ffffffffffffffffffffffffffffffffffffffff163314610c71576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109ab565b828114610c7d57600080fd5b60005b83811015610d77576000858583818110610c9c57610c9c615379565b9050602002016020810190610cb191906146ae565b73ffffffffffffffffffffffffffffffffffffffff161415610cd257600080fd5b828282818110610ce457610ce4615379565b90506020020135601e6000878785818110610d0157610d01615379565b9050602002016020810190610d1691906146ae565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610d5f919061519f565b90915550819050610d6f8161529f565b915050610c80565b5050505050565b610d883382613284565b610e14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016109ab565b610b658383836133f4565b6000610e2a83611271565b8210610eb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e647300000000000000000000000000000000000000000060648201526084016109ab565b5073ffffffffffffffffffffffffffffffffffffffff919091166000908152600660209081526040808320938352929052205490565b600a5473ffffffffffffffffffffffffffffffffffffffff163314610f6f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109ab565b602180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b610b6583838360405180602001604052806000815250611d04565b6000610fc360085490565b8210611051576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e6473000000000000000000000000000000000000000060648201526084016109ab565b6008828154811061106457611064615379565b90600052602060002001549050919050565b600080600d5411801561108b5750600d544210155b905090565b6060600061109d83611271565b905060008167ffffffffffffffff8111156110ba576110ba6153a8565b6040519080825280602002602001820160405280156110e3578160200160208202803683370190505b50905060005b8281101561112a576110fb8582610e1f565b82828151811061110d5761110d615379565b6020908102919091010152806111228161529f565b9150506110e9565b509392505050565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff1680610866576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e000000000000000000000000000000000000000000000060648201526084016109ab565b600a5473ffffffffffffffffffffffffffffffffffffffff163314611265576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109ab565b610b656020838361455a565b600073ffffffffffffffffffffffffffffffffffffffff8216611316576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f20616464726573730000000000000000000000000000000000000000000060648201526084016109ab565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205490565b600a5473ffffffffffffffffffffffffffffffffffffffff1633146113c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109ab565b6113ca6000613666565b565b602154600090610100900460ff166113e45750600190565b6000600c54118015611405575061a8c0600c54426114029190615208565b10155b156114105750600290565b50600090565b805160609060008167ffffffffffffffff811115611436576114366153a8565b60405190808252806020026020018201604052801561145f578160200160208202803683370190505b5090506000805b8381101561150b5785818151811061148057611480615379565b602002602001015191506114b88260009081526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16151590565b6114c157600080fd5b6000828152601f602052604090205483518490839081106114e4576114e4615379565b63ffffffff90921660209283029190910190910152806115038161529f565b915050611466565b5090949350505050565b6000600d541180156115295750600d544210155b61153257600080fd5b333b1561159b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f636f6e7472616374206e6f7420616c6c6f77656400000000000000000000000060448201526064016109ab565b600b5481158015906115c4575061037860016115b7848461519f565b6115c19190615208565b11155b6115cd57600080fd5b336000908152601d60205260409020546005906115eb90849061519f565b11156115f657600080fd5b3461160967013fbe85edc90000846151cb565b1115611671576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f496e636f6e73697374656e74206574682073656e74000000000000000000000060448201526064016109ab565b336000908152601d60205260408120805484929061169090849061519f565b909155506116a19050600a346151b7565b600e60008282546116b2919061519f565b909155505060115473ffffffffffffffffffffffffffffffffffffffff166108fc60056116e03460046151cb565b6116ea91906151b7565b6040518115909202916000818181858888f19350505050158015611712573d6000803e3d6000fd5b5060005b8281101561175a576117313361172c838561519f565b6136dd565b61174561173e828461519f565b60016136fb565b505080806117529061529f565b915050611716565b5081600b600082825461176d919061519f565b9091555050600b5461037810156117ab57602180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b7f94242c431036b9ba6723a138d4b275a5b38e13a95ef66227a45df427c0f843f3600b546040516117de91815260200190565b60405180910390a15050565b60606001805461087b9061524b565b600a5473ffffffffffffffffffffffffffffffffffffffff16331461187a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109ab565b6000600c5411801561189b575061a8c0600c54426118989190615208565b10155b611901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374696c6c206272656564696e6700000000000000000000000000000000000060448201526064016109ab565b6000805b600a811015611960576000601282600a811061192357611923615379565b015473ffffffffffffffffffffffffffffffffffffffff161461194e578161194a8161529f565b9250505b806119588161529f565b915050611905565b5047600e5411156119705747600e555b600081600e5461198091906151b7565b905060005b600a811015611a2d576000601282600a81106119a3576119a3615379565b015473ffffffffffffffffffffffffffffffffffffffff1614611a1b57601281600a81106119d3576119d3615379565b015460405173ffffffffffffffffffffffffffffffffffffffff9091169083156108fc029084906000818181858888f19350505050158015611a19573d6000803e3d6000fd5b505b80611a258161529f565b915050611985565b506000600e554715611a815760115460405173ffffffffffffffffffffffffffffffffffffffff909116904780156108fc02916000818181858888f19350505050158015611a7f573d6000803e3d6000fd5b505b6040518181527f98ada995bbd1dfd160d624e47773dd5df034f32c892209a0802551bd7780441f906020016117de565b73ffffffffffffffffffffffffffffffffffffffff8216331415611b31576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016109ab565b33600081815260056020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600a5473ffffffffffffffffffffffffffffffffffffffff163314611c49576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109ab565b60005b81811015610b65576000838383818110611c6857611c68615379565b9050602002016020810190611c7d91906146ae565b73ffffffffffffffffffffffffffffffffffffffff161415611c9e57600080fd5b6000601e6000858585818110611cb657611cb6615379565b9050602002016020810190611ccb91906146ae565b73ffffffffffffffffffffffffffffffffffffffff16815260208101919091526040016000205580611cfc8161529f565b915050611c4c565b611d0e3383613284565b611d9a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016109ab565b611da6848484846137e7565b50505050565b60008181526002602052604090205460609073ffffffffffffffffffffffffffffffffffffffff16611ddd57600080fd5b602154606090610100900460ff16611e4357611e3c611dfb8461388a565b6040518060e0016040528060b9815260200161544660b991396020604051602001611e2893929190614f58565b6040516020818303038152906040526139bc565b9050612193565b6000838152601f602052604081205490611e5e826001613b95565b90506000611e6d836000613b95565b90506000611e7c846002613b95565b90506000611e898861388a565b905060606001851415611ed0575060408051808201909152600681527f46656d616c6500000000000000000000000000000000000000000000000000006020820152611f49565b6002851415611f13575060408051808201909152600481527f4d616c65000000000000000000000000000000000000000000000000000000006020820152611f49565b5060408051808201909152600b81527f416e64726f67796e6f757300000000000000000000000000000000000000000060208201525b600060038614611f7b576004851015611f6e57611f67856004615208565b9050611f7b565b8460041415611f7b575060015b6000611f868561388a565b611f8f8361388a565b604051602001611fa0929190614c40565b604051602081830303815290604052905060008360008711611ff7576040518060400160405280600581526020017f46616c736500000000000000000000000000000000000000000000000000000081525061202e565b6040518060400160405280600481526020017f54727565000000000000000000000000000000000000000000000000000000008152505b836120388a61388a565b60405160200161204b9493929190614c98565b6040516020818303038152906040529050612187600389146120a2576040518060400160405280600b81526020017f427574746572466c7920230000000000000000000000000000000000000000008152506120d9565b6040518060400160405280600781526020017f47686f73742023000000000000000000000000000000000000000000000000008152505b866040518060e0016040528060b9815260200161544660b9913960208960038e14612139576040518060400160405280600881526020017f30302e706e67222c000000000000000000000000000000000000000000000000815250612170565b6040518060400160405280600881526020017f31302e706e67222c0000000000000000000000000000000000000000000000008152505b87604051602001611e289796959493929190614e33565b99505050505050505050505b6000816040516020016121a69190614f13565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052949350505050565b6060806121e76145fc565b601c601060128280548060200260200160405190810160405280929190818152602001828054801561224f57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612224575b50505050509250818054806020026020016040519081016040528092919081815260200182805480156122a157602002820191906000526020600020905b81548152602001906001019080831161228d575b505060408051610140810191829052949650859350600a9250905082845b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116122bf5750505050509050925092509250909192565b6000600d5411801561230f5750600d544210155b61231857600080fd5b602154610100900460ff16612389576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4e6f742072657665616c6564000000000000000000000000000000000000000060448201526064016109ab565b600c5415806123a6575061a8c0600c54426123a49190615208565b105b6123af57600080fd5b333b156123bb57600080fd5b336123c583611132565b73ffffffffffffffffffffffffffffffffffffffff161480156124055750336123ed82611132565b73ffffffffffffffffffffffffffffffffffffffff16145b61240e57600080fd5b3466470de4df820000111561247f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f496e636f6e73697374656e74206574682073656e74000000000000000000000060448201526064016109ab565b6000828152601f6020526040808220548383529082205490916124a3836002613b95565b90506000811161250f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f506172656e74312063616e6e6f7420627265656400000000000000000000000060448201526064016109ab565b600061251c836002613b95565b905060008111612588576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f506172656e74322063616e6e6f7420627265656400000000000000000000000060448201526064016109ab565b612593836001613b95565b61259e856001613b95565b1415612606576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f47656e646572206469736d61746368000000000000000000000000000000000060448201526064016109ab565b6000612613856000613b95565b90506000612622856000613b95565b9050600081831061263d5761263882600161519f565b612648565b61264883600161519f565b905061266087600261265b600189615208565b613c25565b60008a8152601f602052604090205561268086600261265b600188615208565b6000898152601f6020526040812091909155600b5481906126a190846136fb565b915091506126b133600b546136dd565b66470de4df820000600e60008282546126ca919061519f565b9091555050600b80549060006126df8361529f565b909155503390506000805b600a811015612755578273ffffffffffffffffffffffffffffffffffffffff16601282600a811061271d5761271d615379565b015473ffffffffffffffffffffffffffffffffffffffff16141561274357809150612755565b8061274d8161529f565b9150506126ea565b50805b60098110156127ff57601261276e82600161519f565b600a811061277e5761277e615379565b015473ffffffffffffffffffffffffffffffffffffffff16601282600a81106127a9576127a9615379565b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055806127f78161529f565b915050612758565b50601b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff841617905542600c55600060026128528583613d29565b61285c91906152d8565b61295857600f5480156129565760005b8181101561295457600061289c600f838154811061288c5761288c615379565b9060005260206000200154611132565b90508573ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156129415760405173ffffffffffffffffffffffffffffffffffffffff87169060009066470de4df8200009082818181858883f19350505050158015612917573d6000803e3d6000fd5b5066470de4df820000600e60008282546129319190615208565b9091555060019450612954915050565b508061294c8161529f565b91505061286c565b505b505b600486111561299757600f80546001810182556000919091527f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac802018690555b6003851480156129a9575047600e5411155b15612c255760006002600e546129bf91906151b7565b905080600e546129cf9190615208565b600e5560405173ffffffffffffffffffffffffffffffffffffffff85169082156108fc029083906000818181858888f19350505050158015612a15573d6000803e3d6000fd5b50612a1e613dc1565b7f2b9afe533c21902e2c4b7857630588289393b4ded0a9bd5ecbcc8bea0f87f93a336001600b54612a4f9190615208565b601f60006001600b54612a629190615208565b8152602080820192909252604090810160002054815173ffffffffffffffffffffffffffffffffffffffff9095168552918401929092529082015260608101839052831515608082015260a00160405180910390a1601c5460005b81811015612b6e578573ffffffffffffffffffffffffffffffffffffffff16601c8281548110612aef57612aef615379565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff161415612b5c578260108281548110612b2b57612b2b615379565b906000526020600020016000828254612b44919061519f565b90915550505050505050505050505050505050505050565b80612b668161529f565b915050612abd565b5050601c805460018082019092557f0e4562a10381dec21b205ed72637e6b1b523bdd0e4d4d50af5cd23dd4500a2110180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff96909616959095179094556010805494850181556000527f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae6729093019290925550505050505050505050505050565b612c2d613dc1565b7f2b9afe533c21902e2c4b7857630588289393b4ded0a9bd5ecbcc8bea0f87f93a336001600b54612c5e9190615208565b601f60006001600b54612c719190615208565b81526020808201929092526040908101600090812054825173ffffffffffffffffffffffffffffffffffffffff9096168652928501939093528301526060820152821515608082015260a00160405180910390a15050505050505050505050505050565b60215460ff16612ce457600080fd5b333b15612d4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f636f6e7472616374206e6f7420616c6c6f77656400000000000000000000000060448201526064016109ab565b600b548115801590612d7657506103786001612d69848461519f565b612d739190615208565b11155b612d7f57600080fd5b336000908152601e602052604090205415801590612dac5750336000908152601e60205260409020548211155b612db557600080fd5b34612dc867013fbe85edc90000846151cb565b1115612e30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f496e636f6e73697374656e74206574682073656e74000000000000000000000060448201526064016109ab565b612e3b600a346151b7565b600e6000828254612e4c919061519f565b909155505060115473ffffffffffffffffffffffffffffffffffffffff166108fc6005612e7a3460046151cb565b612e8491906151b7565b6040518115909202916000818181858888f19350505050158015612eac573d6000803e3d6000fd5b5060005b82811015612ee857612ec63361172c838561519f565b612ed361173e828461519f565b50508080612ee09061529f565b915050612eb0565b5081600b6000828254612efb919061519f565b9091555050336000908152601e60205260408120805484929061176d908490615208565b600a5473ffffffffffffffffffffffffffffffffffffffff163314612fa0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109ab565b602180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b600a5473ffffffffffffffffffffffffffffffffffffffff163314613052576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109ab565b73ffffffffffffffffffffffffffffffffffffffff81166130f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016109ab565b6130fe81613666565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd00000000000000000000000000000000000000000000000000000000148061319457507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b8061086657507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610866565b600081815260046020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416908117909155819061323e82611132565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff16613335576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084016109ab565b600061334083611132565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806133af57508373ffffffffffffffffffffffffffffffffffffffff16613397846108fe565b73ffffffffffffffffffffffffffffffffffffffff16145b806133ec575073ffffffffffffffffffffffffffffffffffffffff80821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b8273ffffffffffffffffffffffffffffffffffffffff1661341482611132565b73ffffffffffffffffffffffffffffffffffffffff16146134b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201527f73206e6f74206f776e000000000000000000000000000000000000000000000060648201526084016109ab565b73ffffffffffffffffffffffffffffffffffffffff8216613559576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016109ab565b613564838383613e2d565b61356f6000826131e4565b73ffffffffffffffffffffffffffffffffffffffff831660009081526003602052604081208054600192906135a5908490615208565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604081208054600192906135e090849061519f565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600a805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6136f7828260405180602001604052806000815250613f33565b5050565b600080600061370a8486613d29565b9050600060018511613735576137216002836152d8565b61372d5750600161376c565b50600261376c565b60056137436103e8846152d8565b10156137515750600361376c565b61375c6002836152d8565b6137685750600161376c565b5060025b600061377a81600088613c25565b905061378881600184613c25565b90506000600383146137bc5760048710156137af576137a8876004615208565b90506137bc565b86600414156137bc575060015b6137c882600283613c25565b6000898152601f602052604090205550909350909150505b9250929050565b6137f28484846133f4565b6137fe84848484613fd6565b611da6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016109ab565b6060816138ca57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156138f457806138de8161529f565b91506138ed9050600a836151b7565b91506138ce565b60008167ffffffffffffffff81111561390f5761390f6153a8565b6040519080825280601f01601f191660200182016040528015613939576020820181803683370190505b5090505b84156133ec5761394e600183615208565b915061395b600a866152d8565b61396690603061519f565b60f81b81838151811061397b5761397b615379565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506139b5600a866151b7565b945061393d565b8051606090806139dc575050604080516020810190915260008152919050565b600060036139eb83600261519f565b6139f591906151b7565b613a009060046151cb565b90506000613a0f82602061519f565b67ffffffffffffffff811115613a2757613a276153a8565b6040519080825280601f01601f191660200182016040528015613a51576020820181803683370190505b5090506000604051806060016040528060408152602001615406604091399050600181016020830160005b86811015613add576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b835260049092019101613a7c565b506003860660018114613af75760028114613b4157613b87565b7f3d3d0000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe830152613b87565b7f3d000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8301525b505050918152949350505050565b600060208210613c01576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f696478206f6f720000000000000000000000000000000000000000000000000060448201526064016109ab565b613c0e6001610100615208565b613c198360086151cb565b84901c16905092915050565b600060208310613c91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f696478206f6f720000000000000000000000000000000000000000000000000060448201526064016109ab565b6101008210613cfc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f76616c206f6f720000000000000000000000000000000000000000000000000060448201526064016109ab565b613d076008846151cb565b925081831b83613d1a6001610100615208565b901b1985161790509392505050565b600032613d37600143615208565b60405160609290921b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166020830152406034820152426054820152607481018490526094810183905260b401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209392505050565b6101f4610378600b54613dd49190615208565b613dde91906152d8565b600114156113ca57600e54613dfb90670de0b6b3a764000061519f565b471115613e2757670de0b6b3a7640000600e6000828254613e1c919061519f565b909155506113ca9050565b47600e55565b73ffffffffffffffffffffffffffffffffffffffff8316613e9557613e9081600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b613ed2565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614613ed257613ed283826141d5565b73ffffffffffffffffffffffffffffffffffffffff8216613ef657610b658161428c565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614610b6557610b65828261433b565b613f3d838361438c565b613f4a6000848484613fd6565b610b65576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016109ab565b600073ffffffffffffffffffffffffffffffffffffffff84163b156141ca576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063150b7a029061404d903390899088908890600401614fe7565b602060405180830381600087803b15801561406757600080fd5b505af19250505080156140b5575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526140b291810190614a04565b60015b61417f573d8080156140e3576040519150601f19603f3d011682016040523d82523d6000602084013e6140e8565b606091505b508051614177576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016109ab565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a02000000000000000000000000000000000000000000000000000000001490506133ec565b506001949350505050565b600060016141e284611271565b6141ec9190615208565b60008381526007602052604090205490915080821461424c5773ffffffffffffffffffffffffffffffffffffffff841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b50600091825260076020908152604080842084905573ffffffffffffffffffffffffffffffffffffffff9094168352600681528383209183525290812055565b60085460009061429e90600190615208565b600083815260096020526040812054600880549394509092849081106142c6576142c6615379565b9060005260206000200154905080600883815481106142e7576142e7615379565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061431f5761431f61534a565b6001900381819060005260206000200160009055905550505050565b600061434683611271565b73ffffffffffffffffffffffffffffffffffffffff9093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b73ffffffffffffffffffffffffffffffffffffffff8216614409576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016109ab565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1615614495576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016109ab565b6144a160008383613e2d565b73ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604081208054600192906144d790849061519f565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b8280546145669061524b565b90600052602060002090601f01602090048101928261458857600085556145ec565b82601f106145bf578280017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008235161785556145ec565b828001600101855582156145ec579182015b828111156145ec5782358255916020019190600101906145d1565b506145f892915061461b565b5090565b604051806101400160405280600a906020820280368337509192915050565b5b808211156145f8576000815560010161461c565b803573ffffffffffffffffffffffffffffffffffffffff8116811461465457600080fd5b919050565b60008083601f84011261466b57600080fd5b50813567ffffffffffffffff81111561468357600080fd5b6020830191508360208260051b85010111156137e057600080fd5b8035801515811461465457600080fd5b6000602082840312156146c057600080fd5b6146c982614630565b9392505050565b600080604083850312156146e357600080fd5b6146ec83614630565b91506146fa60208401614630565b90509250929050565b60008060006060848603121561471857600080fd5b61472184614630565b925061472f60208501614630565b9150604084013590509250925092565b6000806000806080858703121561475557600080fd5b61475e85614630565b9350602061476d818701614630565b935060408601359250606086013567ffffffffffffffff8082111561479157600080fd5b818801915088601f8301126147a557600080fd5b8135818111156147b7576147b76153a8565b6147e7847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601615150565b915080825289848285010111156147fd57600080fd5b808484018584013760008482840101525080935050505092959194509250565b6000806040838503121561483057600080fd5b61483983614630565b91506146fa6020840161469e565b6000806040838503121561485a57600080fd5b61486383614630565b946020939093013593505050565b6000806020838503121561488457600080fd5b823567ffffffffffffffff81111561489b57600080fd5b6148a785828601614659565b90969095509350505050565b600080600080604085870312156148c957600080fd5b843567ffffffffffffffff808211156148e157600080fd5b6148ed88838901614659565b9096509450602087013591508082111561490657600080fd5b5061491387828801614659565b95989497509550505050565b6000602080838503121561493257600080fd5b823567ffffffffffffffff8082111561494a57600080fd5b818501915085601f83011261495e57600080fd5b813581811115614970576149706153a8565b8060051b9150614981848301615150565b8181528481019084860184860187018a101561499c57600080fd5b600095505b838610156149bf5780358352600195909501949186019186016149a1565b5098975050505050505050565b6000602082840312156149de57600080fd5b6146c98261469e565b6000602082840312156149f957600080fd5b81356146c9816153d7565b600060208284031215614a1657600080fd5b81516146c9816153d7565b60008060208385031215614a3457600080fd5b823567ffffffffffffffff80821115614a4c57600080fd5b818501915085601f830112614a6057600080fd5b813581811115614a6f57600080fd5b866020828501011115614a8157600080fd5b60209290920196919550909350505050565b600060208284031215614aa557600080fd5b5035919050565b60008060408385031215614abf57600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b83811015614afe57815187529582019590820190600101614ae2565b509495945050505050565b60008151808452614b2181602086016020860161521f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60008151614b6581856020860161521f565b9290920192915050565b8054600090600181811c9080831680614b8957607f831692505b6020808410821415614bc4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b818015614bd85760018114614c0757614c34565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00861689528489019650614c34565b60008881526020902060005b86811015614c2c5781548b820152908501908301614c13565b505084890196505b50505050505092915050565b60008351614c5281846020880161521f565b7f2f000000000000000000000000000000000000000000000000000000000000009083019081528351614c8c81600184016020880161521f565b01600101949350505050565b7f2261747472696275746573223a205b7b2274726169745f74797065223a22476581527f6e646572222c2276616c7565223a202200000000000000000000000000000000602082015260008551614cf6816030850160208a0161521f565b7f227d2c207b2274726169745f74797065223a22427265656461626c65222c22766030918401918201527f616c7565223a202200000000000000000000000000000000000000000000000060508201528551614d59816058840160208a0161521f565b8082019150507f227d2c207b2274726169745f74797065223a224272656564436f756e74222c2260588201527f76616c7565223a202200000000000000000000000000000000000000000000008060788301528551614dbf816081850160208a0161521f565b7f227d2c207b2274726169745f74797065223a2247656e65726174696f6e222c226081939091019283015260a1820152614e28614dff60aa830186614b53565b7f227d5d0000000000000000000000000000000000000000000000000000000000815260030190565b979650505050505050565b7f7b226e616d65223a2022000000000000000000000000000000000000000000008152600088516020614e6c82600a8601838e0161521f565b895191840191614e8281600a8501848e0161521f565b8951920191614e9781600a8501848d0161521f565b614ea6600a828501018a614b6f565b9250508651614eb88184848b0161521f565b8651920191614eca8184848a0161521f565b8551920191614edc818484890161521f565b7f7d000000000000000000000000000000000000000000000000000000000000009201918252506001019998505050505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000815260008251614f4b81601d85016020870161521f565b91909101601d0192915050565b7f7b226e616d65223a2022427574746572466c7920230000000000000000000000815260008451614f9081601585016020890161521f565b845190830190614fa781601584016020890161521f565b614fb660158284010186614b6f565b7f227d0000000000000000000000000000000000000000000000000000000000008152600201979650505050505050565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526150266080830184614b09565b9695505050505050565b61018080825284519082018190526000906101a0830190602090818801845b8281101561508157815173ffffffffffffffffffffffffffffffffffffffff168552938301939083019060010161504f565b505050838203818501526150958287614ace565b92506040840191508460005b600a8110156150d457815173ffffffffffffffffffffffffffffffffffffffff16845292820192908201906001016150a1565b50505050949350505050565b6020815260006146c96020830184614ace565b6020808252825182820181905260009190848201906040850190845b8181101561513157835163ffffffff168352928401929184019160010161510f565b50909695505050505050565b6020815260006146c96020830184614b09565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715615197576151976153a8565b604052919050565b600082198211156151b2576151b26152ec565b500190565b6000826151c6576151c661531b565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615203576152036152ec565b500290565b60008282101561521a5761521a6152ec565b500390565b60005b8381101561523a578181015183820152602001615222565b83811115611da65750506000910152565b600181811c9082168061525f57607f821691505b60208210811415615299577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156152d1576152d16152ec565b5060010190565b6000826152e7576152e761531b565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7fffffffff00000000000000000000000000000000000000000000000000000000811681146130fe57600080fdfe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f222c20226465736372697074696f6e223a20225073796368652e41727420697320616e20616c676f726974686d2061727420636f6c6c656374696f6e206f6620383838204f47206f6e2d636861696e20627574746572666c6965732e20416c6c20746865206d65746164617461206172652073746f726564206f6e2074686520736d61727420636f6e747261637420616e6420696d61676573206172652073746f726564206f6e20495046532e222c22696d616765223a2022a2646970667358221220c0dd4d44c0d5255a8f1544c161c77b546f7772824c971070567e5b8e673e4f6464736f6c63430008070033

Deployed Bytecode

0x6080604052600436106102c65760003560e01c8063715018a611610179578063a22cb465116100d6578063d9ecad7b1161008a578063eca73f6411610064578063eca73f64146107ba578063f1088700146107d0578063f2fde38b146107f057600080fd5b8063d9ecad7b1461073e578063e985e9c514610751578063eaa5bea0146107a757600080fd5b8063b88d4fde116100bb578063b88d4fde146106da578063c87b56dd146106fa578063d69d0d001461071a57600080fd5b8063a22cb4651461069a578063a51312c8146106ba57600080fd5b80638588b2c51161012d5780638e2ffd63116101125780638e2ffd631461062d57806395d89b41146106705780639a35646f1461068557600080fd5b80638588b2c5146105ef5780638da5cb5b1461060257600080fd5b806375794a3c1161015e57806375794a3c146105945780637fd705ba146105aa578063824553cc146105c257600080fd5b8063715018a61461056a57806373630c651461057f57600080fd5b80633bd64968116102275780635c474f9e116101db5780636352211e116101c05780636352211e1461050a5780636cfa24cc1461052a57806370a082311461054a57600080fd5b80635c474f9e146104c85780635de6dc55146104dd57600080fd5b806342842e0e1161020c57806342842e0e146104695780634f6ccce71461048957806351830227146104a957600080fd5b80633bd649681461043e578063416e39e71461045357600080fd5b806318160ddd1161027e578063218f197e11610263578063218f197e146103de57806323b872dd146103fe5780632f745c591461041e57600080fd5b806318160ddd146103a95780631bdc608e146103c857600080fd5b8063081812fc116102af578063081812fc14610322578063095ea7b314610367578063150c5c261461038957600080fd5b806301ffc9a7146102cb57806306fdde0314610300575b600080fd5b3480156102d757600080fd5b506102eb6102e63660046149e7565b610810565b60405190151581526020015b60405180910390f35b34801561030c57600080fd5b5061031561086c565b6040516102f7919061513d565b34801561032e57600080fd5b5061034261033d366004614a93565b6108fe565b60405173ffffffffffffffffffffffffffffffffffffffff90911681526020016102f7565b34801561037357600080fd5b50610387610382366004614847565b6109dd565b005b34801561039557600080fd5b506103876103a4366004614a93565b610b6a565b3480156103b557600080fd5b506008545b6040519081526020016102f7565b3480156103d457600080fd5b506103ba600d5481565b3480156103ea57600080fd5b506103876103f93660046148b3565b610bf0565b34801561040a57600080fd5b50610387610419366004614703565b610d7e565b34801561042a57600080fd5b506103ba610439366004614847565b610e1f565b34801561044a57600080fd5b50610387610eee565b34801561045f57600080fd5b506103ba600c5481565b34801561047557600080fd5b50610387610484366004614703565b610f9d565b34801561049557600080fd5b506103ba6104a4366004614a93565b610fb8565b3480156104b557600080fd5b506021546102eb90610100900460ff1681565b3480156104d457600080fd5b506102eb611076565b3480156104e957600080fd5b506104fd6104f83660046146ae565b611090565b6040516102f791906150e0565b34801561051657600080fd5b50610342610525366004614a93565b611132565b34801561053657600080fd5b50610387610545366004614a21565b6111e4565b34801561055657600080fd5b506103ba6105653660046146ae565b611271565b34801561057657600080fd5b5061038761133f565b34801561058b57600080fd5b506103ba6113cc565b3480156105a057600080fd5b506103ba600b5481565b3480156105b657600080fd5b5060215460ff166102eb565b3480156105ce57600080fd5b506105e26105dd36600461491f565b611416565b6040516102f791906150f3565b6103876105fd366004614a93565b611515565b34801561060e57600080fd5b50600a5473ffffffffffffffffffffffffffffffffffffffff16610342565b34801561063957600080fd5b506103ba6106483660046146ae565b73ffffffffffffffffffffffffffffffffffffffff166000908152601e602052604090205490565b34801561067c57600080fd5b506103156117ea565b34801561069157600080fd5b506103876117f9565b3480156106a657600080fd5b506103876106b536600461481d565b611ab1565b3480156106c657600080fd5b506103876106d5366004614871565b611bc8565b3480156106e657600080fd5b506103876106f536600461473f565b611d04565b34801561070657600080fd5b50610315610715366004614a93565b611dac565b34801561072657600080fd5b5061072f6121dc565b6040516102f793929190615030565b61038761074c366004614aac565b6122fb565b34801561075d57600080fd5b506102eb61076c3660046146d0565b73ffffffffffffffffffffffffffffffffffffffff918216600090815260056020908152604080832093909416825291909152205460ff1690565b6103876107b5366004614a93565b612cd5565b3480156107c657600080fd5b506103ba600e5481565b3480156107dc57600080fd5b506103876107eb3660046149cc565b612f1f565b3480156107fc57600080fd5b5061038761080b3660046146ae565b612fd1565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f780e9d63000000000000000000000000000000000000000000000000000000001480610866575061086682613101565b92915050565b60606000805461087b9061524b565b80601f01602080910402602001604051908101604052809291908181526020018280546108a79061524b565b80156108f45780601f106108c9576101008083540402835291602001916108f4565b820191906000526020600020905b8154815290600101906020018083116108d757829003601f168201915b5050505050905090565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff166109b4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084015b60405180910390fd5b5060009081526004602052604090205473ffffffffffffffffffffffffffffffffffffffff1690565b60006109e882611132565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610aa6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560448201527f720000000000000000000000000000000000000000000000000000000000000060648201526084016109ab565b3373ffffffffffffffffffffffffffffffffffffffff82161480610acf5750610acf813361076c565b610b5b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c000000000000000060648201526084016109ab565b610b6583836131e4565b505050565b600a5473ffffffffffffffffffffffffffffffffffffffff163314610beb576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109ab565b600d55565b600a5473ffffffffffffffffffffffffffffffffffffffff163314610c71576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109ab565b828114610c7d57600080fd5b60005b83811015610d77576000858583818110610c9c57610c9c615379565b9050602002016020810190610cb191906146ae565b73ffffffffffffffffffffffffffffffffffffffff161415610cd257600080fd5b828282818110610ce457610ce4615379565b90506020020135601e6000878785818110610d0157610d01615379565b9050602002016020810190610d1691906146ae565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254610d5f919061519f565b90915550819050610d6f8161529f565b915050610c80565b5050505050565b610d883382613284565b610e14576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016109ab565b610b658383836133f4565b6000610e2a83611271565b8210610eb8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201527f74206f6620626f756e647300000000000000000000000000000000000000000060648201526084016109ab565b5073ffffffffffffffffffffffffffffffffffffffff919091166000908152600660209081526040808320938352929052205490565b600a5473ffffffffffffffffffffffffffffffffffffffff163314610f6f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109ab565b602180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff16610100179055565b610b6583838360405180602001604052806000815250611d04565b6000610fc360085490565b8210611051576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201527f7574206f6620626f756e6473000000000000000000000000000000000000000060648201526084016109ab565b6008828154811061106457611064615379565b90600052602060002001549050919050565b600080600d5411801561108b5750600d544210155b905090565b6060600061109d83611271565b905060008167ffffffffffffffff8111156110ba576110ba6153a8565b6040519080825280602002602001820160405280156110e3578160200160208202803683370190505b50905060005b8281101561112a576110fb8582610e1f565b82828151811061110d5761110d615379565b6020908102919091010152806111228161529f565b9150506110e9565b509392505050565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff1680610866576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201527f656e7420746f6b656e000000000000000000000000000000000000000000000060648201526084016109ab565b600a5473ffffffffffffffffffffffffffffffffffffffff163314611265576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109ab565b610b656020838361455a565b600073ffffffffffffffffffffffffffffffffffffffff8216611316576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a6560448201527f726f20616464726573730000000000000000000000000000000000000000000060648201526084016109ab565b5073ffffffffffffffffffffffffffffffffffffffff1660009081526003602052604090205490565b600a5473ffffffffffffffffffffffffffffffffffffffff1633146113c0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109ab565b6113ca6000613666565b565b602154600090610100900460ff166113e45750600190565b6000600c54118015611405575061a8c0600c54426114029190615208565b10155b156114105750600290565b50600090565b805160609060008167ffffffffffffffff811115611436576114366153a8565b60405190808252806020026020018201604052801561145f578160200160208202803683370190505b5090506000805b8381101561150b5785818151811061148057611480615379565b602002602001015191506114b88260009081526002602052604090205473ffffffffffffffffffffffffffffffffffffffff16151590565b6114c157600080fd5b6000828152601f602052604090205483518490839081106114e4576114e4615379565b63ffffffff90921660209283029190910190910152806115038161529f565b915050611466565b5090949350505050565b6000600d541180156115295750600d544210155b61153257600080fd5b333b1561159b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f636f6e7472616374206e6f7420616c6c6f77656400000000000000000000000060448201526064016109ab565b600b5481158015906115c4575061037860016115b7848461519f565b6115c19190615208565b11155b6115cd57600080fd5b336000908152601d60205260409020546005906115eb90849061519f565b11156115f657600080fd5b3461160967013fbe85edc90000846151cb565b1115611671576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f496e636f6e73697374656e74206574682073656e74000000000000000000000060448201526064016109ab565b336000908152601d60205260408120805484929061169090849061519f565b909155506116a19050600a346151b7565b600e60008282546116b2919061519f565b909155505060115473ffffffffffffffffffffffffffffffffffffffff166108fc60056116e03460046151cb565b6116ea91906151b7565b6040518115909202916000818181858888f19350505050158015611712573d6000803e3d6000fd5b5060005b8281101561175a576117313361172c838561519f565b6136dd565b61174561173e828461519f565b60016136fb565b505080806117529061529f565b915050611716565b5081600b600082825461176d919061519f565b9091555050600b5461037810156117ab57602180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00ff166101001790555b7f94242c431036b9ba6723a138d4b275a5b38e13a95ef66227a45df427c0f843f3600b546040516117de91815260200190565b60405180910390a15050565b60606001805461087b9061524b565b600a5473ffffffffffffffffffffffffffffffffffffffff16331461187a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109ab565b6000600c5411801561189b575061a8c0600c54426118989190615208565b10155b611901576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600e60248201527f7374696c6c206272656564696e6700000000000000000000000000000000000060448201526064016109ab565b6000805b600a811015611960576000601282600a811061192357611923615379565b015473ffffffffffffffffffffffffffffffffffffffff161461194e578161194a8161529f565b9250505b806119588161529f565b915050611905565b5047600e5411156119705747600e555b600081600e5461198091906151b7565b905060005b600a811015611a2d576000601282600a81106119a3576119a3615379565b015473ffffffffffffffffffffffffffffffffffffffff1614611a1b57601281600a81106119d3576119d3615379565b015460405173ffffffffffffffffffffffffffffffffffffffff9091169083156108fc029084906000818181858888f19350505050158015611a19573d6000803e3d6000fd5b505b80611a258161529f565b915050611985565b506000600e554715611a815760115460405173ffffffffffffffffffffffffffffffffffffffff909116904780156108fc02916000818181858888f19350505050158015611a7f573d6000803e3d6000fd5b505b6040518181527f98ada995bbd1dfd160d624e47773dd5df034f32c892209a0802551bd7780441f906020016117de565b73ffffffffffffffffffffffffffffffffffffffff8216331415611b31576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016109ab565b33600081815260056020908152604080832073ffffffffffffffffffffffffffffffffffffffff87168085529083529281902080547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff001686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600a5473ffffffffffffffffffffffffffffffffffffffff163314611c49576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109ab565b60005b81811015610b65576000838383818110611c6857611c68615379565b9050602002016020810190611c7d91906146ae565b73ffffffffffffffffffffffffffffffffffffffff161415611c9e57600080fd5b6000601e6000858585818110611cb657611cb6615379565b9050602002016020810190611ccb91906146ae565b73ffffffffffffffffffffffffffffffffffffffff16815260208101919091526040016000205580611cfc8161529f565b915050611c4c565b611d0e3383613284565b611d9a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60448201527f776e6572206e6f7220617070726f76656400000000000000000000000000000060648201526084016109ab565b611da6848484846137e7565b50505050565b60008181526002602052604090205460609073ffffffffffffffffffffffffffffffffffffffff16611ddd57600080fd5b602154606090610100900460ff16611e4357611e3c611dfb8461388a565b6040518060e0016040528060b9815260200161544660b991396020604051602001611e2893929190614f58565b6040516020818303038152906040526139bc565b9050612193565b6000838152601f602052604081205490611e5e826001613b95565b90506000611e6d836000613b95565b90506000611e7c846002613b95565b90506000611e898861388a565b905060606001851415611ed0575060408051808201909152600681527f46656d616c6500000000000000000000000000000000000000000000000000006020820152611f49565b6002851415611f13575060408051808201909152600481527f4d616c65000000000000000000000000000000000000000000000000000000006020820152611f49565b5060408051808201909152600b81527f416e64726f67796e6f757300000000000000000000000000000000000000000060208201525b600060038614611f7b576004851015611f6e57611f67856004615208565b9050611f7b565b8460041415611f7b575060015b6000611f868561388a565b611f8f8361388a565b604051602001611fa0929190614c40565b604051602081830303815290604052905060008360008711611ff7576040518060400160405280600581526020017f46616c736500000000000000000000000000000000000000000000000000000081525061202e565b6040518060400160405280600481526020017f54727565000000000000000000000000000000000000000000000000000000008152505b836120388a61388a565b60405160200161204b9493929190614c98565b6040516020818303038152906040529050612187600389146120a2576040518060400160405280600b81526020017f427574746572466c7920230000000000000000000000000000000000000000008152506120d9565b6040518060400160405280600781526020017f47686f73742023000000000000000000000000000000000000000000000000008152505b866040518060e0016040528060b9815260200161544660b9913960208960038e14612139576040518060400160405280600881526020017f30302e706e67222c000000000000000000000000000000000000000000000000815250612170565b6040518060400160405280600881526020017f31302e706e67222c0000000000000000000000000000000000000000000000008152505b87604051602001611e289796959493929190614e33565b99505050505050505050505b6000816040516020016121a69190614f13565b604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0818403018152919052949350505050565b6060806121e76145fc565b601c601060128280548060200260200160405190810160405280929190818152602001828054801561224f57602002820191906000526020600020905b815473ffffffffffffffffffffffffffffffffffffffff168152600190910190602001808311612224575b50505050509250818054806020026020016040519081016040528092919081815260200182805480156122a157602002820191906000526020600020905b81548152602001906001019080831161228d575b505060408051610140810191829052949650859350600a9250905082845b815473ffffffffffffffffffffffffffffffffffffffff1681526001909101906020018083116122bf5750505050509050925092509250909192565b6000600d5411801561230f5750600d544210155b61231857600080fd5b602154610100900460ff16612389576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600c60248201527f4e6f742072657665616c6564000000000000000000000000000000000000000060448201526064016109ab565b600c5415806123a6575061a8c0600c54426123a49190615208565b105b6123af57600080fd5b333b156123bb57600080fd5b336123c583611132565b73ffffffffffffffffffffffffffffffffffffffff161480156124055750336123ed82611132565b73ffffffffffffffffffffffffffffffffffffffff16145b61240e57600080fd5b3466470de4df820000111561247f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f496e636f6e73697374656e74206574682073656e74000000000000000000000060448201526064016109ab565b6000828152601f6020526040808220548383529082205490916124a3836002613b95565b90506000811161250f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f506172656e74312063616e6e6f7420627265656400000000000000000000000060448201526064016109ab565b600061251c836002613b95565b905060008111612588576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f506172656e74322063616e6e6f7420627265656400000000000000000000000060448201526064016109ab565b612593836001613b95565b61259e856001613b95565b1415612606576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600f60248201527f47656e646572206469736d61746368000000000000000000000000000000000060448201526064016109ab565b6000612613856000613b95565b90506000612622856000613b95565b9050600081831061263d5761263882600161519f565b612648565b61264883600161519f565b905061266087600261265b600189615208565b613c25565b60008a8152601f602052604090205561268086600261265b600188615208565b6000898152601f6020526040812091909155600b5481906126a190846136fb565b915091506126b133600b546136dd565b66470de4df820000600e60008282546126ca919061519f565b9091555050600b80549060006126df8361529f565b909155503390506000805b600a811015612755578273ffffffffffffffffffffffffffffffffffffffff16601282600a811061271d5761271d615379565b015473ffffffffffffffffffffffffffffffffffffffff16141561274357809150612755565b8061274d8161529f565b9150506126ea565b50805b60098110156127ff57601261276e82600161519f565b600a811061277e5761277e615379565b015473ffffffffffffffffffffffffffffffffffffffff16601282600a81106127a9576127a9615379565b0180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff92909216919091179055806127f78161529f565b915050612758565b50601b80547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff841617905542600c55600060026128528583613d29565b61285c91906152d8565b61295857600f5480156129565760005b8181101561295457600061289c600f838154811061288c5761288c615379565b9060005260206000200154611132565b90508573ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff1614156129415760405173ffffffffffffffffffffffffffffffffffffffff87169060009066470de4df8200009082818181858883f19350505050158015612917573d6000803e3d6000fd5b5066470de4df820000600e60008282546129319190615208565b9091555060019450612954915050565b508061294c8161529f565b91505061286c565b505b505b600486111561299757600f80546001810182556000919091527f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac802018690555b6003851480156129a9575047600e5411155b15612c255760006002600e546129bf91906151b7565b905080600e546129cf9190615208565b600e5560405173ffffffffffffffffffffffffffffffffffffffff85169082156108fc029083906000818181858888f19350505050158015612a15573d6000803e3d6000fd5b50612a1e613dc1565b7f2b9afe533c21902e2c4b7857630588289393b4ded0a9bd5ecbcc8bea0f87f93a336001600b54612a4f9190615208565b601f60006001600b54612a629190615208565b8152602080820192909252604090810160002054815173ffffffffffffffffffffffffffffffffffffffff9095168552918401929092529082015260608101839052831515608082015260a00160405180910390a1601c5460005b81811015612b6e578573ffffffffffffffffffffffffffffffffffffffff16601c8281548110612aef57612aef615379565b60009182526020909120015473ffffffffffffffffffffffffffffffffffffffff161415612b5c578260108281548110612b2b57612b2b615379565b906000526020600020016000828254612b44919061519f565b90915550505050505050505050505050505050505050565b80612b668161529f565b915050612abd565b5050601c805460018082019092557f0e4562a10381dec21b205ed72637e6b1b523bdd0e4d4d50af5cd23dd4500a2110180547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff96909616959095179094556010805494850181556000527f1b6847dc741a1b0cd08d278845f9d819d87b734759afb55fe2de5cb82a9ae6729093019290925550505050505050505050505050565b612c2d613dc1565b7f2b9afe533c21902e2c4b7857630588289393b4ded0a9bd5ecbcc8bea0f87f93a336001600b54612c5e9190615208565b601f60006001600b54612c719190615208565b81526020808201929092526040908101600090812054825173ffffffffffffffffffffffffffffffffffffffff9096168652928501939093528301526060820152821515608082015260a00160405180910390a15050505050505050505050505050565b60215460ff16612ce457600080fd5b333b15612d4d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601460248201527f636f6e7472616374206e6f7420616c6c6f77656400000000000000000000000060448201526064016109ab565b600b548115801590612d7657506103786001612d69848461519f565b612d739190615208565b11155b612d7f57600080fd5b336000908152601e602052604090205415801590612dac5750336000908152601e60205260409020548211155b612db557600080fd5b34612dc867013fbe85edc90000846151cb565b1115612e30576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601560248201527f496e636f6e73697374656e74206574682073656e74000000000000000000000060448201526064016109ab565b612e3b600a346151b7565b600e6000828254612e4c919061519f565b909155505060115473ffffffffffffffffffffffffffffffffffffffff166108fc6005612e7a3460046151cb565b612e8491906151b7565b6040518115909202916000818181858888f19350505050158015612eac573d6000803e3d6000fd5b5060005b82811015612ee857612ec63361172c838561519f565b612ed361173e828461519f565b50508080612ee09061529f565b915050612eb0565b5081600b6000828254612efb919061519f565b9091555050336000908152601e60205260408120805484929061176d908490615208565b600a5473ffffffffffffffffffffffffffffffffffffffff163314612fa0576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109ab565b602180547fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0016911515919091179055565b600a5473ffffffffffffffffffffffffffffffffffffffff163314613052576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016109ab565b73ffffffffffffffffffffffffffffffffffffffff81166130f5576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201527f646472657373000000000000000000000000000000000000000000000000000060648201526084016109ab565b6130fe81613666565b50565b60007fffffffff0000000000000000000000000000000000000000000000000000000082167f80ac58cd00000000000000000000000000000000000000000000000000000000148061319457507fffffffff0000000000000000000000000000000000000000000000000000000082167f5b5e139f00000000000000000000000000000000000000000000000000000000145b8061086657507f01ffc9a7000000000000000000000000000000000000000000000000000000007fffffffff00000000000000000000000000000000000000000000000000000000831614610866565b600081815260046020526040902080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff8416908117909155819061323e82611132565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60008181526002602052604081205473ffffffffffffffffffffffffffffffffffffffff16613335576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201527f697374656e7420746f6b656e000000000000000000000000000000000000000060648201526084016109ab565b600061334083611132565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806133af57508373ffffffffffffffffffffffffffffffffffffffff16613397846108fe565b73ffffffffffffffffffffffffffffffffffffffff16145b806133ec575073ffffffffffffffffffffffffffffffffffffffff80821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b8273ffffffffffffffffffffffffffffffffffffffff1661341482611132565b73ffffffffffffffffffffffffffffffffffffffff16146134b7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201527f73206e6f74206f776e000000000000000000000000000000000000000000000060648201526084016109ab565b73ffffffffffffffffffffffffffffffffffffffff8216613559576040517f08c379a0000000000000000000000000000000000000000000000000000000008152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f2061646460448201527f726573730000000000000000000000000000000000000000000000000000000060648201526084016109ab565b613564838383613e2d565b61356f6000826131e4565b73ffffffffffffffffffffffffffffffffffffffff831660009081526003602052604081208054600192906135a5908490615208565b909155505073ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604081208054600192906135e090849061519f565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff86811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600a805473ffffffffffffffffffffffffffffffffffffffff8381167fffffffffffffffffffffffff0000000000000000000000000000000000000000831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6136f7828260405180602001604052806000815250613f33565b5050565b600080600061370a8486613d29565b9050600060018511613735576137216002836152d8565b61372d5750600161376c565b50600261376c565b60056137436103e8846152d8565b10156137515750600361376c565b61375c6002836152d8565b6137685750600161376c565b5060025b600061377a81600088613c25565b905061378881600184613c25565b90506000600383146137bc5760048710156137af576137a8876004615208565b90506137bc565b86600414156137bc575060015b6137c882600283613c25565b6000898152601f602052604090205550909350909150505b9250929050565b6137f28484846133f4565b6137fe84848484613fd6565b611da6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016109ab565b6060816138ca57505060408051808201909152600181527f3000000000000000000000000000000000000000000000000000000000000000602082015290565b8160005b81156138f457806138de8161529f565b91506138ed9050600a836151b7565b91506138ce565b60008167ffffffffffffffff81111561390f5761390f6153a8565b6040519080825280601f01601f191660200182016040528015613939576020820181803683370190505b5090505b84156133ec5761394e600183615208565b915061395b600a866152d8565b61396690603061519f565b60f81b81838151811061397b5761397b615379565b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a9053506139b5600a866151b7565b945061393d565b8051606090806139dc575050604080516020810190915260008152919050565b600060036139eb83600261519f565b6139f591906151b7565b613a009060046151cb565b90506000613a0f82602061519f565b67ffffffffffffffff811115613a2757613a276153a8565b6040519080825280601f01601f191660200182016040528015613a51576020820181803683370190505b5090506000604051806060016040528060408152602001615406604091399050600181016020830160005b86811015613add576003818a01810151603f601282901c8116860151600c83901c8216870151600684901c831688015192909316870151600891821b60ff94851601821b92841692909201901b91160160e01b835260049092019101613a7c565b506003860660018114613af75760028114613b4157613b87565b7f3d3d0000000000000000000000000000000000000000000000000000000000007ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe830152613b87565b7f3d000000000000000000000000000000000000000000000000000000000000007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8301525b505050918152949350505050565b600060208210613c01576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f696478206f6f720000000000000000000000000000000000000000000000000060448201526064016109ab565b613c0e6001610100615208565b613c198360086151cb565b84901c16905092915050565b600060208310613c91576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f696478206f6f720000000000000000000000000000000000000000000000000060448201526064016109ab565b6101008210613cfc576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152600760248201527f76616c206f6f720000000000000000000000000000000000000000000000000060448201526064016109ab565b613d076008846151cb565b925081831b83613d1a6001610100615208565b901b1985161790509392505050565b600032613d37600143615208565b60405160609290921b7fffffffffffffffffffffffffffffffffffffffff000000000000000000000000166020830152406034820152426054820152607481018490526094810183905260b401604080517fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe081840301815291905280516020909101209392505050565b6101f4610378600b54613dd49190615208565b613dde91906152d8565b600114156113ca57600e54613dfb90670de0b6b3a764000061519f565b471115613e2757670de0b6b3a7640000600e6000828254613e1c919061519f565b909155506113ca9050565b47600e55565b73ffffffffffffffffffffffffffffffffffffffff8316613e9557613e9081600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b613ed2565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614613ed257613ed283826141d5565b73ffffffffffffffffffffffffffffffffffffffff8216613ef657610b658161428c565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614610b6557610b65828261433b565b613f3d838361438c565b613f4a6000848484613fd6565b610b65576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016109ab565b600073ffffffffffffffffffffffffffffffffffffffff84163b156141ca576040517f150b7a0200000000000000000000000000000000000000000000000000000000815273ffffffffffffffffffffffffffffffffffffffff85169063150b7a029061404d903390899088908890600401614fe7565b602060405180830381600087803b15801561406757600080fd5b505af19250505080156140b5575060408051601f3d9081017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe01682019092526140b291810190614a04565b60015b61417f573d8080156140e3576040519150601f19603f3d011682016040523d82523d6000602084013e6140e8565b606091505b508051614177576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152603260248201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560448201527f63656976657220696d706c656d656e746572000000000000000000000000000060648201526084016109ab565b805181602001fd5b7fffffffff00000000000000000000000000000000000000000000000000000000167f150b7a02000000000000000000000000000000000000000000000000000000001490506133ec565b506001949350505050565b600060016141e284611271565b6141ec9190615208565b60008381526007602052604090205490915080821461424c5773ffffffffffffffffffffffffffffffffffffffff841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b50600091825260076020908152604080842084905573ffffffffffffffffffffffffffffffffffffffff9094168352600681528383209183525290812055565b60085460009061429e90600190615208565b600083815260096020526040812054600880549394509092849081106142c6576142c6615379565b9060005260206000200154905080600883815481106142e7576142e7615379565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061431f5761431f61534a565b6001900381819060005260206000200160009055905550505050565b600061434683611271565b73ffffffffffffffffffffffffffffffffffffffff9093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b73ffffffffffffffffffffffffffffffffffffffff8216614409576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016109ab565b60008181526002602052604090205473ffffffffffffffffffffffffffffffffffffffff1615614495576040517f08c379a000000000000000000000000000000000000000000000000000000000815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016109ab565b6144a160008383613e2d565b73ffffffffffffffffffffffffffffffffffffffff821660009081526003602052604081208054600192906144d790849061519f565b909155505060008181526002602052604080822080547fffffffffffffffffffffffff00000000000000000000000000000000000000001673ffffffffffffffffffffffffffffffffffffffff861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b8280546145669061524b565b90600052602060002090601f01602090048101928261458857600085556145ec565b82601f106145bf578280017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff008235161785556145ec565b828001600101855582156145ec579182015b828111156145ec5782358255916020019190600101906145d1565b506145f892915061461b565b5090565b604051806101400160405280600a906020820280368337509192915050565b5b808211156145f8576000815560010161461c565b803573ffffffffffffffffffffffffffffffffffffffff8116811461465457600080fd5b919050565b60008083601f84011261466b57600080fd5b50813567ffffffffffffffff81111561468357600080fd5b6020830191508360208260051b85010111156137e057600080fd5b8035801515811461465457600080fd5b6000602082840312156146c057600080fd5b6146c982614630565b9392505050565b600080604083850312156146e357600080fd5b6146ec83614630565b91506146fa60208401614630565b90509250929050565b60008060006060848603121561471857600080fd5b61472184614630565b925061472f60208501614630565b9150604084013590509250925092565b6000806000806080858703121561475557600080fd5b61475e85614630565b9350602061476d818701614630565b935060408601359250606086013567ffffffffffffffff8082111561479157600080fd5b818801915088601f8301126147a557600080fd5b8135818111156147b7576147b76153a8565b6147e7847fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0601f84011601615150565b915080825289848285010111156147fd57600080fd5b808484018584013760008482840101525080935050505092959194509250565b6000806040838503121561483057600080fd5b61483983614630565b91506146fa6020840161469e565b6000806040838503121561485a57600080fd5b61486383614630565b946020939093013593505050565b6000806020838503121561488457600080fd5b823567ffffffffffffffff81111561489b57600080fd5b6148a785828601614659565b90969095509350505050565b600080600080604085870312156148c957600080fd5b843567ffffffffffffffff808211156148e157600080fd5b6148ed88838901614659565b9096509450602087013591508082111561490657600080fd5b5061491387828801614659565b95989497509550505050565b6000602080838503121561493257600080fd5b823567ffffffffffffffff8082111561494a57600080fd5b818501915085601f83011261495e57600080fd5b813581811115614970576149706153a8565b8060051b9150614981848301615150565b8181528481019084860184860187018a101561499c57600080fd5b600095505b838610156149bf5780358352600195909501949186019186016149a1565b5098975050505050505050565b6000602082840312156149de57600080fd5b6146c98261469e565b6000602082840312156149f957600080fd5b81356146c9816153d7565b600060208284031215614a1657600080fd5b81516146c9816153d7565b60008060208385031215614a3457600080fd5b823567ffffffffffffffff80821115614a4c57600080fd5b818501915085601f830112614a6057600080fd5b813581811115614a6f57600080fd5b866020828501011115614a8157600080fd5b60209290920196919550909350505050565b600060208284031215614aa557600080fd5b5035919050565b60008060408385031215614abf57600080fd5b50508035926020909101359150565b600081518084526020808501945080840160005b83811015614afe57815187529582019590820190600101614ae2565b509495945050505050565b60008151808452614b2181602086016020860161521f565b601f017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe0169290920160200192915050565b60008151614b6581856020860161521f565b9290920192915050565b8054600090600181811c9080831680614b8957607f831692505b6020808410821415614bc4577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b818015614bd85760018114614c0757614c34565b7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff00861689528489019650614c34565b60008881526020902060005b86811015614c2c5781548b820152908501908301614c13565b505084890196505b50505050505092915050565b60008351614c5281846020880161521f565b7f2f000000000000000000000000000000000000000000000000000000000000009083019081528351614c8c81600184016020880161521f565b01600101949350505050565b7f2261747472696275746573223a205b7b2274726169745f74797065223a22476581527f6e646572222c2276616c7565223a202200000000000000000000000000000000602082015260008551614cf6816030850160208a0161521f565b7f227d2c207b2274726169745f74797065223a22427265656461626c65222c22766030918401918201527f616c7565223a202200000000000000000000000000000000000000000000000060508201528551614d59816058840160208a0161521f565b8082019150507f227d2c207b2274726169745f74797065223a224272656564436f756e74222c2260588201527f76616c7565223a202200000000000000000000000000000000000000000000008060788301528551614dbf816081850160208a0161521f565b7f227d2c207b2274726169745f74797065223a2247656e65726174696f6e222c226081939091019283015260a1820152614e28614dff60aa830186614b53565b7f227d5d0000000000000000000000000000000000000000000000000000000000815260030190565b979650505050505050565b7f7b226e616d65223a2022000000000000000000000000000000000000000000008152600088516020614e6c82600a8601838e0161521f565b895191840191614e8281600a8501848e0161521f565b8951920191614e9781600a8501848d0161521f565b614ea6600a828501018a614b6f565b9250508651614eb88184848b0161521f565b8651920191614eca8184848a0161521f565b8551920191614edc818484890161521f565b7f7d000000000000000000000000000000000000000000000000000000000000009201918252506001019998505050505050505050565b7f646174613a6170706c69636174696f6e2f6a736f6e3b6261736536342c000000815260008251614f4b81601d85016020870161521f565b91909101601d0192915050565b7f7b226e616d65223a2022427574746572466c7920230000000000000000000000815260008451614f9081601585016020890161521f565b845190830190614fa781601584016020890161521f565b614fb660158284010186614b6f565b7f227d0000000000000000000000000000000000000000000000000000000000008152600201979650505050505050565b600073ffffffffffffffffffffffffffffffffffffffff8087168352808616602084015250836040830152608060608301526150266080830184614b09565b9695505050505050565b61018080825284519082018190526000906101a0830190602090818801845b8281101561508157815173ffffffffffffffffffffffffffffffffffffffff168552938301939083019060010161504f565b505050838203818501526150958287614ace565b92506040840191508460005b600a8110156150d457815173ffffffffffffffffffffffffffffffffffffffff16845292820192908201906001016150a1565b50505050949350505050565b6020815260006146c96020830184614ace565b6020808252825182820181905260009190848201906040850190845b8181101561513157835163ffffffff168352928401929184019160010161510f565b50909695505050505050565b6020815260006146c96020830184614b09565b604051601f82017fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffe016810167ffffffffffffffff81118282101715615197576151976153a8565b604052919050565b600082198211156151b2576151b26152ec565b500190565b6000826151c6576151c661531b565b500490565b6000817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff0483118215151615615203576152036152ec565b500290565b60008282101561521a5761521a6152ec565b500390565b60005b8381101561523a578181015183820152602001615222565b83811115611da65750506000910152565b600181811c9082168061525f57607f821691505b60208210811415615299577f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b50919050565b60007fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156152d1576152d16152ec565b5060010190565b6000826152e7576152e761531b565b500690565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b7fffffffff00000000000000000000000000000000000000000000000000000000811681146130fe57600080fdfe4142434445464748494a4b4c4d4e4f505152535455565758595a6162636465666768696a6b6c6d6e6f707172737475767778797a303132333435363738392b2f222c20226465736372697074696f6e223a20225073796368652e41727420697320616e20616c676f726974686d2061727420636f6c6c656374696f6e206f6620383838204f47206f6e2d636861696e20627574746572666c6965732e20416c6c20746865206d65746164617461206172652073746f726564206f6e2074686520736d61727420636f6e747261637420616e6420696d61676573206172652073746f726564206f6e20495046532e222c22696d616765223a2022a2646970667358221220c0dd4d44c0d5255a8f1544c161c77b546f7772824c971070567e5b8e673e4f6464736f6c63430008070033

Deployed Bytecode Sourcemap

43277:16881:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;37002:224;;;;;;;;;;-1:-1:-1;37002:224:0;;;;;:::i;:::-;;:::i;:::-;;;19765:14:1;;19758:22;19740:41;;19728:2;19713:18;37002:224:0;;;;;;;;24894:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;26453:221::-;;;;;;;;;;-1:-1:-1;26453:221:0;;;;;:::i;:::-;;:::i;:::-;;;15732:42:1;15720:55;;;15702:74;;15690:2;15675:18;26453:221:0;15556:226:1;25976:411:0;;;;;;;;;;-1:-1:-1;25976:411:0;;;;;:::i;:::-;;:::i;:::-;;54930:107;;;;;;;;;;-1:-1:-1;54930:107:0;;;;;:::i;:::-;;:::i;37642:113::-;;;;;;;;;;-1:-1:-1;37730:10:0;:17;37642:113;;;30048:25:1;;;30036:2;30021:18;37642:113:0;29902:177:1;44262:25:0;;;;;;;;;;;;;;;;45643:334;;;;;;;;;;-1:-1:-1;45643:334:0;;;;;:::i;:::-;;:::i;27343:339::-;;;;;;;;;;-1:-1:-1;27343:339:0;;;;;:::i;:::-;;:::i;37310:256::-;;;;;;;;;;-1:-1:-1;37310:256:0;;;;;:::i;:::-;;:::i;55177:76::-;;;;;;;;;;;;;:::i;44107:28::-;;;;;;;;;;;;;;;;27753:185;;;;;;;;;;-1:-1:-1;27753:185:0;;;;;:::i;:::-;;:::i;37832:233::-;;;;;;;;;;-1:-1:-1;37832:233:0;;;;;:::i;:::-;;:::i;45144:20::-;;;;;;;;;;-1:-1:-1;45144:20:0;;;;;;;;;;;55045:124;;;;;;;;;;;;;:::i;54401:325::-;;;;;;;;;;-1:-1:-1;54401:325:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;24588:239::-;;;;;;;;;;-1:-1:-1;24588:239:0;;;;;:::i;:::-;;:::i;55541:115::-;;;;;;;;;;-1:-1:-1;55541:115:0;;;;;:::i;:::-;;:::i;24318:208::-;;;;;;;;;;-1:-1:-1;24318:208:0;;;;;:::i;:::-;;:::i;4593:94::-;;;;;;;;;;;;;:::i;55261:268::-;;;;;;;;;;;;;:::i;44051:30::-;;;;;;;;;;;;;;;;45538:97;;;;;;;;;;-1:-1:-1;45610:17:0;;;;45538:97;;59510:411;;;;;;;;;;-1:-1:-1;59510:411:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;47407:1064::-;;;;;;:::i;:::-;;:::i;3942:87::-;;;;;;;;;;-1:-1:-1;4015:6:0;;;;3942:87;;45985:115;;;;;;;;;;-1:-1:-1;45985:115:0;;;;;:::i;:::-;46076:16;;46049:7;46076:16;;;:10;:16;;;;;;;45985:115;25063:104;;;;;;;;;;;;;:::i;53351:1039::-;;;;;;;;;;;;;:::i;26746:295::-;;;;;;;;;;-1:-1:-1;26746:295:0;;;;;:::i;:::-;;:::i;46108:248::-;;;;;;;;;;-1:-1:-1;46108:248:0;;;;;:::i;:::-;;:::i;28009:328::-;;;;;;;;;;-1:-1:-1;28009:328:0;;;;;:::i;:::-;;:::i;55668:2221::-;;;;;;;;;;-1:-1:-1;55668:2221:0;;;;;:::i;:::-;;:::i;54734:184::-;;;;;;;;;;;;;:::i;:::-;;;;;;;;;:::i;48483:4422::-;;;;;;:::i;:::-;;:::i;27112:164::-;;;;;;;;;;-1:-1:-1;27112:164:0;;;;;:::i;:::-;27233:25;;;;27209:4;27233:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;27112:164;46364:1035;;;;;;:::i;:::-;;:::i;44326:27::-;;;;;;;;;;;;;;;;45419:111;;;;;;;;;;-1:-1:-1;45419:111:0;;;;;:::i;:::-;;:::i;4842:192::-;;;;;;;;;;-1:-1:-1;4842:192:0;;;;;:::i;:::-;;:::i;37002:224::-;37104:4;37128:50;;;37143:35;37128:50;;:90;;;37182:36;37206:11;37182:23;:36::i;:::-;37121:97;37002:224;-1:-1:-1;;37002:224:0:o;24894:100::-;24948:13;24981:5;24974:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;24894:100;:::o;26453:221::-;26529:7;29936:16;;;:7;:16;;;;;;:30;:16;26549:73;;;;;;;25961:2:1;26549:73:0;;;25943:21:1;26000:2;25980:18;;;25973:30;26039:34;26019:18;;;26012:62;26110:14;26090:18;;;26083:42;26142:19;;26549:73:0;;;;;;;;;-1:-1:-1;26642:24:0;;;;:15;:24;;;;;;;;;26453:221::o;25976:411::-;26057:13;26073:23;26088:7;26073:14;:23::i;:::-;26057:39;;26121:5;26115:11;;:2;:11;;;;26107:57;;;;;;;28193:2:1;26107:57:0;;;28175:21:1;28232:2;28212:18;;;28205:30;28271:34;28251:18;;;28244:62;28342:3;28322:18;;;28315:31;28363:19;;26107:57:0;27991:397:1;26107:57:0;2810:10;26199:21;;;;;:62;;-1:-1:-1;26224:37:0;26241:5;2810:10;27112:164;:::i;26224:37::-;26177:168;;;;;;;24354:2:1;26177:168:0;;;24336:21:1;24393:2;24373:18;;;24366:30;24432:34;24412:18;;;24405:62;24503:26;24483:18;;;24476:54;24547:19;;26177:168:0;24152:420:1;26177:168:0;26358:21;26367:2;26371:7;26358:8;:21::i;:::-;26046:341;25976:411;;:::o;54930:107::-;4015:6;;4162:23;4015:6;2810:10;4162:23;4154:68;;;;;;;26374:2:1;4154:68:0;;;26356:21:1;;;26393:18;;;26386:30;26452:34;26432:18;;;26425:62;26504:18;;4154:68:0;26172:356:1;4154:68:0;55005:10:::1;:24:::0;54930:107::o;45643:334::-;4015:6;;4162:23;4015:6;2810:10;4162:23;4154:68;;;;;;;26374:2:1;4154:68:0;;;26356:21:1;;;26393:18;;;26386:30;26452:34;26432:18;;;26425:62;26504:18;;4154:68:0;26172:356:1;4154:68:0;45762:33;;::::1;45754:42;;;::::0;::::1;;45814:9;45809:161;45829:20:::0;;::::1;45809:161;;;45903:1;45879:9:::0;;45889:1;45879:12;;::::1;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;:26;;;;45871:35;;;::::0;::::1;;45949:6;;45956:1;45949:9;;;;;;;:::i;:::-;;;;;;;45921:10;:24;45932:9;;45942:1;45932:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;45921:24;;;;;;;;;;;;;;;;:37;;;;;;;:::i;:::-;::::0;;;-1:-1:-1;45851:3:0;;-1:-1:-1;45851:3:0::1;::::0;::::1;:::i;:::-;;;;45809:161;;;;45643:334:::0;;;;:::o;27343:339::-;27538:41;2810:10;27571:7;27538:18;:41::i;:::-;27530:103;;;;;;;28595:2:1;27530:103:0;;;28577:21:1;28634:2;28614:18;;;28607:30;28673:34;28653:18;;;28646:62;28744:19;28724:18;;;28717:47;28781:19;;27530:103:0;28393:413:1;27530:103:0;27646:28;27656:4;27662:2;27666:7;27646:9;:28::i;37310:256::-;37407:7;37443:23;37460:5;37443:16;:23::i;:::-;37435:5;:31;37427:87;;;;;;;20553:2:1;37427:87:0;;;20535:21:1;20592:2;20572:18;;;20565:30;20631:34;20611:18;;;20604:62;20702:13;20682:18;;;20675:41;20733:19;;37427:87:0;20351:407:1;37427:87:0;-1:-1:-1;37532:19:0;;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;37310:256::o;55177:76::-;4015:6;;4162:23;4015:6;2810:10;4162:23;4154:68;;;;;;;26374:2:1;4154:68:0;;;26356:21:1;;;26393:18;;;26386:30;26452:34;26432:18;;;26425:62;26504:18;;4154:68:0;26172:356:1;4154:68:0;55230:8:::1;:15:::0;;;::::1;;;::::0;;55177:76::o;27753:185::-;27891:39;27908:4;27914:2;27918:7;27891:39;;;;;;;;;;;;:16;:39::i;37832:233::-;37907:7;37943:30;37730:10;:17;;37642:113;37943:30;37935:5;:38;37927:95;;;;;;;29013:2:1;37927:95:0;;;28995:21:1;29052:2;29032:18;;;29025:30;29091:34;29071:18;;;29064:62;29162:14;29142:18;;;29135:42;29194:19;;37927:95:0;28811:408:1;37927:95:0;38040:10;38051:5;38040:17;;;;;;;;:::i;:::-;;;;;;;;;38033:24;;37832:233;;;:::o;55045:124::-;55090:4;55127:1;55114:10;;:14;:47;;;;;55151:10;;55132:15;:29;;55114:47;55107:54;;55045:124;:::o;54401:325::-;54464:16;54493:14;54510:15;54520:4;54510:9;:15::i;:::-;54493:32;;54536:23;54576:6;54562:21;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;54562:21:0;;54536:47;;54599:9;54594:101;54614:6;54610:1;:10;54594:101;;;54655:28;54675:4;54681:1;54655:19;:28::i;:::-;54643:6;54650:1;54643:9;;;;;;;;:::i;:::-;;;;;;;;;;:40;54622:4;;;;:::i;:::-;;;;54594:101;;;-1:-1:-1;54712:6:0;54401:325;-1:-1:-1;;;54401:325:0:o;24588:239::-;24660:7;24696:16;;;:7;:16;;;;;;;;24731:19;24723:73;;;;;;;25190:2:1;24723:73:0;;;25172:21:1;25229:2;25209:18;;;25202:30;25268:34;25248:18;;;25241:62;25339:11;25319:18;;;25312:39;25368:19;;24723:73:0;24988:405:1;55541:115:0;4015:6;;4162:23;4015:6;2810:10;4162:23;4154:68;;;;;;;26374:2:1;4154:68:0;;;26356:21:1;;;26393:18;;;26386:30;26452:34;26432:18;;;26425:62;26504:18;;4154:68:0;26172:356:1;4154:68:0;55621:27:::1;:17;55641:7:::0;;55621:27:::1;:::i;24318:208::-:0;24390:7;24418:19;;;24410:74;;;;;;;24779:2:1;24410:74:0;;;24761:21:1;24818:2;24798:18;;;24791:30;24857:34;24837:18;;;24830:62;24928:12;24908:18;;;24901:40;24958:19;;24410:74:0;24577:406:1;24410:74:0;-1:-1:-1;24502:16:0;;;;;;:9;:16;;;;;;;24318:208::o;4593:94::-;4015:6;;4162:23;4015:6;2810:10;4162:23;4154:68;;;;;;;26374:2:1;4154:68:0;;;26356:21:1;;;26393:18;;;26386:30;26452:34;26432:18;;;26425:62;26504:18;;4154:68:0;26172:356:1;4154:68:0;4658:21:::1;4676:1;4658:9;:21::i;:::-;4593:94::o:0;55261:268::-;55334:8;;55309:7;;55334:8;;;;;55329:50;;-1:-1:-1;55366:1:0;;55261:268::o;55329:50::-;55409:1;55393:13;;:17;:73;;;;;44222:12;55432:13;;55414:15;:31;;;;:::i;:::-;:52;;55393:73;55389:114;;;-1:-1:-1;55490:1:0;;55261:268::o;55389:114::-;-1:-1:-1;55520:1:0;;55261:268::o;59510:411::-;59628:14;;59584:15;;59612:13;59628:14;59677:19;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;59677:19:0;;59653:43;;59707:10;59733:9;59728:163;59748:5;59744:1;:9;59728:163;;;59780:7;59788:1;59780:10;;;;;;;;:::i;:::-;;;;;;;59775:15;;59813:11;59821:2;29912:4;29936:16;;;:7;:16;;;;;;:30;:16;:30;;;29847:127;59813:11;59805:20;;;;;;59858;;;;:16;:20;;;;;;59840:8;;:5;;59846:1;;59840:8;;;;;;:::i;:::-;:39;;;;:8;;;;;;;;;;;:39;59755:3;;;;:::i;:::-;;;;59728:163;;;-1:-1:-1;59908:5:0;;59510:411;-1:-1:-1;;;;59510:411:0:o;47407:1064::-;47489:1;47476:10;;:14;:47;;;;;47513:10;;47494:15;:29;;47476:47;47468:56;;;;;;47544:10;6311:20;6359:8;47535:57;;;;;;;27495:2:1;47535:57:0;;;27477:21:1;27534:2;27514:18;;;27507:30;27573:22;27553:18;;;27546:50;27613:18;;47535:57:0;27293:344:1;47535:57:0;47620:11;;47650:12;;;;;:57;;-1:-1:-1;43759:3:0;47686:1;47666:17;47675:8;47666:6;:17;:::i;:::-;:21;;;;:::i;:::-;:41;;47650:57;47642:66;;;;;;47743:10;47727:27;;;;:15;:27;;;;;;43853:1;;47727:38;;47757:8;;47727:38;:::i;:::-;:57;;47719:66;;;;;;47825:9;47804:17;43923:10;47804:8;:17;:::i;:::-;:30;;47796:63;;;;;;;26735:2:1;47796:63:0;;;26717:21:1;26774:2;26754:18;;;26747:30;26813:23;26793:18;;;26786:51;26854:18;;47796:63:0;26533:345:1;47796:63:0;47888:10;47872:27;;;;:15;:27;;;;;:39;;47903:8;;47872:27;:39;;47903:8;;47872:39;:::i;:::-;;;;-1:-1:-1;48071:14:0;;-1:-1:-1;48083:2:0;48071:9;:14;:::i;:::-;48055:12;;:30;;;;;;;:::i;:::-;;;;-1:-1:-1;;48104:10:0;;;;48096:47;48141:1;48125:13;:9;48137:1;48125:13;:::i;:::-;:17;;;;:::i;:::-;48096:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;48161:9;48156:138;48176:8;48172:1;:12;48156:138;;;48206:33;48216:10;48228;48237:1;48228:6;:10;:::i;:::-;48206:9;:33::i;:::-;48254:28;48268:10;48277:1;48268:6;:10;:::i;:::-;48280:1;48254:13;:28::i;:::-;;;48186:3;;;;;:::i;:::-;;;;48156:138;;;;48319:8;48304:11;;:23;;;;;;;:::i;:::-;;;;-1:-1:-1;;48352:11:0;;43759:3;-1:-1:-1;48348:78:0;;;48399:8;:15;;;;;;;;48348:78;48441:22;48451:11;;48441:22;;;;30048:25:1;;30036:2;30021:18;;29902:177;48441:22:0;;;;;;;;47457:1014;47407:1064;:::o;25063:104::-;25119:13;25152:7;25145:14;;;;;:::i;53351:1039::-;4015:6;;4162:23;4015:6;2810:10;4162:23;4154:68;;;;;;;26374:2:1;4154:68:0;;;26356:21:1;;;26393:18;;;26386:30;26452:34;26432:18;;;26425:62;26504:18;;4154:68:0;26172:356:1;4154:68:0;53432:1:::1;53416:13;;:17;:73;;;;;44222:12;53455:13;;53437:15;:31;;;;:::i;:::-;:52;;53416:73;53408:100;;;::::0;::::1;::::0;;29761:2:1;53408:100:0::1;::::0;::::1;29743:21:1::0;29800:2;29780:18;;;29773:30;29839:16;29819:18;;;29812:44;29873:18;;53408:100:0::1;29559:338:1::0;53408:100:0::1;53521:25;::::0;53557:155:::1;53581:2;53577:1;:6;53557:155;;;53642:1;53610:17;53628:1:::0;53610:20:::1;::::0;::::1;;;;;:::i;:::-;;::::0;::::1;;:34;53606:95;;53665:20:::0;::::1;::::0;::::1;:::i;:::-;;;;53606:95;53585:4:::0;::::1;::::0;::::1;:::i;:::-;;;;53557:155;;;;53743:21;53728:12;;:36;53724:105;;;53796:21;53781:12;:36:::0;53724:105:::1;53871:17;53906;53891:12;;:32;;;;:::i;:::-;53871:52;;53939:9;53934:184;53958:2;53954:1;:6;53934:184;;;54019:1;53987:17;54005:1:::0;53987:20:::1;::::0;::::1;;;;;:::i;:::-;;::::0;::::1;;:34;53983:124;;54050:17;54068:1;54050:20;;;;;;;:::i;:::-;;::::0;54042:49:::1;::::0;54050:20:::1;::::0;;::::1;::::0;54042:49;::::1;;;::::0;54081:9;;54050:20:::1;54042:49:::0;54050:20;54042:49;54081:9;54050:20;54042:49;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;53983:124;53962:4:::0;::::1;::::0;::::1;:::i;:::-;;;;53934:184;;;-1:-1:-1::0;54143:1:0::1;54128:12;:16:::0;54208:21:::1;:25:::0;54204:109:::1;;54258:10;::::0;54250:51:::1;::::0;54258:10:::1;::::0;;::::1;::::0;54279:21:::1;54250:51:::0;::::1;;;::::0;54258:10:::1;54250:51:::0;54258:10;54250:51;54279:21;54258:10;54250:51;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;54204:109;54361:21;::::0;30048:25:1;;;54361:21:0::1;::::0;30036:2:1;30021:18;54361:21:0::1;29902:177:1::0;26746:295:0;26849:24;;;2810:10;26849:24;;26841:62;;;;;;;23243:2:1;26841:62:0;;;23225:21:1;23282:2;23262:18;;;23255:30;23321:27;23301:18;;;23294:55;23366:18;;26841:62:0;23041:349:1;26841:62:0;2810:10;26916:32;;;;:18;:32;;;;;;;;;:42;;;;;;;;;;;;:53;;;;;;;;;;;;;26985:48;;19740:41:1;;;26916:42:0;;2810:10;26985:48;;19713:18:1;26985:48:0;;;;;;;26746:295;;:::o;46108:248::-;4015:6;;4162:23;4015:6;2810:10;4162:23;4154:68;;;;;;;26374:2:1;4154:68:0;;;26356:21:1;;;26393:18;;;26386:30;26452:34;26432:18;;;26425:62;26504:18;;4154:68:0;26172:356:1;4154:68:0;46202:9:::1;46197:152;46217:20:::0;;::::1;46197:152;;;46291:1;46267:9:::0;;46277:1;46267:12;;::::1;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;:26;;;;46259:35;;;::::0;::::1;;46336:1;46309:10;:24;46320:9;;46330:1;46320:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;:::i;:::-;46309:24;;::::0;;::::1;::::0;::::1;::::0;;;;;;-1:-1:-1;46309:24:0;:28;46239:3;::::1;::::0;::::1;:::i;:::-;;;;46197:152;;28009:328:::0;28184:41;2810:10;28217:7;28184:18;:41::i;:::-;28176:103;;;;;;;28595:2:1;28176:103:0;;;28577:21:1;28634:2;28614:18;;;28607:30;28673:34;28653:18;;;28646:62;28744:19;28724:18;;;28717:47;28781:19;;28176:103:0;28393:413:1;28176:103:0;28290:39;28304:4;28310:2;28314:7;28323:5;28290:13;:39::i;:::-;28009:328;;;;:::o;55668:2221::-;29912:4;29936:16;;;:7;:16;;;;;;55733:13;;29936:30;:16;55759:25;;;;;;55829:8;;55795:18;;55829:8;;;;;55824:1937;;55861:135;55930:24;55946:7;55930:15;:24::i;:::-;55956:11;;;;;;;;;;;;;;;;;55969:17;55888:105;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;55861:13;:135::i;:::-;55854:142;;55824:1937;;;56029:21;56053:25;;;:16;:25;;;;;;;56107:37;56053:25;43606:1;56107:12;:37::i;:::-;56093:51;;56159:18;56180:37;56193:13;43562:1;56180:12;:37::i;:::-;56159:58;;56232:18;56253:45;56266:13;43658:1;56253:12;:45::i;:::-;56232:66;;56315:23;56341:24;56357:7;56341:15;:24::i;:::-;56315:50;;56380:22;43424:1;56421:3;:17;56417:221;;;-1:-1:-1;56459:19:0;;;;;;;;;;;;;;;;;56417:221;;;43468:1;56504:3;:15;56500:138;;;-1:-1:-1;56540:17:0;;;;;;;;;;;;;;;;;56500:138;;;-1:-1:-1;56598:24:0;;;;;;;;;;;;;;;;;56500:138;56666:21;43512:1;56791:3;:15;56787:235;;56844:1;56831:10;:14;56827:180;;;56886:14;56890:10;56886:1;:14;:::i;:::-;56870:30;;56827:180;;;56930:10;56944:1;56930:15;56926:81;;;-1:-1:-1;56986:1:0;56926:81;57050:24;57101:27;57117:10;57101:15;:27::i;:::-;57135:30;57151:13;57135:15;:30::i;:::-;57084:82;;;;;;;;;:::i;:::-;;;;;;;;;;;;;57050:117;;57182:24;57285:8;57351:1;57338:10;:14;:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57417:10;57473:27;57489:10;57473:15;:27::i;:::-;57216:291;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;57182:326;;57530:219;43512:1;57588:3;:15;:43;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57633:9;57644:11;;;;;;;;;;;;;;;;;57657:17;57676:9;43512:1;57687:3;:15;:41;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57730:10;57557:189;;;;;;;;;;;;;;:::i;57530:219::-;57523:226;;56014:1747;;;;;;;;;55824:1937;57771:20;57851:4;57801:55;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;55668:2221;-1:-1:-1;;;;55668:2221:0:o;54734:184::-;54782:16;54800;54818:18;;:::i;:::-;54857:15;54874:16;54892:17;54849:61;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;54849:61:0;;;;;;;;;;;;-1:-1:-1;54849:61:0;;-1:-1:-1;54849:61:0;;-1:-1:-1;54849:61:0;-1:-1:-1;54849:61:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54734:184;;;:::o;48483:4422::-;48583:1;48570:10;;:14;:47;;;;;48607:10;;48588:15;:29;;48570:47;48562:56;;;;;;48637:8;;;;;;;48629:33;;;;;;;22140:2:1;48629:33:0;;;22122:21:1;22179:2;22159:18;;;22152:30;22218:14;22198:18;;;22191:42;22250:18;;48629:33:0;21938:336:1;48629:33:0;48681:13;;:18;;:73;;;44222:12;48721:13;;48703:15;:31;;;;:::i;:::-;:51;48681:73;48673:82;;;;;;48775:10;6311:20;6359:8;48766:33;;;;;;48847:10;48818:17;48826:8;48818:7;:17::i;:::-;:40;;;:84;;;;-1:-1:-1;48891:10:0;48862:17;48870:8;48862:7;:17::i;:::-;:40;;;48818:84;48810:93;;;;;;48937:9;44006:10;48922:24;;48914:58;;;;;;;26735:2:1;48914:58:0;;;26717:21:1;26774:2;26754:18;;;26747:30;26813:23;26793:18;;;26786:51;26854:18;;48914:58:0;26533:345:1;48914:58:0;48993:19;49015:26;;;:16;:26;;;;;;;49074;;;;;;;49015;;49213:43;49015:26;43658:1;49213:12;:43::i;:::-;49185:71;;49295:1;49275:17;:21;49267:54;;;;;;;27844:2:1;49267:54:0;;;27826:21:1;27883:2;27863:18;;;27856:30;27922:22;27902:18;;;27895:50;27962:18;;49267:54:0;27642:344:1;49267:54:0;49342:25;49370:43;49383:11;43658:1;49370:12;:43::i;:::-;49342:71;;49452:1;49432:17;:21;49424:54;;;;;;;21384:2:1;49424:54:0;;;21366:21:1;21423:2;21403:18;;;21396:30;21462:22;21442:18;;;21435:50;21502:18;;49424:54:0;21182:344:1;49424:54:0;49546:35;49559:11;43606:1;49546:12;:35::i;:::-;49507;49520:11;43606:1;49507:12;:35::i;:::-;:74;;49499:102;;;;;;;23597:2:1;49499:102:0;;;23579:21:1;23636:2;23616:18;;;23609:30;23675:17;23655:18;;;23648:45;23710:18;;49499:102:0;23395:339:1;49499:102:0;49622:18;49643:35;49656:11;43562:1;49643:12;:35::i;:::-;49622:56;;49689:18;49710:35;49723:11;43562:1;49710:12;:35::i;:::-;49689:56;;49820:23;49859:10;49846;:23;:56;;49888:14;:10;49901:1;49888:14;:::i;:::-;49846:56;;;49872:14;:10;49885:1;49872:14;:::i;:::-;49820:82;-1:-1:-1;49944:66:0;49957:11;43658:1;49988:21;50008:1;49988:17;:21;:::i;:::-;49944:12;:66::i;:::-;49915:26;;;;:16;:26;;;;;:95;50050:66;50063:11;43658:1;50094:21;50114:1;50094:17;:21;:::i;50050:66::-;50021:26;;;;:16;:26;;;;;:95;;;;50213:11;;50021:26;;50199:43;;50226:15;50199:13;:43::i;:::-;50169:73;;;;50280:34;50290:10;50302:11;;50280:9;:34::i;:::-;44006:10;50361:12;;:27;;;;;;;:::i;:::-;;;;-1:-1:-1;;50430:11:0;:14;;;:11;:14;;;:::i;:::-;;;;-1:-1:-1;50522:10:0;;-1:-1:-1;50497:14:0;;50566:158;50586:2;50582:1;:6;50566:158;;;50639:6;50615:30;;:17;50633:1;50615:20;;;;;;;:::i;:::-;;;;;:30;50611:102;;;50672:1;50666:7;;50692:5;;50611:102;50590:4;;;;:::i;:::-;;;;50566:158;;;-1:-1:-1;50751:3:0;50734:109;50760:1;50756;:5;50734:109;;;50807:17;50825:5;:1;50829;50825:5;:::i;:::-;50807:24;;;;;;;:::i;:::-;;;;;50784:17;50802:1;50784:20;;;;;;;:::i;:::-;;:47;;;;;;;;;;;;;;;50763:4;;;;:::i;:::-;;;;50734:109;;;-1:-1:-1;50853:20:0;:29;;;;;;;;;;50909:15;50893:13;:31;-1:-1:-1;51054:1:0;51036:15;51043:4;-1:-1:-1;51036:6:0;:15::i;:::-;:19;;;;:::i;:::-;51032:531;;51091:15;:22;51132:7;;51128:424;;51165:9;51160:377;51180:3;51176:1;:7;51160:377;;;51213:14;51230:27;51238:15;51254:1;51238:18;;;;;;;;:::i;:::-;;;;;;;;;51230:7;:27::i;:::-;51213:44;;51294:6;51284:16;;:6;:16;;;51280:238;;;51330:37;;:24;;;;:37;;44006:10;;51330:37;;;;44006:10;51330:24;:37;;;;;;;;;;;;;;;;;;;;;44006:10;51394:12;;:27;;;;;;;:::i;:::-;;;;-1:-1:-1;51458:4:0;;-1:-1:-1;51489:5:0;;-1:-1:-1;;51489:5:0;51280:238;-1:-1:-1;51185:3:0;;;;:::i;:::-;;;;51160:377;;;;51128:424;51062:501;51032:531;51634:1;51616:15;:19;51612:89;;;51652:15;:37;;;;;;;-1:-1:-1;51652:37:0;;;;;;;;;51612:89;43512:1;51801:3;:15;:56;;;;;51836:21;51820:12;;:37;;51801:56;51797:893;;;51874:17;51909:1;51894:12;;:16;;;;:::i;:::-;51874:36;;51955:9;51940:12;;:24;;;;:::i;:::-;51925:12;:39;51993:35;;:24;;;;:35;;;;;52018:9;;51993:35;;;;52018:9;51993:24;:35;;;;;;;;;;;;;;;;;;;;;52106:19;:17;:19::i;:::-;52172:90;52183:10;52207:1;52195:11;;:13;;;;:::i;:::-;52210:16;:31;52239:1;52227:11;;:13;;;;:::i;:::-;52210:31;;;;;;;;;;;;;;-1:-1:-1;52210:31:0;;52172:90;;16594:42:1;16582:55;;;16564:74;;16654:18;;;16647:34;;;;16697:18;;;16690:34;16755:2;16740:18;;16733:34;;;16811:14;;16804:22;16798:3;16783:19;;16776:51;16551:3;16536:19;52172:90:0;;;;;;;52329:15;:22;52315:11;52366:202;52386:3;52382:1;:7;52366:202;;;52442:6;52420:28;;:15;52436:1;52420:18;;;;;;;;:::i;:::-;;;;;;;;;;;;;:28;52416:137;;;52495:9;52472:16;52489:1;52472:19;;;;;;;;:::i;:::-;;;;;;;;;:32;;;;;;;:::i;:::-;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;48483:4422:0:o;52416:137::-;52391:4;;;;:::i;:::-;;;;52366:202;;;-1:-1:-1;;52582:15:0;:28;;;;;;;;;;;;;;;;;;;;;;;;;;;52625:16;:32;;;;;;;-1:-1:-1;52625:32:0;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;48483:4422:0:o;51797:893::-;52757:19;:17;:19::i;:::-;52815:82;52826:10;52850:1;52838:11;;:13;;;;:::i;:::-;52853:16;:31;52882:1;52870:11;;:13;;;;:::i;:::-;52853:31;;;;;;;;;;;;;;-1:-1:-1;52853:31:0;;;;52815:82;;16594:42:1;16582:55;;;16564:74;;16654:18;;;16647:34;;;;16697:18;;16690:34;16755:2;16740:18;;16733:34;16811:14;;16804:22;16798:3;16783:19;;16776:51;16551:3;16536:19;52815:82:0;;;;;;;48551:4354;;;;;;;;;;;;48483:4422;;:::o;46364:1035::-;46442:17;;;;46434:26;;;;;;46480:10;6311:20;6359:8;46471:57;;;;;;;27495:2:1;46471:57:0;;;27477:21:1;27534:2;27514:18;;;27507:30;27573:22;27553:18;;;27546:50;27613:18;;46471:57:0;27293:344:1;46471:57:0;46556:11;;46586:12;;;;;:57;;-1:-1:-1;43759:3:0;46622:1;46602:17;46611:8;46602:6;:17;:::i;:::-;:21;;;;:::i;:::-;:41;;46586:57;46578:66;;;;;;46674:10;46688:1;46663:22;;;:10;:22;;;;;;:26;;;;:64;;-1:-1:-1;46716:10:0;46705:22;;;;:10;:22;;;;;;46693:34;;;46663:64;46655:73;;;;;;46768:9;46747:17;43923:10;46747:8;:17;:::i;:::-;:30;;46739:63;;;;;;;26735:2:1;46739:63:0;;;26717:21:1;26774:2;26754:18;;;26747:30;26813:23;26793:18;;;26786:51;26854:18;;46739:63:0;26533:345:1;46739:63:0;46962:14;46974:2;46962:9;:14;:::i;:::-;46946:12;;:30;;;;;;;:::i;:::-;;;;-1:-1:-1;;46995:10:0;;;;46987:47;47032:1;47016:13;:9;47028:1;47016:13;:::i;:::-;:17;;;;:::i;:::-;46987:47;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47052:9;47047:138;47067:8;47063:1;:12;47047:138;;;47097:33;47107:10;47119;47128:1;47119:6;:10;:::i;47097:33::-;47145:28;47159:10;47168:1;47159:6;:10;:::i;47145:28::-;;;47077:3;;;;;:::i;:::-;;;;47047:138;;;;47210:8;47195:11;;:23;;;;;;;:::i;:::-;;;;-1:-1:-1;;47240:10:0;47229:22;;;;:10;:22;;;;;:34;;47255:8;;47229:22;:34;;47255:8;;47229:34;:::i;45419:111::-;4015:6;;4162:23;4015:6;2810:10;4162:23;4154:68;;;;;;;26374:2:1;4154:68:0;;;26356:21:1;;;26393:18;;;26386:30;26452:34;26432:18;;;26425:62;26504:18;;4154:68:0;26172:356:1;4154:68:0;45493:17:::1;:29:::0;;;::::1;::::0;::::1;;::::0;;;::::1;::::0;;45419:111::o;4842:192::-;4015:6;;4162:23;4015:6;2810:10;4162:23;4154:68;;;;;;;26374:2:1;4154:68:0;;;26356:21:1;;;26393:18;;;26386:30;26452:34;26432:18;;;26425:62;26504:18;;4154:68:0;26172:356:1;4154:68:0;4931:22:::1;::::0;::::1;4923:73;;;::::0;::::1;::::0;;21733:2:1;4923:73:0::1;::::0;::::1;21715:21:1::0;21772:2;21752:18;;;21745:30;21811:34;21791:18;;;21784:62;21882:8;21862:18;;;21855:36;21908:19;;4923:73:0::1;21531:402:1::0;4923:73:0::1;5007:19;5017:8;5007:9;:19::i;:::-;4842:192:::0;:::o;23949:305::-;24051:4;24088:40;;;24103:25;24088:40;;:105;;-1:-1:-1;24145:48:0;;;24160:33;24145:48;24088:105;:158;;;-1:-1:-1;16052:25:0;16037:40;;;;24210:36;15928:157;33829:174;33904:24;;;;:15;:24;;;;;:29;;;;;;;;;;;;;:24;;33958:23;33904:24;33958:14;:23::i;:::-;33949:46;;;;;;;;;;;;33829:174;;:::o;30141:348::-;30234:4;29936:16;;;:7;:16;;;;;;:30;:16;30251:73;;;;;;;23941:2:1;30251:73:0;;;23923:21:1;23980:2;23960:18;;;23953:30;24019:34;23999:18;;;23992:62;24090:14;24070:18;;;24063:42;24122:19;;30251:73:0;23739:408:1;30251:73:0;30335:13;30351:23;30366:7;30351:14;:23::i;:::-;30335:39;;30404:5;30393:16;;:7;:16;;;:51;;;;30437:7;30413:31;;:20;30425:7;30413:11;:20::i;:::-;:31;;;30393:51;:87;;;-1:-1:-1;27233:25:0;;;;27209:4;27233:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;30448:32;30385:96;30141:348;-1:-1:-1;;;;30141:348:0:o;33133:578::-;33292:4;33265:31;;:23;33280:7;33265:14;:23::i;:::-;:31;;;33257:85;;;;;;;27085:2:1;33257:85:0;;;27067:21:1;27124:2;27104:18;;;27097:30;27163:34;27143:18;;;27136:62;27234:11;27214:18;;;27207:39;27263:19;;33257:85:0;26883:405:1;33257:85:0;33361:16;;;33353:65;;;;;;;22838:2:1;33353:65:0;;;22820:21:1;22877:2;22857:18;;;22850:30;22916:34;22896:18;;;22889:62;22987:6;22967:18;;;22960:34;23011:19;;33353:65:0;22636:400:1;33353:65:0;33431:39;33452:4;33458:2;33462:7;33431:20;:39::i;:::-;33535:29;33552:1;33556:7;33535:8;:29::i;:::-;33577:15;;;;;;;:9;:15;;;;;:20;;33596:1;;33577:15;:20;;33596:1;;33577:20;:::i;:::-;;;;-1:-1:-1;;33608:13:0;;;;;;;:9;:13;;;;;:18;;33625:1;;33608:13;:18;;33625:1;;33608:18;:::i;:::-;;;;-1:-1:-1;;33637:16:0;;;;:7;:16;;;;;;:21;;;;;;;;;;;;;;33676:27;;33637:16;;33676:27;;;;;;;33133:578;;;:::o;5042:173::-;5117:6;;;;5134:17;;;;;;;;;;;5167:40;;5117:6;;;5134:17;5117:6;;5167:40;;5098:16;;5167:40;5087:128;5042:173;:::o;30831:110::-;30907:26;30917:2;30921:7;30907:26;;;;;;;;;;;;:9;:26::i;:::-;30831:110;;:::o;58119:1379::-;58196:7;58205;58246:12;58261:27;58268:10;58280:7;58261:6;:27::i;:::-;58246:42;;58299:11;58339:1;58325:10;:15;58321:513;;58361:8;58368:1;58361:4;:8;:::i;:::-;58357:160;;-1:-1:-1;43424:1:0;58321:513;;58357:160;-1:-1:-1;43468:1:0;58321:513;;;58604:1;58590:11;58597:4;58590;:11;:::i;:::-;:15;58586:237;;;-1:-1:-1;43512:1:0;58586:237;;;58701:8;58708:1;58701:4;:8;:::i;:::-;58697:126;;-1:-1:-1;43424:1:0;58697:126;;;-1:-1:-1;43468:1:0;58697:126;58854:12;58936:40;58949:4;43562:1;58965:10;58936:12;:40::i;:::-;58929:47;;58994:33;59007:4;43606:1;59023:3;58994:12;:33::i;:::-;58987:40;;59048:18;43512:1;59162:3;:15;59158:205;;59211:1;59198:10;:14;59194:158;;;59246:14;59250:10;59246:1;:14;:::i;:::-;59233:27;;59194:158;;;59286:10;59300:1;59286:15;59282:70;;;-1:-1:-1;59335:1:0;59282:70;59411:48;59424:4;43658:1;59448:10;59411:12;:48::i;:::-;59383:25;;;;:16;:25;;;;;:76;-1:-1:-1;59480:3:0;;-1:-1:-1;59485:4:0;;-1:-1:-1;;58119:1379:0;;;;;;:::o;29219:315::-;29376:28;29386:4;29392:2;29396:7;29376:9;:28::i;:::-;29423:48;29446:4;29452:2;29456:7;29465:5;29423:22;:48::i;:::-;29415:111;;;;;;;20965:2:1;29415:111:0;;;20947:21:1;21004:2;20984:18;;;20977:30;21043:34;21023:18;;;21016:62;21114:20;21094:18;;;21087:48;21152:19;;29415:111:0;20763:414:1;61975:715:0;62031:13;62244:10;62240:53;;-1:-1:-1;;62271:10:0;;;;;;;;;;;;;;;;;;61975:715::o;62240:53::-;62318:5;62303:12;62359:78;62366:9;;62359:78;;62392:8;;;;:::i;:::-;;-1:-1:-1;62415:10:0;;-1:-1:-1;62423:2:0;62415:10;;:::i;:::-;;;62359:78;;;62447:19;62479:6;62469:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;62469:17:0;;62447:39;;62497:154;62504:10;;62497:154;;62531:11;62541:1;62531:11;;:::i;:::-;;-1:-1:-1;62600:10:0;62608:2;62600:5;:10;:::i;:::-;62587:24;;:2;:24;:::i;:::-;62574:39;;62557:6;62564;62557:14;;;;;;;;:::i;:::-;;;;:56;;;;;;;;;;-1:-1:-1;62628:11:0;62637:2;62628:11;;:::i;:::-;;;62497:154;;60356:1607;60454:11;;60414:13;;60480:8;60476:23;;-1:-1:-1;;60490:9:0;;;;;;;;;-1:-1:-1;60490:9:0;;;60356:1607;-1:-1:-1;60356:1607:0:o;60476:23::-;60551:18;60589:1;60578:7;:3;60584:1;60578:7;:::i;:::-;60577:13;;;;:::i;:::-;60572:19;;:1;:19;:::i;:::-;60551:40;-1:-1:-1;60649:19:0;60681:15;60551:40;60694:2;60681:15;:::i;:::-;60671:26;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;60671:26:0;;60649:48;;60710:18;60731:5;;;;;;;;;;;;;;;;;60710:26;;60800:1;60793:5;60789:13;60845:2;60837:6;60833:15;60896:1;60864:777;60919:3;60916:1;60913:10;60864:777;;;60974:1;61017:12;;;;;61011:19;61112:4;61100:2;61096:14;;;;;61078:40;;61072:47;61221:2;61217:14;;;61213:25;;61199:40;;61193:47;61350:1;61346:13;;;61342:24;;61328:39;;61322:46;61470:16;;;;61456:31;;61450:38;61148:1;61144:11;;;61242:4;61189:58;;;61180:68;61273:11;;61318:57;;;61309:67;;;;61401:11;;61446:49;;61437:59;61525:3;61521:13;61554:22;;61624:1;61609:17;;;;60967:9;60864:777;;;60868:44;61673:1;61668:3;61664:11;61694:1;61689:84;;;;61792:1;61787:82;;;;61657:212;;61689:84;61741:16;61722:17;;;61715:43;61689:84;;61787:82;61839:14;61820:17;;;61813:41;61657:212;-1:-1:-1;;;61885:26:0;;;61892:6;60356:1607;-1:-1:-1;;;;60356:1607:0:o;62905:189::-;62974:7;62796:2;63002:5;:16;62994:36;;;;;;;29426:2:1;62994:36:0;;;29408:21:1;29465:1;29445:18;;;29438:29;29503:9;29483:18;;;29476:37;29530:18;;62994:36:0;29224:330:1;62994:36:0;62869:9;62877:1;62830:9;62869;:::i;:::-;63063:12;63070:5;62760:1;63063:12;:::i;:::-;63050:8;:26;;63049:36;63041:45;;62905:189;;;;:::o;63124:281::-;63208:7;62796:2;63236:5;:16;63228:36;;;;;;;29426:2:1;63228:36:0;;;29408:21:1;29465:1;29445:18;;;29438:29;29503:9;29483:18;;;29476:37;29530:18;;63228:36:0;29224:330:1;63228:36:0;62830:9;63283:13;;63275:33;;;;;;;20218:2:1;63275:33:0;;;20200:21:1;20257:1;20237:18;;;20230:29;20295:9;20275:18;;;20268:37;20322:18;;63275:33:0;20016:330:1;63275:33:0;63319:13;62760:1;63319:13;;:::i;:::-;;-1:-1:-1;63382:14:0;;;63319:13;62869:9;62877:1;62830:9;62869;:::i;:::-;63364:12;;63362:15;63351:8;:26;63350:47;63343:54;;63124:281;;;;;:::o;57901:210::-;57969:7;58031:9;58052:16;58067:1;58052:12;:16;:::i;:::-;58014:87;;9496:2:1;9492:15;;;;9509:66;9488:88;58014:87:0;;;9476:101:1;58042:27:0;9593:12:1;;;9586:28;58071:15:0;9630:12:1;;;9623:28;9667:12;;;9660:28;;;9704:13;;;9697:29;;;9742:13;;58014:87:0;;;;;;;;;;;;;58004:98;;58014:87;58004:98;;;;;57901:210;-1:-1:-1;;;57901:210:0:o;52913:375::-;53058:3;43759;53024:11;;:30;;;;:::i;:::-;53023:38;;;;:::i;:::-;53065:1;53023:43;53019:262;;;53111:12;;:22;;53126:7;53111:22;:::i;:::-;53087:21;:46;53083:187;;;53170:7;53154:12;;:23;;;;;;;:::i;:::-;;;;-1:-1:-1;53083:187:0;;-1:-1:-1;53083:187:0;;53233:21;53218:12;:36;52913:375::o;38678:589::-;38884:18;;;38880:187;;38919:40;38951:7;40094:10;:17;;40067:24;;;;:15;:24;;;;;:44;;;40122:24;;;;;;;;;;;;39990:164;38919:40;38880:187;;;38989:2;38981:10;;:4;:10;;;38977:90;;39008:47;39041:4;39047:7;39008:32;:47::i;:::-;39081:16;;;39077:183;;39114:45;39151:7;39114:36;:45::i;39077:183::-;39187:4;39181:10;;:2;:10;;;39177:83;;39208:40;39236:2;39240:7;39208:27;:40::i;31168:321::-;31298:18;31304:2;31308:7;31298:5;:18::i;:::-;31349:54;31380:1;31384:2;31388:7;31397:5;31349:22;:54::i;:::-;31327:154;;;;;;;20965:2:1;31327:154:0;;;20947:21:1;21004:2;20984:18;;;20977:30;21043:34;21023:18;;;21016:62;21114:20;21094:18;;;21087:48;21152:19;;31327:154:0;20763:414:1;34568:799:0;34723:4;34744:13;;;6311:20;6359:8;34740:620;;34780:72;;;;;:36;;;;;;:72;;2810:10;;34831:4;;34837:7;;34846:5;;34780:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;34780:72:0;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;34776:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;35022:13:0;;35018:272;;35065:60;;;;;20965:2:1;35065:60:0;;;20947:21:1;21004:2;20984:18;;;20977:30;21043:34;21023:18;;;21016:62;21114:20;21094:18;;;21087:48;21152:19;;35065:60:0;20763:414:1;35018:272:0;35240:6;35234:13;35225:6;35221:2;35217:15;35210:38;34776:529;34903:51;;34913:41;34903:51;;-1:-1:-1;34896:58:0;;34740:620;-1:-1:-1;35344:4:0;34568:799;;;;;;:::o;40781:988::-;41047:22;41097:1;41072:22;41089:4;41072:16;:22::i;:::-;:26;;;;:::i;:::-;41109:18;41130:26;;;:17;:26;;;;;;41047:51;;-1:-1:-1;41263:28:0;;;41259:328;;41330:18;;;41308:19;41330:18;;;:12;:18;;;;;;;;:34;;;;;;;;;41381:30;;;;;;:44;;;41498:30;;:17;:30;;;;;:43;;;41259:328;-1:-1:-1;41683:26:0;;;;:17;:26;;;;;;;;41676:33;;;41727:18;;;;;;:12;:18;;;;;:34;;;;;;;41720:41;40781:988::o;42064:1079::-;42342:10;:17;42317:22;;42342:21;;42362:1;;42342:21;:::i;:::-;42374:18;42395:24;;;:15;:24;;;;;;42768:10;:26;;42317:46;;-1:-1:-1;42395:24:0;;42317:46;;42768:26;;;;;;:::i;:::-;;;;;;;;;42746:48;;42832:11;42807:10;42818;42807:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;42912:28;;;:15;:28;;;;;;;:41;;;43084:24;;;;;43077:31;43119:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;42135:1008;;;42064:1079;:::o;39568:221::-;39653:14;39670:20;39687:2;39670:16;:20::i;:::-;39701:16;;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;39746:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;39568:221:0:o;31825:382::-;31905:16;;;31897:61;;;;;;;25600:2:1;31897:61:0;;;25582:21:1;;;25619:18;;;25612:30;25678:34;25658:18;;;25651:62;25730:18;;31897:61:0;25398:356:1;31897:61:0;29912:4;29936:16;;;:7;:16;;;;;;:30;:16;:30;31969:58;;;;;;;22481:2:1;31969:58:0;;;22463:21:1;22520:2;22500:18;;;22493:30;22559;22539:18;;;22532:58;22607:18;;31969:58:0;22279:352:1;31969:58:0;32040:45;32069:1;32073:2;32077:7;32040:20;:45::i;:::-;32098:13;;;;;;;:9;:13;;;;;:18;;32115:1;;32098:13;:18;;32115:1;;32098:18;:::i;:::-;;;;-1:-1:-1;;32127:16:0;;;;:7;:16;;;;;;:21;;;;;;;;;;;;;32166:33;;32127:16;;;32166:33;;32127:16;;32166:33;31825:382;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;;;;:::o;:::-;;;;;;;;;;;;;;;14:196:1;82:20;;142:42;131:54;;121:65;;111:93;;200:1;197;190:12;111:93;14:196;;;:::o;215:367::-;278:8;288:6;342:3;335:4;327:6;323:17;319:27;309:55;;360:1;357;350:12;309:55;-1:-1:-1;383:20:1;;426:18;415:30;;412:50;;;458:1;455;448:12;412:50;495:4;487:6;483:17;471:29;;555:3;548:4;538:6;535:1;531:14;523:6;519:27;515:38;512:47;509:67;;;572:1;569;562:12;587:160;652:20;;708:13;;701:21;691:32;;681:60;;737:1;734;727:12;752:186;811:6;864:2;852:9;843:7;839:23;835:32;832:52;;;880:1;877;870:12;832:52;903:29;922:9;903:29;:::i;:::-;893:39;752:186;-1:-1:-1;;;752:186:1:o;943:260::-;1011:6;1019;1072:2;1060:9;1051:7;1047:23;1043:32;1040:52;;;1088:1;1085;1078:12;1040:52;1111:29;1130:9;1111:29;:::i;:::-;1101:39;;1159:38;1193:2;1182:9;1178:18;1159:38;:::i;:::-;1149:48;;943:260;;;;;:::o;1208:328::-;1285:6;1293;1301;1354:2;1342:9;1333:7;1329:23;1325:32;1322:52;;;1370:1;1367;1360:12;1322:52;1393:29;1412:9;1393:29;:::i;:::-;1383:39;;1441:38;1475:2;1464:9;1460:18;1441:38;:::i;:::-;1431:48;;1526:2;1515:9;1511:18;1498:32;1488:42;;1208:328;;;;;:::o;1541:1039::-;1636:6;1644;1652;1660;1713:3;1701:9;1692:7;1688:23;1684:33;1681:53;;;1730:1;1727;1720:12;1681:53;1753:29;1772:9;1753:29;:::i;:::-;1743:39;;1801:2;1822:38;1856:2;1845:9;1841:18;1822:38;:::i;:::-;1812:48;;1907:2;1896:9;1892:18;1879:32;1869:42;;1962:2;1951:9;1947:18;1934:32;1985:18;2026:2;2018:6;2015:14;2012:34;;;2042:1;2039;2032:12;2012:34;2080:6;2069:9;2065:22;2055:32;;2125:7;2118:4;2114:2;2110:13;2106:27;2096:55;;2147:1;2144;2137:12;2096:55;2183:2;2170:16;2205:2;2201;2198:10;2195:36;;;2211:18;;:::i;:::-;2253:112;2361:2;2292:66;2285:4;2281:2;2277:13;2273:86;2269:95;2253:112;:::i;:::-;2240:125;;2388:2;2381:5;2374:17;2428:7;2423:2;2418;2414;2410:11;2406:20;2403:33;2400:53;;;2449:1;2446;2439:12;2400:53;2504:2;2499;2495;2491:11;2486:2;2479:5;2475:14;2462:45;2548:1;2543:2;2538;2531:5;2527:14;2523:23;2516:34;;2569:5;2559:15;;;;;1541:1039;;;;;;;:::o;2585:254::-;2650:6;2658;2711:2;2699:9;2690:7;2686:23;2682:32;2679:52;;;2727:1;2724;2717:12;2679:52;2750:29;2769:9;2750:29;:::i;:::-;2740:39;;2798:35;2829:2;2818:9;2814:18;2798:35;:::i;2844:254::-;2912:6;2920;2973:2;2961:9;2952:7;2948:23;2944:32;2941:52;;;2989:1;2986;2979:12;2941:52;3012:29;3031:9;3012:29;:::i;:::-;3002:39;3088:2;3073:18;;;;3060:32;;-1:-1:-1;;;2844:254:1:o;3103:437::-;3189:6;3197;3250:2;3238:9;3229:7;3225:23;3221:32;3218:52;;;3266:1;3263;3256:12;3218:52;3306:9;3293:23;3339:18;3331:6;3328:30;3325:50;;;3371:1;3368;3361:12;3325:50;3410:70;3472:7;3463:6;3452:9;3448:22;3410:70;:::i;:::-;3499:8;;3384:96;;-1:-1:-1;3103:437:1;-1:-1:-1;;;;3103:437:1:o;3545:773::-;3667:6;3675;3683;3691;3744:2;3732:9;3723:7;3719:23;3715:32;3712:52;;;3760:1;3757;3750:12;3712:52;3800:9;3787:23;3829:18;3870:2;3862:6;3859:14;3856:34;;;3886:1;3883;3876:12;3856:34;3925:70;3987:7;3978:6;3967:9;3963:22;3925:70;:::i;:::-;4014:8;;-1:-1:-1;3899:96:1;-1:-1:-1;4102:2:1;4087:18;;4074:32;;-1:-1:-1;4118:16:1;;;4115:36;;;4147:1;4144;4137:12;4115:36;;4186:72;4250:7;4239:8;4228:9;4224:24;4186:72;:::i;:::-;3545:773;;;;-1:-1:-1;4277:8:1;-1:-1:-1;;;;3545:773:1:o;4323:957::-;4407:6;4438:2;4481;4469:9;4460:7;4456:23;4452:32;4449:52;;;4497:1;4494;4487:12;4449:52;4537:9;4524:23;4566:18;4607:2;4599:6;4596:14;4593:34;;;4623:1;4620;4613:12;4593:34;4661:6;4650:9;4646:22;4636:32;;4706:7;4699:4;4695:2;4691:13;4687:27;4677:55;;4728:1;4725;4718:12;4677:55;4764:2;4751:16;4786:2;4782;4779:10;4776:36;;;4792:18;;:::i;:::-;4838:2;4835:1;4831:10;4821:20;;4861:28;4885:2;4881;4877:11;4861:28;:::i;:::-;4923:15;;;4954:12;;;;4986:11;;;5016;;;5012:20;;5009:33;-1:-1:-1;5006:53:1;;;5055:1;5052;5045:12;5006:53;5077:1;5068:10;;5087:163;5101:2;5098:1;5095:9;5087:163;;;5158:17;;5146:30;;5119:1;5112:9;;;;;5196:12;;;;5228;;5087:163;;;-1:-1:-1;5269:5:1;4323:957;-1:-1:-1;;;;;;;;4323:957:1:o;5285:180::-;5341:6;5394:2;5382:9;5373:7;5369:23;5365:32;5362:52;;;5410:1;5407;5400:12;5362:52;5433:26;5449:9;5433:26;:::i;5470:245::-;5528:6;5581:2;5569:9;5560:7;5556:23;5552:32;5549:52;;;5597:1;5594;5587:12;5549:52;5636:9;5623:23;5655:30;5679:5;5655:30;:::i;5720:249::-;5789:6;5842:2;5830:9;5821:7;5817:23;5813:32;5810:52;;;5858:1;5855;5848:12;5810:52;5890:9;5884:16;5909:30;5933:5;5909:30;:::i;5974:592::-;6045:6;6053;6106:2;6094:9;6085:7;6081:23;6077:32;6074:52;;;6122:1;6119;6112:12;6074:52;6162:9;6149:23;6191:18;6232:2;6224:6;6221:14;6218:34;;;6248:1;6245;6238:12;6218:34;6286:6;6275:9;6271:22;6261:32;;6331:7;6324:4;6320:2;6316:13;6312:27;6302:55;;6353:1;6350;6343:12;6302:55;6393:2;6380:16;6419:2;6411:6;6408:14;6405:34;;;6435:1;6432;6425:12;6405:34;6480:7;6475:2;6466:6;6462:2;6458:15;6454:24;6451:37;6448:57;;;6501:1;6498;6491:12;6448:57;6532:2;6524:11;;;;;6554:6;;-1:-1:-1;5974:592:1;;-1:-1:-1;;;;5974:592:1:o;6571:180::-;6630:6;6683:2;6671:9;6662:7;6658:23;6654:32;6651:52;;;6699:1;6696;6689:12;6651:52;-1:-1:-1;6722:23:1;;6571:180;-1:-1:-1;6571:180:1:o;6756:248::-;6824:6;6832;6885:2;6873:9;6864:7;6860:23;6856:32;6853:52;;;6901:1;6898;6891:12;6853:52;-1:-1:-1;;6924:23:1;;;6994:2;6979:18;;;6966:32;;-1:-1:-1;6756:248:1:o;7009:435::-;7062:3;7100:5;7094:12;7127:6;7122:3;7115:19;7153:4;7182:2;7177:3;7173:12;7166:19;;7219:2;7212:5;7208:14;7240:1;7250:169;7264:6;7261:1;7258:13;7250:169;;;7325:13;;7313:26;;7359:12;;;;7394:15;;;;7286:1;7279:9;7250:169;;;-1:-1:-1;7435:3:1;;7009:435;-1:-1:-1;;;;;7009:435:1:o;7449:316::-;7490:3;7528:5;7522:12;7555:6;7550:3;7543:19;7571:63;7627:6;7620:4;7615:3;7611:14;7604:4;7597:5;7593:16;7571:63;:::i;:::-;7679:2;7667:15;7684:66;7663:88;7654:98;;;;7754:4;7650:109;;7449:316;-1:-1:-1;;7449:316:1:o;7770:185::-;7812:3;7850:5;7844:12;7865:52;7910:6;7905:3;7898:4;7891:5;7887:16;7865:52;:::i;:::-;7933:16;;;;;7770:185;-1:-1:-1;;7770:185:1:o;7960:1088::-;8045:12;;8010:3;;8100:1;8120:18;;;;8173;;;;8200:61;;8254:4;8246:6;8242:17;8232:27;;8200:61;8280:2;8328;8320:6;8317:14;8297:18;8294:38;8291:218;;;8365:77;8362:1;8355:88;8466:4;8463:1;8456:15;8494:4;8491:1;8484:15;8291:218;8525:18;8552:162;;;;8728:1;8723:319;;;;8518:524;;8552:162;8600:66;8589:9;8585:82;8580:3;8573:95;8697:6;8692:3;8688:16;8681:23;;8552:162;;8723:319;30496:1;30489:14;;;30533:4;30520:18;;8817:1;8831:165;8845:6;8842:1;8839:13;8831:165;;;8923:14;;8910:11;;;8903:35;8966:16;;;;8860:10;;8831:165;;;8835:3;;9025:6;9020:3;9016:16;9009:23;;8518:524;;;;;;;7960:1088;;;;:::o;9766:614::-;10046:3;10084:6;10078:13;10100:53;10146:6;10141:3;10134:4;10126:6;10122:17;10100:53;:::i;:::-;10214:3;10175:16;;;10200:18;;;10243:13;;10265:65;10243:13;10317:1;10306:13;;10299:4;10287:17;;10265:65;:::i;:::-;10350:20;10372:1;10346:28;;9766:614;-1:-1:-1;;;;9766:614:1:o;10385:2031::-;11195:66;11190:3;11183:79;11292:66;11287:2;11282:3;11278:12;11271:88;11165:3;11388:6;11382:13;11404:60;11457:6;11452:2;11447:3;11443:12;11438:2;11430:6;11426:15;11404:60;:::i;:::-;11528:66;11523:2;11483:16;;;11515:11;;;11508:87;11624:66;11619:2;11611:11;;11604:87;11716:13;;11738:61;11716:13;11785:2;11777:11;;11772:2;11760:15;;11738:61;:::i;:::-;11826:8;11822:2;11818:17;11808:27;;;11864:66;11859:2;11855;11851:11;11844:87;11950:66;12046:2;12040:3;12036:2;12032:12;12025:24;12080:6;12074:13;12096:62;12149:8;12143:3;12139:2;12135:12;12130:2;12122:6;12118:15;12096:62;:::i;:::-;12224:66;12218:3;12177:17;;;;12210:12;;;12203:88;12315:3;12307:12;;12300:24;12340:70;12370:39;12404:3;12396:12;;12388:6;12370:39;:::i;:::-;9130:66;9118:79;;9222:1;9213:11;;9053:177;12340:70;12333:77;10385:2031;-1:-1:-1;;;;;;;10385:2031:1:o;12421:1698::-;13069:66;13064:3;13057:79;13039:3;13165:6;13159:13;13191:4;13204:60;13257:6;13252:2;13247:3;13243:12;13238:2;13230:6;13226:15;13204:60;:::i;:::-;13324:13;;13283:16;;;;13346:61;13324:13;13393:2;13385:11;;13368:15;;;13346:61;:::i;:::-;13468:13;;13426:17;;;13490:61;13468:13;13537:2;13529:11;;13512:15;;;13490:61;:::i;:::-;13570;13627:2;13616:8;13612:2;13608:17;13604:26;13596:6;13570:61;:::i;:::-;13560:71;;;13662:6;13656:13;13678:52;13721:8;13717:2;13712;13704:6;13700:15;13678:52;:::i;:::-;13794:13;;13752:17;;;13816:55;13794:13;13752:17;13838:15;;;13816:55;:::i;:::-;13938:13;;13893:20;;;13960:55;13938:13;13893:20;13982:15;;;13960:55;:::i;:::-;14080:3;14037:20;;14066:18;;;-1:-1:-1;14111:1:1;14100:13;;12421:1698;-1:-1:-1;;;;;;;;;12421:1698:1:o;14124:448::-;14386:31;14381:3;14374:44;14356:3;14447:6;14441:13;14463:62;14518:6;14513:2;14508:3;14504:12;14497:4;14489:6;14485:17;14463:62;:::i;:::-;14545:16;;;;14563:2;14541:25;;14124:448;-1:-1:-1;;14124:448:1:o;14577:974::-;15033:66;15028:3;15021:79;15003:3;15129:6;15123:13;15145:62;15200:6;15195:2;15190:3;15186:12;15179:4;15171:6;15167:17;15145:62;:::i;:::-;15267:13;;15226:16;;;;15289:63;15267:13;15338:2;15330:11;;15323:4;15311:17;;15289:63;:::i;:::-;15371:61;15428:2;15417:8;15413:2;15409:17;15405:26;15397:6;15371:61;:::i;:::-;15452:66;15441:78;;15543:1;15535:10;;14577:974;-1:-1:-1;;;;;;;14577:974:1:o;15787:511::-;15981:4;16010:42;16091:2;16083:6;16079:15;16068:9;16061:34;16143:2;16135:6;16131:15;16126:2;16115:9;16111:18;16104:43;;16183:6;16178:2;16167:9;16163:18;16156:34;16226:3;16221:2;16210:9;16206:18;16199:31;16247:45;16287:3;16276:9;16272:19;16264:6;16247:45;:::i;:::-;16239:53;15787:511;-1:-1:-1;;;;;;15787:511:1:o;17365:1312::-;17690:3;17743:21;;;17813:13;;17716:18;;;17835:22;;;17661:4;;17888:3;17873:19;;;17911:4;;17938:15;;;17661:4;17981:218;17995:6;17992:1;17989:13;17981:218;;;18060:13;;18075:42;18056:62;18044:75;;18139:12;;;;18174:15;;;;18017:1;18010:9;17981:218;;;17985:3;;;18244:9;18239:3;18235:19;18230:2;18219:9;18215:18;18208:47;18272:41;18309:3;18301:6;18272:41;:::i;:::-;18264:49;;18350:2;18339:9;18335:18;18322:31;;18401:6;18427:1;18437:234;18453:4;18448:3;18445:13;18437:234;;;18522:15;;18539:42;18518:64;18504:79;;18605:14;;;;18644:17;;;;18477:1;18468:11;18437:234;;;18441:3;;;;17365:1312;;;;;;:::o;18682:261::-;18861:2;18850:9;18843:21;18824:4;18881:56;18933:2;18922:9;18918:18;18910:6;18881:56;:::i;18948:647::-;19117:2;19169:21;;;19239:13;;19142:18;;;19261:22;;;19088:4;;19117:2;19340:15;;;;19314:2;19299:18;;;19088:4;19383:186;19397:6;19394:1;19391:13;19383:186;;;19462:13;;19477:10;19458:30;19446:43;;19544:15;;;;19509:12;;;;19419:1;19412:9;19383:186;;;-1:-1:-1;19586:3:1;;18948:647;-1:-1:-1;;;;;;18948:647:1:o;19792:219::-;19941:2;19930:9;19923:21;19904:4;19961:44;20001:2;19990:9;19986:18;19978:6;19961:44;:::i;30084:334::-;30155:2;30149:9;30211:2;30201:13;;30216:66;30197:86;30185:99;;30314:18;30299:34;;30335:22;;;30296:62;30293:88;;;30361:18;;:::i;:::-;30397:2;30390:22;30084:334;;-1:-1:-1;30084:334:1:o;30549:128::-;30589:3;30620:1;30616:6;30613:1;30610:13;30607:39;;;30626:18;;:::i;:::-;-1:-1:-1;30662:9:1;;30549:128::o;30682:120::-;30722:1;30748;30738:35;;30753:18;;:::i;:::-;-1:-1:-1;30787:9:1;;30682:120::o;30807:228::-;30847:7;30973:1;30905:66;30901:74;30898:1;30895:81;30890:1;30883:9;30876:17;30872:105;30869:131;;;30980:18;;:::i;:::-;-1:-1:-1;31020:9:1;;30807:228::o;31040:125::-;31080:4;31108:1;31105;31102:8;31099:34;;;31113:18;;:::i;:::-;-1:-1:-1;31150:9:1;;31040:125::o;31170:258::-;31242:1;31252:113;31266:6;31263:1;31260:13;31252:113;;;31342:11;;;31336:18;31323:11;;;31316:39;31288:2;31281:10;31252:113;;;31383:6;31380:1;31377:13;31374:48;;;-1:-1:-1;;31418:1:1;31400:16;;31393:27;31170:258::o;31433:437::-;31512:1;31508:12;;;;31555;;;31576:61;;31630:4;31622:6;31618:17;31608:27;;31576:61;31683:2;31675:6;31672:14;31652:18;31649:38;31646:218;;;31720:77;31717:1;31710:88;31821:4;31818:1;31811:15;31849:4;31846:1;31839:15;31646:218;;31433:437;;;:::o;31875:195::-;31914:3;31945:66;31938:5;31935:77;31932:103;;;32015:18;;:::i;:::-;-1:-1:-1;32062:1:1;32051:13;;31875:195::o;32075:112::-;32107:1;32133;32123:35;;32138:18;;:::i;:::-;-1:-1:-1;32172:9:1;;32075:112::o;32192:184::-;32244:77;32241:1;32234:88;32341:4;32338:1;32331:15;32365:4;32362:1;32355:15;32381:184;32433:77;32430:1;32423:88;32530:4;32527:1;32520:15;32554:4;32551:1;32544:15;32570:184;32622:77;32619:1;32612:88;32719:4;32716:1;32709:15;32743:4;32740:1;32733:15;32759:184;32811:77;32808:1;32801:88;32908:4;32905:1;32898:15;32932:4;32929:1;32922:15;32948:184;33000:77;32997:1;32990:88;33097:4;33094:1;33087:15;33121:4;33118:1;33111:15;33137:177;33222:66;33215:5;33211:78;33204:5;33201:89;33191:117;;33304:1;33301;33294:12

Swarm Source

ipfs://c0dd4d44c0d5255a8f1544c161c77b546f7772824c971070567e5b8e673e4f64
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

A token is a representation of an on-chain or off-chain asset. The token page shows information such as price, total supply, holders, transfers and social links. Learn more about this page in our Knowledge Base.