ETH Price: $3,786.20 (+6.08%)

Token

Puli Runners (PRNR)
 

Overview

Max Total Supply

962 PRNR

Holders

298

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 PRNR
0x46cca403d1f233f10f759635c1e2295ec40f64e8
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:
PuliRunners

Compiler Version
v0.8.1+commit.df193b15

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-04-15
*/

// Dependency file: @openzeppelin/contracts/token/ERC20/IERC20.sol

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC20/IERC20.sol)

// pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    /**
     * @dev Returns the amount of tokens in existence.
     */
    function totalSupply() external view returns (uint256);

    /**
     * @dev Returns the amount of tokens owned by `account`.
     */
    function balanceOf(address account) external view returns (uint256);

    /**
     * @dev Moves `amount` tokens from the caller's account to `to`.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transfer(address to, uint256 amount) external returns (bool);

    /**
     * @dev Returns the remaining number of tokens that `spender` will be
     * allowed to spend on behalf of `owner` through {transferFrom}. This is
     * zero by default.
     *
     * This value changes when {approve} or {transferFrom} are called.
     */
    function allowance(address owner, address spender) external view returns (uint256);

    /**
     * @dev Sets `amount` as the allowance of `spender` over the caller's tokens.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * IMPORTANT: Beware that changing an allowance with this method brings the risk
     * that someone may use both the old and the new allowance by unfortunate
     * transaction ordering. One possible solution to mitigate this race
     * condition is to first reduce the spender's allowance to 0 and set the
     * desired value afterwards:
     * https://github.com/ethereum/EIPs/issues/20#issuecomment-263524729
     *
     * Emits an {Approval} event.
     */
    function approve(address spender, uint256 amount) external returns (bool);

    /**
     * @dev Moves `amount` tokens from `from` to `to` using the
     * allowance mechanism. `amount` is then deducted from the caller's
     * allowance.
     *
     * Returns a boolean value indicating whether the operation succeeded.
     *
     * Emits a {Transfer} event.
     */
    function transferFrom(
        address from,
        address to,
        uint256 amount
    ) external returns (bool);

    /**
     * @dev Emitted when `value` tokens are moved from one account (`from`) to
     * another (`to`).
     *
     * Note that `value` may be zero.
     */
    event Transfer(address indexed from, address indexed to, uint256 value);

    /**
     * @dev Emitted when the allowance of a `spender` for an `owner` is set by
     * a call to {approve}. `value` is the new allowance.
     */
    event Approval(address indexed owner, address indexed spender, uint256 value);
}


// Dependency file: @openzeppelin/contracts/utils/introspection/IERC165.sol

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

// pragma solidity ^0.8.0;

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


// Dependency file: @openzeppelin/contracts/token/ERC721/IERC721.sol

// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)

// pragma solidity ^0.8.0;

// import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

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


// Dependency file: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol

// OpenZeppelin Contracts v4.4.1 (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);
}


// Dependency file: @openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol

// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

// pragma solidity ^0.8.0;

// import "@openzeppelin/contracts/token/ERC721/IERC721.sol";

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


// Dependency file: @openzeppelin/contracts/utils/Address.sol

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

// pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

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

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

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


// Dependency file: @openzeppelin/contracts/utils/Context.sol

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

// pragma solidity ^0.8.0;

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

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


// Dependency file: @openzeppelin/contracts/utils/Strings.sol

// OpenZeppelin Contracts v4.4.1 (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);
    }
}


// Dependency file: @openzeppelin/contracts/utils/introspection/ERC165.sol

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

// pragma solidity ^0.8.0;

// import "@openzeppelin/contracts/utils/introspection/IERC165.sol";

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


// Dependency file: @openzeppelin/contracts/token/ERC721/ERC721.sol

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

// pragma solidity ^0.8.0;

// import "@openzeppelin/contracts/token/ERC721/IERC721.sol";
// import "@openzeppelin/contracts/token/ERC721/IERC721Receiver.sol";
// import "@openzeppelin/contracts/token/ERC721/extensions/IERC721Metadata.sol";
// import "@openzeppelin/contracts/utils/Address.sol";
// import "@openzeppelin/contracts/utils/Context.sol";
// import "@openzeppelin/contracts/utils/Strings.sol";
// import "@openzeppelin/contracts/utils/introspection/ERC165.sol";

/**
 * @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 {
        _setApprovalForAll(_msgSender(), operator, approved);
    }

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

    /**
     * @dev See {IERC721-transferFrom}.
     */
    function transferFrom(
        address from,
        address to,
        uint256 tokenId
    ) public virtual override {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721: 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);

        _afterTokenTransfer(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);

        _afterTokenTransfer(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 from incorrect owner");
        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);

        _afterTokenTransfer(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 Approve `operator` to operate on all of `owner` tokens
     *
     * Emits a {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC721: approve to caller");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev 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 {}

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}


// Dependency file: @openzeppelin/contracts/access/Ownable.sol

// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

// pragma solidity ^0.8.0;

// import "@openzeppelin/contracts/utils/Context.sol";

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

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

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

    /**
     * @dev 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 {
        _transferOwnership(address(0));
    }

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

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


// Dependency file: @openzeppelin/contracts/utils/Counters.sol

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

// pragma solidity ^0.8.0;

/**
 * @title Counters
 * @author Matt Condon (@shrugs)
 * @dev Provides counters that can only be incremented, decremented or reset. This can be used e.g. to track the number
 * of elements in a mapping, issuing ERC721 ids, or counting request ids.
 *
 * Include with `using Counters for Counters.Counter;`
 */
library Counters {
    struct Counter {
        // This variable should never be directly accessed by users of the library: interactions must be restricted to
        // the library's function. As of Solidity v0.5.2, this cannot be enforced, though there is a proposal to add
        // this feature: see https://github.com/ethereum/solidity/issues/4637
        uint256 _value; // default: 0
    }

    function current(Counter storage counter) internal view returns (uint256) {
        return counter._value;
    }

    function increment(Counter storage counter) internal {
        unchecked {
            counter._value += 1;
        }
    }

    function decrement(Counter storage counter) internal {
        uint256 value = counter._value;
        require(value > 0, "Counter: decrement overflow");
        unchecked {
            counter._value = value - 1;
        }
    }

    function reset(Counter storage counter) internal {
        counter._value = 0;
    }
}


// Dependency file: @openzeppelin/contracts/utils/math/SafeMath.sol

// OpenZeppelin Contracts v4.4.1 (utils/math/SafeMath.sol)

// pragma solidity ^0.8.0;

// CAUTION
// This version of SafeMath should only be used with Solidity 0.8 or later,
// because it relies on the compiler's built in overflow checks.

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is generally not needed starting with Solidity 0.8, since the compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

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

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

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

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

    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting on
     * overflow (when the result is negative).
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(uint256 a, uint256 b) internal pure returns (uint256) {
        return a - b;
    }

    /**
     * @dev Returns the multiplication of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `*` operator.
     *
     * Requirements:
     *
     * - Multiplication cannot overflow.
     */
    function mul(uint256 a, uint256 b) internal pure returns (uint256) {
        return a * b;
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator.
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(uint256 a, uint256 b) internal pure returns (uint256) {
        return a / b;
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting when dividing by zero.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(uint256 a, uint256 b) internal pure returns (uint256) {
        return a % b;
    }

    /**
     * @dev Returns the subtraction of two unsigned integers, reverting with custom message on
     * overflow (when the result is negative).
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {trySub}.
     *
     * Counterpart to Solidity's `-` operator.
     *
     * Requirements:
     *
     * - Subtraction cannot overflow.
     */
    function sub(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b <= a, errorMessage);
            return a - b;
        }
    }

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `/` operator. Note: this function uses a
     * `revert` opcode (which leaves remaining gas untouched) while Solidity
     * uses an invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function div(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a / b;
        }
    }

    /**
     * @dev Returns the remainder of dividing two unsigned integers. (unsigned integer modulo),
     * reverting with custom message when dividing by zero.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryMod}.
     *
     * Counterpart to Solidity's `%` operator. This function uses a `revert`
     * opcode (which leaves remaining gas untouched) while Solidity uses an
     * invalid opcode to revert (consuming all remaining gas).
     *
     * Requirements:
     *
     * - The divisor cannot be zero.
     */
    function mod(
        uint256 a,
        uint256 b,
        string memory errorMessage
    ) internal pure returns (uint256) {
        unchecked {
            require(b > 0, errorMessage);
            return a % b;
        }
    }
}


// Dependency file: src/common/meta-transactions/ContentMixin.sol


// pragma solidity ^0.8.0;

abstract contract ContextMixin {
    function msgSender()
        internal
        view
        returns (address payable sender)
    {
        if (msg.sender == address(this)) {
            bytes memory array = msg.data;
            uint256 index = msg.data.length;
            assembly {
                // Load the 32 bytes word from memory with the address on the lower 20 bytes, and mask those.
                sender := and(
                    mload(add(array, index)),
                    0xffffffffffffffffffffffffffffffffffffffff
                )
            }
        } else {
            sender = payable(msg.sender);
        }
        return sender;
    }
}


// Dependency file: src/common/meta-transactions/Initializable.sol


// pragma solidity ^0.8.0;

contract Initializable {
    bool inited = false;

    modifier initializer() {
        require(!inited, "already inited");
        _;
        inited = true;
    }
}


// Dependency file: src/common/meta-transactions/EIP712Base.sol


// pragma solidity ^0.8.0;

// import {Initializable} from "src/common/meta-transactions/Initializable.sol";

contract EIP712Base is Initializable {
    struct EIP712Domain {
        string name;
        string version;
        address verifyingContract;
        bytes32 salt;
    }

    string constant public ERC712_VERSION = "1";

    bytes32 internal constant EIP712_DOMAIN_TYPEHASH = keccak256(
        bytes(
            "EIP712Domain(string name,string version,address verifyingContract,bytes32 salt)"
        )
    );
    bytes32 internal domainSeperator;

    // supposed to be called once while initializing.
    // one of the contracts that inherits this contract follows proxy pattern
    // so it is not possible to do this in a constructor
    function _initializeEIP712(
        string memory name
    )
        internal
        initializer
    {
        _setDomainSeperator(name);
    }

    function _setDomainSeperator(string memory name) internal {
        domainSeperator = keccak256(
            abi.encode(
                EIP712_DOMAIN_TYPEHASH,
                keccak256(bytes(name)),
                keccak256(bytes(ERC712_VERSION)),
                address(this),
                bytes32(getChainId())
            )
        );
    }

    function getDomainSeperator() public view returns (bytes32) {
        return domainSeperator;
    }

    function getChainId() public view returns (uint256) {
        uint256 id;
        assembly {
            id := chainid()
        }
        return id;
    }

    /**
     * Accept message hash and returns hash message in EIP712 compatible form
     * So that it can be used to recover signer from signature signed using EIP712 formatted data
     * https://eips.ethereum.org/EIPS/eip-712
     * "\\x19" makes the encoding deterministic
     * "\\x01" is the version byte to make it compatible to EIP-191
     */
    function toTypedMessageHash(bytes32 messageHash)
        internal
        view
        returns (bytes32)
    {
        return
            keccak256(
                abi.encodePacked("\x19\x01", getDomainSeperator(), messageHash)
            );
    }
}

// Dependency file: src/common/meta-transactions/NativeMetaTransaction.sol


// pragma solidity ^0.8.0;

// import {SafeMath} from  "@openzeppelin/contracts/utils/math/SafeMath.sol";
// import {EIP712Base} from "src/common/meta-transactions/EIP712Base.sol";

contract NativeMetaTransaction is EIP712Base {
    using SafeMath for uint256;
    bytes32 private constant META_TRANSACTION_TYPEHASH = keccak256(
        bytes(
            "MetaTransaction(uint256 nonce,address from,bytes functionSignature)"
        )
    );
    event MetaTransactionExecuted(
        address userAddress,
        address payable relayerAddress,
        bytes functionSignature
    );
    mapping(address => uint256) nonces;

    /*
     * Meta transaction structure.
     * No point of including value field here as if user is doing value transfer then he has the funds to pay for gas
     * He should call the desired function directly in that case.
     */
    struct MetaTransaction {
        uint256 nonce;
        address from;
        bytes functionSignature;
    }

    function executeMetaTransaction(
        address userAddress,
        bytes memory functionSignature,
        bytes32 sigR,
        bytes32 sigS,
        uint8 sigV
    ) public payable returns (bytes memory) {
        MetaTransaction memory metaTx = MetaTransaction({
            nonce: nonces[userAddress],
            from: userAddress,
            functionSignature: functionSignature
        });

        require(
            verify(userAddress, metaTx, sigR, sigS, sigV),
            "Signer and signature do not match"
        );

        // increase nonce for user (to avoid re-use)
        nonces[userAddress] = nonces[userAddress].add(1);

        emit MetaTransactionExecuted(
            userAddress,
            payable(msg.sender),
            functionSignature
        );

        // Append userAddress and relayer address at the end to extract it from calling context
        (bool success, bytes memory returnData) = address(this).call(
            abi.encodePacked(functionSignature, userAddress)
        );
        require(success, "Function call not successful");

        return returnData;
    }

    function hashMetaTransaction(MetaTransaction memory metaTx)
        internal
        pure
        returns (bytes32)
    {
        return
            keccak256(
                abi.encode(
                    META_TRANSACTION_TYPEHASH,
                    metaTx.nonce,
                    metaTx.from,
                    keccak256(metaTx.functionSignature)
                )
            );
    }

    function getNonce(address user) public view returns (uint256 nonce) {
        nonce = nonces[user];
    }

    function verify(
        address signer,
        MetaTransaction memory metaTx,
        bytes32 sigR,
        bytes32 sigS,
        uint8 sigV
    ) internal view returns (bool) {
        require(signer != address(0), "NativeMetaTransaction: INVALID_SIGNER");
        return
            signer ==
            ecrecover(
                toTypedMessageHash(hashMetaTransaction(metaTx)),
                sigV,
                sigR,
                sigS
            );
    }
}


// Dependency file: src/PuliNFT.sol


// pragma solidity ^0.8.0;

// import "@openzeppelin/contracts/token/ERC20/IERC20.sol";
// import "@openzeppelin/contracts/token/ERC721/ERC721.sol";
// import "@openzeppelin/contracts/access/Ownable.sol";
// import "@openzeppelin/contracts/utils/Counters.sol";
// import "@openzeppelin/contracts/utils/Strings.sol";
// import "@openzeppelin/contracts/utils/math/SafeMath.sol";

// import "src/common/meta-transactions/ContentMixin.sol";
// import "src/common/meta-transactions/NativeMetaTransaction.sol";

contract OwnableDelegateProxy {}

contract ProxyRegistry {
    mapping(address => OwnableDelegateProxy) public proxies;
}

abstract contract PuliNFT is
    ERC721,
    ContextMixin,
    NativeMetaTransaction,
    Ownable
{
    address proxyRegistryAddress;

    struct WhiteListInfo {
        mapping(address => uint256) users;
        address[] userlist;
    }

    WhiteListInfo whitelist;

    mapping(address => uint256) price;

    uint256 public tokenIdCounter = 1;
    uint256 public totalSupply = 0;
    uint256 public maxSupply = 0;

    address public constant NATIVE = 0x0000000000000000000000000000000000000001;

    event SetWhiteList(address[] whitelistAddress, uint256 quantity);

    event SetPrice(address[] tokenAddress, uint256[] tokenPrice);

    event WhiteListMint(address indexed whitelistAddress, uint256 index);
    event Mint(address indexed publicAddress, uint256 index);

    constructor(
        string memory name_,
        string memory symbol_,
        address proxyAddress,
        uint256 _maxSupply
    ) ERC721(name_, symbol_) {
        proxyRegistryAddress = proxyAddress;
        _initializeEIP712(name_);
        maxSupply = _maxSupply;
    }

    function mintTo(address to) external onlyOwner {
        require(
            maxSupply == 0 || maxSupply > totalSupply,
            "Max supply exceeded"
        );
        uint256 currentTokenId = tokenIdCounter++;
        _safeMint(to, currentTokenId);
        totalSupply++;
        emit Mint(to, currentTokenId);
    }

    function setWhiteList(
        address[] memory whitelistAddress,
        uint256 quantity,
        address[] memory tokenAddress,
        uint256[] memory tokenPrice
    ) external onlyOwner {
        require(whitelistAddress.length > 0, "No addresses inputted");
        require(quantity > 0, "Invalid quantity, should be greater than 0");

        setPrice(tokenAddress, tokenPrice);

        for (
            uint256 address_index = 0;
            address_index < whitelistAddress.length;
            address_index++
        ) {
            whitelist.users[whitelistAddress[address_index]] = quantity;
        }
        whitelist.userlist = whitelistAddress;
        emit SetWhiteList(whitelistAddress, quantity);
    }

    function mint(uint256 quantity) public payable virtual {
        require((quantity + totalSupply) <= maxSupply, "Max supply exceeded");

        _checkPricing(address(NATIVE), quantity);

        _checkWhitelist(_msgSender(), quantity);

        totalSupply += quantity;
        for (uint256 index = 0; index < quantity; index++) {
            _safeMint(_msgSender(), tokenIdCounter);
            emit Mint(msg.sender, tokenIdCounter++);
        }
    }

    function mintByToken(IERC20 token, uint256 quantity) public virtual {
        require((quantity + totalSupply) <= maxSupply, "Max supply exceeded");

        require(price[address(token)] > 0, "Price is not set for minting");

        _checkWhitelist(_msgSender(), quantity);

        // Transfer IERC20 to contract
        uint256 _price = price[address(token)];
        bool success = token.transferFrom(
            msgSender(),
            address(this),
            quantity * _price
        );
        require(success, "Transfer failed");

        totalSupply += quantity;
        for (uint256 index = 0; index < quantity; index++) {
            _safeMint(_msgSender(), tokenIdCounter);
            emit Mint(msg.sender, tokenIdCounter++);
        }
    }

    function closeWhitelisting(
        address[] memory tokenAddress,
        uint256[] memory tokenPrice
    ) external onlyOwner {
        require(
            whitelist.userlist.length > 0,
            "Error cannot close, No Whitelist addresses added"
        );
        for (uint256 index = 0; index < whitelist.userlist.length; index++) {
            address currentUser = whitelist.userlist[index];
            whitelist.users[currentUser] = 0;
        }
        delete whitelist.userlist;
        setPrice(tokenAddress, tokenPrice);
    }

    function getPrice(address tokenAddress) external view returns (uint256) {
        require(tokenAddress > address(0), "Invalid address");
        require(price[address(tokenAddress)] > 0, "Price is not yet set");
        return price[tokenAddress];
    }

    function contractURI() external view virtual returns (string memory);

    function setPrice(
        address[] memory tokenAddress,
        uint256[] memory tokenPrice
    ) public onlyOwner {
        require(tokenAddress.length > 0, "Token address is empty");
        require(tokenPrice.length > 0, "Token price is empty");
        require(
            tokenPrice.length == tokenAddress.length,
            "Price and address does not match"
        );

        bool isNativeIncluded = false;
        for (uint256 index = 0; index < tokenAddress.length; index++) {
            if (tokenAddress[index] == address(NATIVE)) {
                isNativeIncluded = true;
            }
        }

        require(
            isNativeIncluded,
            "Error, price does not contain native currency"
        );

        for (uint256 index = 0; index < tokenAddress.length; index++) {
            require(
                tokenPrice[index] > 0,
                "Invalid quantity, should be greater than 0"
            );
            price[address(tokenAddress[index])] = tokenPrice[index];
        }
        emit SetPrice(tokenAddress, tokenPrice);
    }

    function tokenURI(uint256 tokenId)
        public
        view
        override
        returns (string memory)
    {
        return
            string(
                abi.encodePacked(
                    baseTokenURI(),
                    Strings.toString(tokenId),
                    ".json"
                )
            );
    }

    function baseTokenURI() public view virtual returns (string memory);

    /**
     * Override isApprovedForAll to whitelist user's OpenSea proxy accounts to enable gas-less listings.
     */
    function isApprovedForAll(address owner, address operator)
        public
        view
        override
        returns (bool)
    {
        // Whitelist OpenSea proxy contract for easy trading.
        ProxyRegistry proxyRegistry = ProxyRegistry(proxyRegistryAddress);
        if (address(proxyRegistry.proxies(owner)) == operator) {
            return true;
        }

        return super.isApprovedForAll(owner, operator);
    }

    function _checkWhitelist(address user, uint256 quantity) private {
        if (whitelist.userlist.length > 0) {
            require(
                whitelist.users[user] > 0,
                "Current user is not whitelisted"
            );
            require(
                quantity <= whitelist.users[user],
                "Current user exceeds allowable mint"
            );
            whitelist.users[user] -= quantity;
        }
    }

    function _checkPricing(address tokenAddress, uint256 quantity)
        private
        view
    {
        require(
            price[address(tokenAddress)] > 0,
            "Price is not set for minting"
        );
        require(
            msg.value >= price[address(tokenAddress)] * quantity,
            "Insufficient amount, cannot mint"
        );
    }
}


// Dependency file: @openzeppelin/contracts/interfaces/IERC20.sol

// OpenZeppelin Contracts v4.4.1 (interfaces/IERC20.sol)

// pragma solidity ^0.8.0;

// import "@openzeppelin/contracts/token/ERC20/IERC20.sol";


// Dependency file: src/IPayroll.sol

// pragma solidity ^0.8.0;

// import "@openzeppelin/contracts/token/ERC20/IERC20.sol";

interface IPayroll {
    event PaymentReceived(address indexed sender, uint256 amount);
    event PaymentTokensReceived(
        address indexed sender,
        address token,
        uint256 amount
    );
    event PaymentReleased(address indexed sender, uint256 amount);
    event PaymentTokensReleased(
        address indexed sender,
        address token,
        uint256 amount
    );

    function receivePayment() external payable;

    function receivePayment(IERC20 token, uint256 amount) external;

    function releasePayment(uint256 amount) external payable;

    function releasePayment(IERC20 token, uint256 amount) external;
}


// Root file: src/PuliRunners.sol


pragma solidity ^0.8.0;

// import "src/PuliNFT.sol";
// import "@openzeppelin/contracts/utils/Address.sol";
// import "@openzeppelin/contracts/interfaces/IERC20.sol";
// import "src/IPayroll.sol";

contract PuliRunners is PuliNFT {
    event Withdraw(address indexed recepient, uint256 indexed amount);
    event WithdrawTokens(
        address indexed recepient,
        IERC20 indexed tokenAddress,
        uint256 indexed amount
    );
    event SetWithdrawalAddress(address indexed withdrawalAddress);

    address public withdrawalAddress;

    string public baseToken = "https://runners.pulitoken.net/metadata/";

    uint256 public constant maxSaleCount = 2000;

    constructor(address proxyAddress)
        PuliNFT("Puli Runners", "PRNR", proxyAddress, 2011)
    {
        withdrawalAddress = msg.sender;
    }

    function setBaseTokenURI(string memory _baseToken) external onlyOwner {
        baseToken = _baseToken;
    }

    function baseTokenURI() public view override returns (string memory) {
        return baseToken;
    }

    function contractURI() external view override returns (string memory) {
        return string(abi.encodePacked(baseTokenURI(), "contract.json"));
    }

    function setWithdrawalAddress(address _withdrawalAddress)
        external
        onlyOwner
    {
        require(_withdrawalAddress != address(0), "Invalid withdrawal address");
        withdrawalAddress = _withdrawalAddress;
        emit SetWithdrawalAddress(_withdrawalAddress);
    }

    function withdraw(address tokenAddress, uint256 amount)
        external
        payable
        onlyOwner
    {
        require(amount > 0, "Invalid amount");
        bool isContract = Address.isContract(withdrawalAddress);
        if (tokenAddress == NATIVE) {
            if (isContract) {
                Address.functionCallWithValue(
                    withdrawalAddress,
                    abi.encodeWithSignature("receivePayment()"),
                    amount
                );
            } else {
                Address.sendValue(payable(withdrawalAddress), amount);
            }
            emit Withdraw(withdrawalAddress, amount);
            return;
        }
        IERC20 token = IERC20(tokenAddress);
        if (isContract) {
            bool success = token.approve(withdrawalAddress, amount);
            require(success, "Failed to approve withdrawal");
            IPayroll(withdrawalAddress).receivePayment(token, amount);
        } else {
            token.transfer(withdrawalAddress, amount);
        }
        emit WithdrawTokens(withdrawalAddress, token, amount);
    }

    function mint(uint256 quantity) public payable override {
        require(totalSupply + quantity <= maxSaleCount, "Max sale reached");
        super.mint(quantity);
    }

    function mintByToken(IERC20 token, uint256 quantity) public override {
        require(totalSupply + quantity <= maxSaleCount, "Max sale reached");
        super.mintByToken(token, quantity);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"proxyAddress","type":"address"}],"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":"address","name":"userAddress","type":"address"},{"indexed":false,"internalType":"address payable","name":"relayerAddress","type":"address"},{"indexed":false,"internalType":"bytes","name":"functionSignature","type":"bytes"}],"name":"MetaTransactionExecuted","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"publicAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"Mint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"tokenAddress","type":"address[]"},{"indexed":false,"internalType":"uint256[]","name":"tokenPrice","type":"uint256[]"}],"name":"SetPrice","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address[]","name":"whitelistAddress","type":"address[]"},{"indexed":false,"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"SetWhiteList","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"withdrawalAddress","type":"address"}],"name":"SetWithdrawalAddress","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"whitelistAddress","type":"address"},{"indexed":false,"internalType":"uint256","name":"index","type":"uint256"}],"name":"WhiteListMint","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recepient","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"Withdraw","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"recepient","type":"address"},{"indexed":true,"internalType":"contract IERC20","name":"tokenAddress","type":"address"},{"indexed":true,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"WithdrawTokens","type":"event"},{"inputs":[],"name":"ERC712_VERSION","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NATIVE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseToken","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokenAddress","type":"address[]"},{"internalType":"uint256[]","name":"tokenPrice","type":"uint256[]"}],"name":"closeWhitelisting","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"contractURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"userAddress","type":"address"},{"internalType":"bytes","name":"functionSignature","type":"bytes"},{"internalType":"bytes32","name":"sigR","type":"bytes32"},{"internalType":"bytes32","name":"sigS","type":"bytes32"},{"internalType":"uint8","name":"sigV","type":"uint8"}],"name":"executeMetaTransaction","outputs":[{"internalType":"bytes","name":"","type":"bytes"}],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getChainId","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getDomainSeperator","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"user","type":"address"}],"name":"getNonce","outputs":[{"internalType":"uint256","name":"nonce","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"tokenAddress","type":"address"}],"name":"getPrice","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":"maxSaleCount","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"},{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"mintByToken","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"}],"name":"mintTo","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_baseToken","type":"string"}],"name":"setBaseTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"tokenAddress","type":"address[]"},{"internalType":"uint256[]","name":"tokenPrice","type":"uint256[]"}],"name":"setPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"whitelistAddress","type":"address[]"},{"internalType":"uint256","name":"quantity","type":"uint256"},{"internalType":"address[]","name":"tokenAddress","type":"address[]"},{"internalType":"uint256[]","name":"tokenPrice","type":"uint256[]"}],"name":"setWhiteList","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_withdrawalAddress","type":"address"}],"name":"setWithdrawalAddress","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":[],"name":"tokenIdCounter","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":[{"internalType":"address","name":"tokenAddress","type":"address"},{"internalType":"uint256","name":"amount","type":"uint256"}],"name":"withdraw","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"withdrawalAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"}]

6006805460ff191690556001600e556000600f81905560105560e0604052602760808181529062003fe860a0398051620000429160129160209091019062000292565b503480156200005057600080fd5b506040516200400f3803806200400f833981016040819052620000739162000338565b6040518060400160405280600c81526020016b50756c692052756e6e65727360a01b815250604051806040016040528060048152602001632829272960e11b815250826107db83838160009080519060200190620000d392919062000292565b508051620000e990600190602084019062000292565b50505062000106620001006200014c60201b60201c565b62000150565b600a80546001600160a01b0319166001600160a01b0384161790556200012c84620001a2565b6010555050601180546001600160a01b0319163317905550620003f99050565b3390565b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b60065460ff1615620001d15760405162461bcd60e51b8152600401620001c89062000394565b60405180910390fd5b620001dc81620001ec565b506006805460ff19166001179055565b6040518060800160405280604f815260200162003f99604f913980516020918201208251838301206040805180820190915260018152603160f81b930192909252907fc89efdaa54c0f20c7adf612882df0950f5a951637e0307cdcb4c672f298b8bc6306200025a6200028e565b6040516200027095949392919060200162000368565b60408051601f19818403018152919052805160209091012060075550565b4690565b828054620002a090620003bc565b90600052602060002090601f016020900481019282620002c457600085556200030f565b82601f10620002df57805160ff19168380011785556200030f565b828001600101855582156200030f579182015b828111156200030f578251825591602001919060010190620002f2565b506200031d92915062000321565b5090565b5b808211156200031d576000815560010162000322565b6000602082840312156200034a578081fd5b81516001600160a01b038116811462000361578182fd5b9392505050565b948552602085019390935260408401919091526001600160a01b03166060830152608082015260a00190565b6020808252600e908201526d185b1c9958591e481a5b9a5d195960921b604082015260600190565b600281046001821680620003d157607f821691505b60208210811415620003f357634e487b7160e01b600052602260045260246000fd5b50919050565b613b9080620004096000396000f3fe60806040526004361061023b5760003560e01c8063755edd171161012e578063c55dae63116100ab578063e8a3d4851161006f578063e8a3d4851461062b578063e985e9c514610640578063f2bcd02214610660578063f2fde38b14610675578063f3fef3a3146106955761023b565b8063c55dae63146105ac578063c87b56dd146105c1578063d441987d146105e1578063d547cfb714610601578063d5abeb01146106165761023b565b8063a0c1cdc3116100f2578063a0c1cdc314610517578063a0cf0aea14610537578063a22cb4651461054c578063a58dcf751461056c578063b88d4fde1461058c5761023b565b8063755edd17146104a55780638da5cb5b146104c557806395d89b41146104da57806398bdf6f5146104ef578063a0712d68146105045761023b565b806321b8092e116101bc57806341976e091161018057806341976e091461041057806342842e0e146104305780636352211e1461045057806370a0823114610470578063715018a6146104905761023b565b806321b8092e1461037b57806323b872dd1461039b5780632d0335ab146103bb57806330176e13146103db5780633408e470146103fb5761023b565b80630f403c15116102035780630f403c15146102fa5780630f7e59701461031c57806318160ddd146103315780631dff86a31461034657806320379ee5146103665761023b565b806301ffc9a71461024057806306fdde0314610276578063081812fc14610298578063095ea7b3146102c55780630c53c51c146102e7575b600080fd5b34801561024c57600080fd5b5061026061025b366004612bb3565b6106a8565b60405161026d9190612ee0565b60405180910390f35b34801561028257600080fd5b5061028b6106f0565b60405161026d9190612f36565b3480156102a457600080fd5b506102b86102b3366004612c4d565b610783565b60405161026d9190612db2565b3480156102d157600080fd5b506102e56102e0366004612a89565b6107cf565b005b61028b6102f5366004612a0e565b610867565b34801561030657600080fd5b5061030f6109e7565b60405161026d9190612eeb565b34801561032857600080fd5b5061028b6109ed565b34801561033d57600080fd5b5061030f610a0a565b34801561035257600080fd5b506102e5610361366004612b15565b610a10565b34801561037257600080fd5b5061030f610b61565b34801561038757600080fd5b506102e56103963660046128e3565b610b67565b3480156103a757600080fd5b506102e56103b6366004612937565b610c16565b3480156103c757600080fd5b5061030f6103d63660046128e3565b610c4e565b3480156103e757600080fd5b506102e56103f6366004612c07565b610c69565b34801561040757600080fd5b5061030f610cbf565b34801561041c57600080fd5b5061030f61042b3660046128e3565b610cc3565b34801561043c57600080fd5b506102e561044b366004612937565b610d3c565b34801561045c57600080fd5b506102b861046b366004612c4d565b610d57565b34801561047c57600080fd5b5061030f61048b3660046128e3565b610d8c565b34801561049c57600080fd5b506102e5610dd0565b3480156104b157600080fd5b506102e56104c03660046128e3565b610e1b565b3480156104d157600080fd5b506102b8610f03565b3480156104e657600080fd5b5061028b610f12565b3480156104fb57600080fd5b5061030f610f21565b6102e5610512366004612c4d565b610f27565b34801561052357600080fd5b506102e5610532366004612a89565b610f62565b34801561054357600080fd5b506102b8610f9b565b34801561055857600080fd5b506102e56105673660046129e1565b610fa0565b34801561057857600080fd5b506102e5610587366004612ab4565b610fb2565b34801561059857600080fd5b506102e56105a7366004612977565b61108f565b3480156105b857600080fd5b5061028b6110ce565b3480156105cd57600080fd5b5061028b6105dc366004612c4d565b61115c565b3480156105ed57600080fd5b506102e56105fc366004612ab4565b611196565b34801561060d57600080fd5b5061028b6113d9565b34801561062257600080fd5b5061030f6113e8565b34801561063757600080fd5b5061028b6113ee565b34801561064c57600080fd5b5061026061065b3660046128ff565b61141c565b34801561066c57600080fd5b506102b86114d2565b34801561068157600080fd5b506102e56106903660046128e3565b6114e1565b6102e56106a3366004612a89565b61154f565b60006001600160e01b031982166380ac58cd60e01b14806106d957506001600160e01b03198216635b5e139f60e01b145b806106e857506106e88261185c565b90505b919050565b6060600080546106ff90613a09565b80601f016020809104026020016040519081016040528092919081815260200182805461072b90613a09565b80156107785780601f1061074d57610100808354040283529160200191610778565b820191906000526020600020905b81548152906001019060200180831161075b57829003601f168201915b505050505090505b90565b600061078e82611875565b6107b35760405162461bcd60e51b81526004016107aa906135e7565b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006107da82610d57565b9050806001600160a01b0316836001600160a01b0316141561080e5760405162461bcd60e51b81526004016107aa906136a9565b806001600160a01b0316610820611892565b6001600160a01b0316148061083c575061083c8161065b611892565b6108585760405162461bcd60e51b81526004016107aa90613464565b6108628383611896565b505050565b60408051606081810183526001600160a01b038816600081815260086020908152908590205484528301529181018690526108a58782878787611904565b6108c15760405162461bcd60e51b81526004016107aa90613668565b6001600160a01b0387166000908152600860205260409020546108e59060016119aa565b6001600160a01b0388166000908152600860205260409081902091909155517f5845892132946850460bff5a0083f71031bc5bf9aadcd40f1de79423eac9b10b9061093590899033908a90612dea565b60405180910390a1600080306001600160a01b0316888a60405160200161095d929190612cf0565b60408051601f198184030181529082905261097791612cd4565b6000604051808303816000865af19150503d80600081146109b4576040519150601f19603f3d011682016040523d82523d6000602084013e6109b9565b606091505b5091509150816109db5760405162461bcd60e51b81526004016107aa906130d2565b98975050505050505050565b6107d081565b604051806040016040528060018152602001603160f81b81525081565b600f5481565b610a18611892565b6001600160a01b0316610a29610f03565b6001600160a01b031614610a4f5760405162461bcd60e51b81526004016107aa90613633565b6000845111610a705760405162461bcd60e51b81526004016107aa90612fe2565b60008311610a905760405162461bcd60e51b81526004016107aa9061380a565b610a9a8282611196565b60005b8451811015610b0d5783600b6000016000878481518110610ace57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055508080610b0590613a44565b915050610a9d565b508351610b2190600c906020870190612695565b507fffbc5c495b9a7f2e0a36554d774ddb6abf64012bb8e761c9f77f83d7340d58a48484604051610b53929190612ebe565b60405180910390a150505050565b60075490565b610b6f611892565b6001600160a01b0316610b80610f03565b6001600160a01b031614610ba65760405162461bcd60e51b81526004016107aa90613633565b6001600160a01b038116610bcc5760405162461bcd60e51b81526004016107aa90613772565b601180546001600160a01b0319166001600160a01b0383169081179091556040517f38619916fc3918a525f6345aee2ffa28a377b8c1d39486dcad746990c731f5de90600090a250565b610c27610c21611892565b826119bd565b610c435760405162461bcd60e51b81526004016107aa906136ea565b610862838383611a3a565b6001600160a01b031660009081526008602052604090205490565b610c71611892565b6001600160a01b0316610c82610f03565b6001600160a01b031614610ca85760405162461bcd60e51b81526004016107aa90613633565b8051610cbb9060129060208401906126fa565b5050565b4690565b60006001600160a01b038216610ceb5760405162461bcd60e51b81526004016107aa90613011565b6001600160a01b0382166000908152600d6020526040902054610d205760405162461bcd60e51b81526004016107aa906131d6565b506001600160a01b03166000908152600d602052604090205490565b6108628383836040518060200160405280600081525061108f565b6000818152600260205260408120546001600160a01b0316806106e85760405162461bcd60e51b81526004016107aa9061353b565b60006001600160a01b038216610db45760405162461bcd60e51b81526004016107aa906134c1565b506001600160a01b031660009081526003602052604090205490565b610dd8611892565b6001600160a01b0316610de9610f03565b6001600160a01b031614610e0f5760405162461bcd60e51b81526004016107aa90613633565b610e196000611b6d565b565b610e23611892565b6001600160a01b0316610e34610f03565b6001600160a01b031614610e5a5760405162461bcd60e51b81526004016107aa90613633565b6010541580610e6c5750600f54601054115b610e885760405162461bcd60e51b81526004016107aa90612fb5565b600e805460009182610e9983613a44565b919050559050610ea98282611bbf565b600f8054906000610eb983613a44565b9190505550816001600160a01b03167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688582604051610ef79190612eeb565b60405180910390a25050565b6009546001600160a01b031690565b6060600180546106ff90613a09565b600e5481565b6107d081600f54610f38919061397b565b1115610f565760405162461bcd60e51b81526004016107aa906137a9565b610f5f81611bd9565b50565b6107d081600f54610f73919061397b565b1115610f915760405162461bcd60e51b81526004016107aa906137a9565b610cbb8282611cb8565b600181565b610cbb610fab611892565b8383611e7b565b610fba611892565b6001600160a01b0316610fcb610f03565b6001600160a01b031614610ff15760405162461bcd60e51b81526004016107aa90613633565b600c546110105760405162461bcd60e51b81526004016107aa90613854565b60005b600c54811015611078576000600b600101828154811061104357634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b03168252600b90526040812055508061107081613a44565b915050611013565b50611085600c600061276e565b610cbb8282611196565b6110a061109a611892565b836119bd565b6110bc5760405162461bcd60e51b81526004016107aa906136ea565b6110c884848484611f1e565b50505050565b601280546110db90613a09565b80601f016020809104026020016040519081016040528092919081815260200182805461110790613a09565b80156111545780601f1061112957610100808354040283529160200191611154565b820191906000526020600020905b81548152906001019060200180831161113757829003601f168201915b505050505081565b60606111666113d9565b61116f83611f51565b604051602001611180929190612d27565b6040516020818303038152906040529050919050565b61119e611892565b6001600160a01b03166111af610f03565b6001600160a01b0316146111d55760405162461bcd60e51b81526004016107aa90613633565b60008251116111f65760405162461bcd60e51b81526004016107aa9061350b565b60008151116112175760405162461bcd60e51b81526004016107aa90613584565b81518151146112385760405162461bcd60e51b81526004016107aa906138f1565b6000805b835181101561129e5760016001600160a01b031684828151811061127057634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b0316141561128c57600191505b8061129681613a44565b91505061123c565b50806112bc5760405162461bcd60e51b81526004016107aa906138a4565b60005b835181101561139a5760008382815181106112ea57634e487b7160e01b600052603260045260246000fd5b60200260200101511161130f5760405162461bcd60e51b81526004016107aa9061380a565b82818151811061132f57634e487b7160e01b600052603260045260246000fd5b6020026020010151600d600086848151811061135b57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002081905550808061139290613a44565b9150506112bf565b507fce51bc3b5085c49a50fd6dc08aeaaaef763f7c7d9ab2b3a3d60d9061751e657b83836040516113cc929190612e75565b60405180910390a1505050565b6060601280546106ff90613a09565b60105481565b60606113f86113d9565b6040516020016114089190612d66565b604051602081830303815290604052905090565b600a5460405163c455279160e01b81526000916001600160a01b039081169190841690829063c455279190611455908890600401612db2565b60206040518083038186803b15801561146d57600080fd5b505afa158015611481573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114a59190612beb565b6001600160a01b031614156114be5760019150506114cc565b6114c88484612074565b9150505b92915050565b6011546001600160a01b031681565b6114e9611892565b6001600160a01b03166114fa610f03565b6001600160a01b0316146115205760405162461bcd60e51b81526004016107aa90613633565b6001600160a01b0381166115465760405162461bcd60e51b81526004016107aa9061308c565b610f5f81611b6d565b611557611892565b6001600160a01b0316611568610f03565b6001600160a01b03161461158e5760405162461bcd60e51b81526004016107aa90613633565b600081116115ae5760405162461bcd60e51b81526004016107aa906131ae565b6011546000906115c6906001600160a01b03166120a2565b90506001600160a01b0383166001141561167a578015611626576011546040805160048152602481019091526020810180516001600160e01b031663835c19f360e01b179052611620916001600160a01b031690846120b1565b5061163c565b60115461163c906001600160a01b0316836120d7565b60115460405183916001600160a01b0316907f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a942436490600090a350610cbb565b8281156117915760115460405163095ea7b360e01b81526000916001600160a01b038085169263095ea7b3926116b69216908890600401612e5c565b602060405180830381600087803b1580156116d057600080fd5b505af11580156116e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117089190612b97565b9050806117275760405162461bcd60e51b81526004016107aa906133e8565b601154604051635259b9ab60e01b81526001600160a01b0390911690635259b9ab906117599085908890600401612e5c565b600060405180830381600087803b15801561177357600080fd5b505af1158015611787573d6000803e3d6000fd5b5050505050611819565b60115460405163a9059cbb60e01b81526001600160a01b038381169263a9059cbb926117c592909116908790600401612e5c565b602060405180830381600087803b1580156117df57600080fd5b505af11580156117f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118179190612b97565b505b60115460405184916001600160a01b03808516929116907f70082d08c003c5341f2401bec1c2ae1dbcdc29ae17e9cc5633fa617caa8acd4c90600090a450505050565b6001600160e01b031981166301ffc9a760e01b14919050565b6000908152600260205260409020546001600160a01b0316151590565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906118cb82610d57565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006001600160a01b03861661192c5760405162461bcd60e51b81526004016107aa9061341f565b600161193f61193a87612173565b6121d1565b8386866040516000815260200160405260405161195f9493929190612f18565b6020604051602081039080840390855afa158015611981573d6000803e3d6000fd5b505050602060405103516001600160a01b0316866001600160a01b031614905095945050505050565b60006119b6828461397b565b9392505050565b60006119c882611875565b6119e45760405162461bcd60e51b81526004016107aa9061339c565b60006119ef83610d57565b9050806001600160a01b0316846001600160a01b03161480611a2a5750836001600160a01b0316611a1f84610783565b6001600160a01b0316145b806114c857506114c8818561141c565b826001600160a01b0316611a4d82610d57565b6001600160a01b031614611a735760405162461bcd60e51b81526004016107aa90613132565b6001600160a01b038216611a995760405162461bcd60e51b81526004016107aa90613247565b611aa4838383610862565b611aaf600082611896565b6001600160a01b0383166000908152600360205260408120805460019290611ad89084906139c6565b90915550506001600160a01b0382166000908152600360205260408120805460019290611b0690849061397b565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4610862838383610862565b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b610cbb8282604051806020016040528060008152506121ed565b601054600f54611be9908361397b565b1115611c075760405162461bcd60e51b81526004016107aa90612fb5565b611c12600182612220565b611c23611c1d611892565b82612298565b80600f6000828254611c35919061397b565b90915550600090505b81811015610cbb57611c59611c51611892565b600e54611bbf565b600e805433917f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688591906000611c8d83613a44565b91905055604051611c9e9190612eeb565b60405180910390a280611cb081613a44565b915050611c3e565b601054600f54611cc8908361397b565b1115611ce65760405162461bcd60e51b81526004016107aa90612fb5565b6001600160a01b0382166000908152600d6020526040902054611d1b5760405162461bcd60e51b81526004016107aa906137d3565b611d26611c1d611892565b6001600160a01b0382166000818152600d6020526040812054916323b872dd611d4d61233e565b30611d5886886139a7565b6040518463ffffffff1660e01b8152600401611d7693929190612dc6565b602060405180830381600087803b158015611d9057600080fd5b505af1158015611da4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dc89190612b97565b905080611de75760405162461bcd60e51b81526004016107aa90613109565b82600f6000828254611df9919061397b565b90915550600090505b83811015611e7457611e15611c51611892565b600e805433917f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688591906000611e4983613a44565b91905055604051611e5a9190612eeb565b60405180910390a280611e6c81613a44565b915050611e02565b5050505050565b816001600160a01b0316836001600160a01b03161415611ead5760405162461bcd60e51b81526004016107aa9061328b565b6001600160a01b0383811660008181526005602090815260408083209487168084529490915290819020805460ff1916851515179055517f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3190611f11908590612ee0565b60405180910390a3505050565b611f29848484611a3a565b611f358484848461239a565b6110c85760405162461bcd60e51b81526004016107aa9061303a565b606081611f7657506040805180820190915260018152600360fc1b60208201526106eb565b8160005b8115611fa05780611f8a81613a44565b9150611f999050600a83613993565b9150611f7a565b60008167ffffffffffffffff811115611fc957634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611ff3576020820181803683370190505b5090505b841561206c576120086001836139c6565b9150612015600a86613a5f565b61202090603061397b565b60f81b81838151811061204357634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350612065600a86613993565b9450611ff7565b949350505050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6001600160a01b03163b151590565b606061206c848484604051806060016040528060298152602001613b32602991396124b5565b804710156120f75760405162461bcd60e51b81526004016107aa9061331f565b6000826001600160a01b03168260405161211090610780565b60006040518083038185875af1925050503d806000811461214d576040519150601f19603f3d011682016040523d82523d6000602084013e612152565b606091505b50509050806108625760405162461bcd60e51b81526004016107aa906132c2565b6000604051806080016040528060438152602001613aef60439139805160209182012083518483015160408087015180519086012090516121b49501612ef4565b604051602081830303815290604052805190602001209050919050565b60006121db610b61565b826040516020016121b4929190612d97565b6121f78383612575565b612204600084848461239a565b6108625760405162461bcd60e51b81526004016107aa9061303a565b6001600160a01b0382166000908152600d60205260409020546122555760405162461bcd60e51b81526004016107aa906137d3565b6001600160a01b0382166000908152600d60205260409020546122799082906139a7565b341015610cbb5760405162461bcd60e51b81526004016107aa90612f80565b600c5415610cbb576001600160a01b0382166000908152600b60205260409020546122d55760405162461bcd60e51b81526004016107aa90612f49565b6001600160a01b0382166000908152600b602052604090205481111561230d5760405162461bcd60e51b81526004016107aa90613204565b6001600160a01b0382166000908152600b6020526040812080548392906123359084906139c6565b90915550505050565b60003330141561239557600080368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050503601516001600160a01b031691506107809050565b503390565b60006123ae846001600160a01b03166120a2565b156124aa57836001600160a01b031663150b7a026123ca611892565b8786866040518563ffffffff1660e01b81526004016123ec9493929190612e1f565b602060405180830381600087803b15801561240657600080fd5b505af1925050508015612436575060408051601f3d908101601f1916820190925261243391810190612bcf565b60015b612490573d808015612464576040519150601f19603f3d011682016040523d82523d6000602084013e612469565b606091505b5080516124885760405162461bcd60e51b81526004016107aa9061303a565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061206c565b506001949350505050565b6060824710156124d75760405162461bcd60e51b81526004016107aa90613356565b6124e0856120a2565b6124fc5760405162461bcd60e51b81526004016107aa9061373b565b600080866001600160a01b031685876040516125189190612cd4565b60006040518083038185875af1925050503d8060008114612555576040519150601f19603f3d011682016040523d82523d6000602084013e61255a565b606091505b509150915061256a82828661265c565b979650505050505050565b6001600160a01b03821661259b5760405162461bcd60e51b81526004016107aa906135b2565b6125a481611875565b156125c15760405162461bcd60e51b81526004016107aa90613177565b6125cd60008383610862565b6001600160a01b03821660009081526003602052604081208054600192906125f690849061397b565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4610cbb60008383610862565b6060831561266b5750816119b6565b82511561267b5782518084602001fd5b8160405162461bcd60e51b81526004016107aa9190612f36565b8280548282559060005260206000209081019282156126ea579160200282015b828111156126ea57825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906126b5565b506126f6929150612788565b5090565b82805461270690613a09565b90600052602060002090601f01602090048101928261272857600085556126ea565b82601f1061274157805160ff19168380011785556126ea565b828001600101855582156126ea579182015b828111156126ea578251825591602001919060010190612753565b5080546000825590600052602060002090810190610f5f91905b5b808211156126f65760008155600101612789565b600067ffffffffffffffff8311156127b7576127b7613a9f565b6127ca601f8401601f1916602001613926565b90508281528383830111156127de57600080fd5b828260208301376000602084830101529392505050565b600082601f830112612805578081fd5b8135602061281a61281583613957565b613926565b8281528181019085830183850287018401881015612836578586fd5b855b8581101561285d57813561284b81613ab5565b84529284019290840190600101612838565b5090979650505050505050565b600082601f83011261287a578081fd5b8135602061288a61281583613957565b82815281810190858301838502870184018810156128a6578586fd5b855b8581101561285d578135845292840192908401906001016128a8565b600082601f8301126128d4578081fd5b6119b68383356020850161279d565b6000602082840312156128f4578081fd5b81356119b681613ab5565b60008060408385031215612911578081fd5b823561291c81613ab5565b9150602083013561292c81613ab5565b809150509250929050565b60008060006060848603121561294b578081fd5b833561295681613ab5565b9250602084013561296681613ab5565b929592945050506040919091013590565b6000806000806080858703121561298c578081fd5b843561299781613ab5565b935060208501356129a781613ab5565b925060408501359150606085013567ffffffffffffffff8111156129c9578182fd5b6129d5878288016128c4565b91505092959194509250565b600080604083850312156129f3578182fd5b82356129fe81613ab5565b9150602083013561292c81613aca565b600080600080600060a08688031215612a25578081fd5b8535612a3081613ab5565b9450602086013567ffffffffffffffff811115612a4b578182fd5b612a57888289016128c4565b9450506040860135925060608601359150608086013560ff81168114612a7b578182fd5b809150509295509295909350565b60008060408385031215612a9b578182fd5b8235612aa681613ab5565b946020939093013593505050565b60008060408385031215612ac6578182fd5b823567ffffffffffffffff80821115612add578384fd5b612ae9868387016127f5565b93506020850135915080821115612afe578283fd5b50612b0b8582860161286a565b9150509250929050565b60008060008060808587031215612b2a578182fd5b843567ffffffffffffffff80821115612b41578384fd5b612b4d888389016127f5565b9550602087013594506040870135915080821115612b69578384fd5b612b75888389016127f5565b93506060870135915080821115612b8a578283fd5b506129d58782880161286a565b600060208284031215612ba8578081fd5b81516119b681613aca565b600060208284031215612bc4578081fd5b81356119b681613ad8565b600060208284031215612be0578081fd5b81516119b681613ad8565b600060208284031215612bfc578081fd5b81516119b681613ab5565b600060208284031215612c18578081fd5b813567ffffffffffffffff811115612c2e578182fd5b8201601f81018413612c3e578182fd5b6114c88482356020840161279d565b600060208284031215612c5e578081fd5b5035919050565b6000815180845260208085019450808401835b83811015612c9d5781516001600160a01b031687529582019590820190600101612c78565b509495945050505050565b60008151808452612cc08160208601602086016139dd565b601f01601f19169290920160200192915050565b60008251612ce68184602087016139dd565b9190910192915050565b60008351612d028184602088016139dd565b60609390931b6bffffffffffffffffffffffff19169190920190815260140192915050565b60008351612d398184602088016139dd565b835190830190612d4d8183602088016139dd565b64173539b7b760d91b9101908152600501949350505050565b60008251612d788184602087016139dd565b6c31b7b73a3930b1ba173539b7b760991b920191825250600d01919050565b61190160f01b81526002810192909252602282015260420190565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03848116825283166020820152606060408201819052600090612e1690830184612ca8565b95945050505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612e5290830184612ca8565b9695505050505050565b6001600160a01b03929092168252602082015260400190565b600060408252612e886040830185612c65565b828103602084810191909152845180835285820192820190845b8181101561285d57845183529383019391830191600101612ea2565b600060408252612ed16040830185612c65565b90508260208301529392505050565b901515815260200190565b90815260200190565b93845260208401929092526001600160a01b03166040830152606082015260800190565b93845260ff9290921660208401526040830152606082015260800190565b6000602082526119b66020830184612ca8565b6020808252601f908201527f43757272656e742075736572206973206e6f742077686974656c697374656400604082015260600190565b6020808252818101527f496e73756666696369656e7420616d6f756e742c2063616e6e6f74206d696e74604082015260600190565b60208082526013908201527213585e081cdd5c1c1b1e48195e18d959591959606a1b604082015260600190565b602080825260159082015274139bc81859191c995cdcd95cc81a5b9c1d5d1d1959605a1b604082015260600190565b6020808252600f908201526e496e76616c6964206164647265737360881b604082015260600190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252601c908201527f46756e6374696f6e2063616c6c206e6f74207375636365737366756c00000000604082015260600190565b6020808252600f908201526e151c985b9cd9995c8819985a5b1959608a1b604082015260600190565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b6020808252601c908201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604082015260600190565b6020808252600e908201526d125b9d985b1a5908185b5bdd5b9d60921b604082015260600190565b602080825260149082015273141c9a58d9481a5cc81b9bdd081e595d081cd95d60621b604082015260600190565b60208082526023908201527f43757272656e742075736572206578636565647320616c6c6f7761626c65206d6040820152621a5b9d60ea1b606082015260800190565b60208082526024908201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526019908201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604082015260600190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260408201527f6563697069656e74206d61792068617665207265766572746564000000000000606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6040820152651c8818d85b1b60d21b606082015260800190565b6020808252602c908201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252601c908201527f4661696c656420746f20617070726f7665207769746864726177616c00000000604082015260600190565b60208082526025908201527f4e61746976654d6574615472616e73616374696f6e3a20494e56414c49445f5360408201526424a3a722a960d91b606082015260800190565b60208082526038908201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760408201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606082015260800190565b6020808252602a908201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604082015269726f206164647265737360b01b606082015260800190565b602080825260169082015275546f6b656e206164647265737320697320656d70747960501b604082015260600190565b60208082526029908201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460408201526832b73a103a37b5b2b760b91b606082015260800190565b602080825260149082015273546f6b656e20707269636520697320656d70747960601b604082015260600190565b6020808252818101527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b6020808252602c908201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526021908201527f5369676e657220616e64207369676e617475726520646f206e6f74206d6174636040820152600d60fb1b606082015260800190565b60208082526021908201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656040820152603960f91b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252601a908201527f496e76616c6964207769746864726177616c2061646472657373000000000000604082015260600190565b60208082526010908201526f13585e081cd85b19481c995858da195960821b604082015260600190565b6020808252601c908201527f5072696365206973206e6f742073657420666f72206d696e74696e6700000000604082015260600190565b6020808252602a908201527f496e76616c6964207175616e746974792c2073686f756c6420626520677265616040820152690746572207468616e20360b41b606082015260800190565b60208082526030908201527f4572726f722063616e6e6f7420636c6f73652c204e6f2057686974656c69737460408201526f081859191c995cdcd95cc8185919195960821b606082015260800190565b6020808252602d908201527f4572726f722c20707269636520646f6573206e6f7420636f6e7461696e206e6160408201526c746976652063757272656e637960981b606082015260800190565b6020808252818101527f507269636520616e64206164647265737320646f6573206e6f74206d61746368604082015260600190565b604051601f8201601f1916810167ffffffffffffffff8111828210171561394f5761394f613a9f565b604052919050565b600067ffffffffffffffff82111561397157613971613a9f565b5060209081020190565b6000821982111561398e5761398e613a73565b500190565b6000826139a2576139a2613a89565b500490565b60008160001904831182151516156139c1576139c1613a73565b500290565b6000828210156139d8576139d8613a73565b500390565b60005b838110156139f85781810151838201526020016139e0565b838111156110c85750506000910152565b600281046001821680613a1d57607f821691505b60208210811415613a3e57634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415613a5857613a58613a73565b5060010190565b600082613a6e57613a6e613a89565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610f5f57600080fd5b8015158114610f5f57600080fd5b6001600160e01b031981168114610f5f57600080fdfe4d6574615472616e73616374696f6e2875696e74323536206e6f6e63652c616464726573732066726f6d2c62797465732066756e6374696f6e5369676e617475726529416464726573733a206c6f772d6c6576656c2063616c6c20776974682076616c7565206661696c6564a264697066735822122004b963a2dc9ca7050467442e0de18d54b11d7551453e15be483ab36053fae2d564736f6c63430008010033454950373132446f6d61696e28737472696e67206e616d652c737472696e672076657273696f6e2c6164647265737320766572696679696e67436f6e74726163742c627974657333322073616c742968747470733a2f2f72756e6e6572732e70756c69746f6b656e2e6e65742f6d657461646174612f000000000000000000000000a5409ec958c83c3f309868babaca7c86dcb077c1

Deployed Bytecode

0x60806040526004361061023b5760003560e01c8063755edd171161012e578063c55dae63116100ab578063e8a3d4851161006f578063e8a3d4851461062b578063e985e9c514610640578063f2bcd02214610660578063f2fde38b14610675578063f3fef3a3146106955761023b565b8063c55dae63146105ac578063c87b56dd146105c1578063d441987d146105e1578063d547cfb714610601578063d5abeb01146106165761023b565b8063a0c1cdc3116100f2578063a0c1cdc314610517578063a0cf0aea14610537578063a22cb4651461054c578063a58dcf751461056c578063b88d4fde1461058c5761023b565b8063755edd17146104a55780638da5cb5b146104c557806395d89b41146104da57806398bdf6f5146104ef578063a0712d68146105045761023b565b806321b8092e116101bc57806341976e091161018057806341976e091461041057806342842e0e146104305780636352211e1461045057806370a0823114610470578063715018a6146104905761023b565b806321b8092e1461037b57806323b872dd1461039b5780632d0335ab146103bb57806330176e13146103db5780633408e470146103fb5761023b565b80630f403c15116102035780630f403c15146102fa5780630f7e59701461031c57806318160ddd146103315780631dff86a31461034657806320379ee5146103665761023b565b806301ffc9a71461024057806306fdde0314610276578063081812fc14610298578063095ea7b3146102c55780630c53c51c146102e7575b600080fd5b34801561024c57600080fd5b5061026061025b366004612bb3565b6106a8565b60405161026d9190612ee0565b60405180910390f35b34801561028257600080fd5b5061028b6106f0565b60405161026d9190612f36565b3480156102a457600080fd5b506102b86102b3366004612c4d565b610783565b60405161026d9190612db2565b3480156102d157600080fd5b506102e56102e0366004612a89565b6107cf565b005b61028b6102f5366004612a0e565b610867565b34801561030657600080fd5b5061030f6109e7565b60405161026d9190612eeb565b34801561032857600080fd5b5061028b6109ed565b34801561033d57600080fd5b5061030f610a0a565b34801561035257600080fd5b506102e5610361366004612b15565b610a10565b34801561037257600080fd5b5061030f610b61565b34801561038757600080fd5b506102e56103963660046128e3565b610b67565b3480156103a757600080fd5b506102e56103b6366004612937565b610c16565b3480156103c757600080fd5b5061030f6103d63660046128e3565b610c4e565b3480156103e757600080fd5b506102e56103f6366004612c07565b610c69565b34801561040757600080fd5b5061030f610cbf565b34801561041c57600080fd5b5061030f61042b3660046128e3565b610cc3565b34801561043c57600080fd5b506102e561044b366004612937565b610d3c565b34801561045c57600080fd5b506102b861046b366004612c4d565b610d57565b34801561047c57600080fd5b5061030f61048b3660046128e3565b610d8c565b34801561049c57600080fd5b506102e5610dd0565b3480156104b157600080fd5b506102e56104c03660046128e3565b610e1b565b3480156104d157600080fd5b506102b8610f03565b3480156104e657600080fd5b5061028b610f12565b3480156104fb57600080fd5b5061030f610f21565b6102e5610512366004612c4d565b610f27565b34801561052357600080fd5b506102e5610532366004612a89565b610f62565b34801561054357600080fd5b506102b8610f9b565b34801561055857600080fd5b506102e56105673660046129e1565b610fa0565b34801561057857600080fd5b506102e5610587366004612ab4565b610fb2565b34801561059857600080fd5b506102e56105a7366004612977565b61108f565b3480156105b857600080fd5b5061028b6110ce565b3480156105cd57600080fd5b5061028b6105dc366004612c4d565b61115c565b3480156105ed57600080fd5b506102e56105fc366004612ab4565b611196565b34801561060d57600080fd5b5061028b6113d9565b34801561062257600080fd5b5061030f6113e8565b34801561063757600080fd5b5061028b6113ee565b34801561064c57600080fd5b5061026061065b3660046128ff565b61141c565b34801561066c57600080fd5b506102b86114d2565b34801561068157600080fd5b506102e56106903660046128e3565b6114e1565b6102e56106a3366004612a89565b61154f565b60006001600160e01b031982166380ac58cd60e01b14806106d957506001600160e01b03198216635b5e139f60e01b145b806106e857506106e88261185c565b90505b919050565b6060600080546106ff90613a09565b80601f016020809104026020016040519081016040528092919081815260200182805461072b90613a09565b80156107785780601f1061074d57610100808354040283529160200191610778565b820191906000526020600020905b81548152906001019060200180831161075b57829003601f168201915b505050505090505b90565b600061078e82611875565b6107b35760405162461bcd60e51b81526004016107aa906135e7565b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006107da82610d57565b9050806001600160a01b0316836001600160a01b0316141561080e5760405162461bcd60e51b81526004016107aa906136a9565b806001600160a01b0316610820611892565b6001600160a01b0316148061083c575061083c8161065b611892565b6108585760405162461bcd60e51b81526004016107aa90613464565b6108628383611896565b505050565b60408051606081810183526001600160a01b038816600081815260086020908152908590205484528301529181018690526108a58782878787611904565b6108c15760405162461bcd60e51b81526004016107aa90613668565b6001600160a01b0387166000908152600860205260409020546108e59060016119aa565b6001600160a01b0388166000908152600860205260409081902091909155517f5845892132946850460bff5a0083f71031bc5bf9aadcd40f1de79423eac9b10b9061093590899033908a90612dea565b60405180910390a1600080306001600160a01b0316888a60405160200161095d929190612cf0565b60408051601f198184030181529082905261097791612cd4565b6000604051808303816000865af19150503d80600081146109b4576040519150601f19603f3d011682016040523d82523d6000602084013e6109b9565b606091505b5091509150816109db5760405162461bcd60e51b81526004016107aa906130d2565b98975050505050505050565b6107d081565b604051806040016040528060018152602001603160f81b81525081565b600f5481565b610a18611892565b6001600160a01b0316610a29610f03565b6001600160a01b031614610a4f5760405162461bcd60e51b81526004016107aa90613633565b6000845111610a705760405162461bcd60e51b81526004016107aa90612fe2565b60008311610a905760405162461bcd60e51b81526004016107aa9061380a565b610a9a8282611196565b60005b8451811015610b0d5783600b6000016000878481518110610ace57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166001600160a01b03168152602001908152602001600020819055508080610b0590613a44565b915050610a9d565b508351610b2190600c906020870190612695565b507fffbc5c495b9a7f2e0a36554d774ddb6abf64012bb8e761c9f77f83d7340d58a48484604051610b53929190612ebe565b60405180910390a150505050565b60075490565b610b6f611892565b6001600160a01b0316610b80610f03565b6001600160a01b031614610ba65760405162461bcd60e51b81526004016107aa90613633565b6001600160a01b038116610bcc5760405162461bcd60e51b81526004016107aa90613772565b601180546001600160a01b0319166001600160a01b0383169081179091556040517f38619916fc3918a525f6345aee2ffa28a377b8c1d39486dcad746990c731f5de90600090a250565b610c27610c21611892565b826119bd565b610c435760405162461bcd60e51b81526004016107aa906136ea565b610862838383611a3a565b6001600160a01b031660009081526008602052604090205490565b610c71611892565b6001600160a01b0316610c82610f03565b6001600160a01b031614610ca85760405162461bcd60e51b81526004016107aa90613633565b8051610cbb9060129060208401906126fa565b5050565b4690565b60006001600160a01b038216610ceb5760405162461bcd60e51b81526004016107aa90613011565b6001600160a01b0382166000908152600d6020526040902054610d205760405162461bcd60e51b81526004016107aa906131d6565b506001600160a01b03166000908152600d602052604090205490565b6108628383836040518060200160405280600081525061108f565b6000818152600260205260408120546001600160a01b0316806106e85760405162461bcd60e51b81526004016107aa9061353b565b60006001600160a01b038216610db45760405162461bcd60e51b81526004016107aa906134c1565b506001600160a01b031660009081526003602052604090205490565b610dd8611892565b6001600160a01b0316610de9610f03565b6001600160a01b031614610e0f5760405162461bcd60e51b81526004016107aa90613633565b610e196000611b6d565b565b610e23611892565b6001600160a01b0316610e34610f03565b6001600160a01b031614610e5a5760405162461bcd60e51b81526004016107aa90613633565b6010541580610e6c5750600f54601054115b610e885760405162461bcd60e51b81526004016107aa90612fb5565b600e805460009182610e9983613a44565b919050559050610ea98282611bbf565b600f8054906000610eb983613a44565b9190505550816001600160a01b03167f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688582604051610ef79190612eeb565b60405180910390a25050565b6009546001600160a01b031690565b6060600180546106ff90613a09565b600e5481565b6107d081600f54610f38919061397b565b1115610f565760405162461bcd60e51b81526004016107aa906137a9565b610f5f81611bd9565b50565b6107d081600f54610f73919061397b565b1115610f915760405162461bcd60e51b81526004016107aa906137a9565b610cbb8282611cb8565b600181565b610cbb610fab611892565b8383611e7b565b610fba611892565b6001600160a01b0316610fcb610f03565b6001600160a01b031614610ff15760405162461bcd60e51b81526004016107aa90613633565b600c546110105760405162461bcd60e51b81526004016107aa90613854565b60005b600c54811015611078576000600b600101828154811061104357634e487b7160e01b600052603260045260246000fd5b60009182526020808320909101546001600160a01b03168252600b90526040812055508061107081613a44565b915050611013565b50611085600c600061276e565b610cbb8282611196565b6110a061109a611892565b836119bd565b6110bc5760405162461bcd60e51b81526004016107aa906136ea565b6110c884848484611f1e565b50505050565b601280546110db90613a09565b80601f016020809104026020016040519081016040528092919081815260200182805461110790613a09565b80156111545780601f1061112957610100808354040283529160200191611154565b820191906000526020600020905b81548152906001019060200180831161113757829003601f168201915b505050505081565b60606111666113d9565b61116f83611f51565b604051602001611180929190612d27565b6040516020818303038152906040529050919050565b61119e611892565b6001600160a01b03166111af610f03565b6001600160a01b0316146111d55760405162461bcd60e51b81526004016107aa90613633565b60008251116111f65760405162461bcd60e51b81526004016107aa9061350b565b60008151116112175760405162461bcd60e51b81526004016107aa90613584565b81518151146112385760405162461bcd60e51b81526004016107aa906138f1565b6000805b835181101561129e5760016001600160a01b031684828151811061127057634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b0316141561128c57600191505b8061129681613a44565b91505061123c565b50806112bc5760405162461bcd60e51b81526004016107aa906138a4565b60005b835181101561139a5760008382815181106112ea57634e487b7160e01b600052603260045260246000fd5b60200260200101511161130f5760405162461bcd60e51b81526004016107aa9061380a565b82818151811061132f57634e487b7160e01b600052603260045260246000fd5b6020026020010151600d600086848151811061135b57634e487b7160e01b600052603260045260246000fd5b60200260200101516001600160a01b03166001600160a01b0316815260200190815260200160002081905550808061139290613a44565b9150506112bf565b507fce51bc3b5085c49a50fd6dc08aeaaaef763f7c7d9ab2b3a3d60d9061751e657b83836040516113cc929190612e75565b60405180910390a1505050565b6060601280546106ff90613a09565b60105481565b60606113f86113d9565b6040516020016114089190612d66565b604051602081830303815290604052905090565b600a5460405163c455279160e01b81526000916001600160a01b039081169190841690829063c455279190611455908890600401612db2565b60206040518083038186803b15801561146d57600080fd5b505afa158015611481573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114a59190612beb565b6001600160a01b031614156114be5760019150506114cc565b6114c88484612074565b9150505b92915050565b6011546001600160a01b031681565b6114e9611892565b6001600160a01b03166114fa610f03565b6001600160a01b0316146115205760405162461bcd60e51b81526004016107aa90613633565b6001600160a01b0381166115465760405162461bcd60e51b81526004016107aa9061308c565b610f5f81611b6d565b611557611892565b6001600160a01b0316611568610f03565b6001600160a01b03161461158e5760405162461bcd60e51b81526004016107aa90613633565b600081116115ae5760405162461bcd60e51b81526004016107aa906131ae565b6011546000906115c6906001600160a01b03166120a2565b90506001600160a01b0383166001141561167a578015611626576011546040805160048152602481019091526020810180516001600160e01b031663835c19f360e01b179052611620916001600160a01b031690846120b1565b5061163c565b60115461163c906001600160a01b0316836120d7565b60115460405183916001600160a01b0316907f884edad9ce6fa2440d8a54cc123490eb96d2768479d49ff9c7366125a942436490600090a350610cbb565b8281156117915760115460405163095ea7b360e01b81526000916001600160a01b038085169263095ea7b3926116b69216908890600401612e5c565b602060405180830381600087803b1580156116d057600080fd5b505af11580156116e4573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906117089190612b97565b9050806117275760405162461bcd60e51b81526004016107aa906133e8565b601154604051635259b9ab60e01b81526001600160a01b0390911690635259b9ab906117599085908890600401612e5c565b600060405180830381600087803b15801561177357600080fd5b505af1158015611787573d6000803e3d6000fd5b5050505050611819565b60115460405163a9059cbb60e01b81526001600160a01b038381169263a9059cbb926117c592909116908790600401612e5c565b602060405180830381600087803b1580156117df57600080fd5b505af11580156117f3573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906118179190612b97565b505b60115460405184916001600160a01b03808516929116907f70082d08c003c5341f2401bec1c2ae1dbcdc29ae17e9cc5633fa617caa8acd4c90600090a450505050565b6001600160e01b031981166301ffc9a760e01b14919050565b6000908152600260205260409020546001600160a01b0316151590565b3390565b600081815260046020526040902080546001600160a01b0319166001600160a01b03841690811790915581906118cb82610d57565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006001600160a01b03861661192c5760405162461bcd60e51b81526004016107aa9061341f565b600161193f61193a87612173565b6121d1565b8386866040516000815260200160405260405161195f9493929190612f18565b6020604051602081039080840390855afa158015611981573d6000803e3d6000fd5b505050602060405103516001600160a01b0316866001600160a01b031614905095945050505050565b60006119b6828461397b565b9392505050565b60006119c882611875565b6119e45760405162461bcd60e51b81526004016107aa9061339c565b60006119ef83610d57565b9050806001600160a01b0316846001600160a01b03161480611a2a5750836001600160a01b0316611a1f84610783565b6001600160a01b0316145b806114c857506114c8818561141c565b826001600160a01b0316611a4d82610d57565b6001600160a01b031614611a735760405162461bcd60e51b81526004016107aa90613132565b6001600160a01b038216611a995760405162461bcd60e51b81526004016107aa90613247565b611aa4838383610862565b611aaf600082611896565b6001600160a01b0383166000908152600360205260408120805460019290611ad89084906139c6565b90915550506001600160a01b0382166000908152600360205260408120805460019290611b0690849061397b565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4610862838383610862565b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b610cbb8282604051806020016040528060008152506121ed565b601054600f54611be9908361397b565b1115611c075760405162461bcd60e51b81526004016107aa90612fb5565b611c12600182612220565b611c23611c1d611892565b82612298565b80600f6000828254611c35919061397b565b90915550600090505b81811015610cbb57611c59611c51611892565b600e54611bbf565b600e805433917f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688591906000611c8d83613a44565b91905055604051611c9e9190612eeb565b60405180910390a280611cb081613a44565b915050611c3e565b601054600f54611cc8908361397b565b1115611ce65760405162461bcd60e51b81526004016107aa90612fb5565b6001600160a01b0382166000908152600d6020526040902054611d1b5760405162461bcd60e51b81526004016107aa906137d3565b611d26611c1d611892565b6001600160a01b0382166000818152600d6020526040812054916323b872dd611d4d61233e565b30611d5886886139a7565b6040518463ffffffff1660e01b8152600401611d7693929190612dc6565b602060405180830381600087803b158015611d9057600080fd5b505af1158015611da4573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611dc89190612b97565b905080611de75760405162461bcd60e51b81526004016107aa90613109565b82600f6000828254611df9919061397b565b90915550600090505b83811015611e7457611e15611c51611892565b600e805433917f0f6798a560793a54c3bcfe86a93cde1e73087d944c0ea20544137d412139688591906000611e4983613a44565b91905055604051611e5a9190612eeb565b60405180910390a280611e6c81613a44565b915050611e02565b5050505050565b816001600160a01b0316836001600160a01b03161415611ead5760405162461bcd60e51b81526004016107aa9061328b565b6001600160a01b0383811660008181526005602090815260408083209487168084529490915290819020805460ff1916851515179055517f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c3190611f11908590612ee0565b60405180910390a3505050565b611f29848484611a3a565b611f358484848461239a565b6110c85760405162461bcd60e51b81526004016107aa9061303a565b606081611f7657506040805180820190915260018152600360fc1b60208201526106eb565b8160005b8115611fa05780611f8a81613a44565b9150611f999050600a83613993565b9150611f7a565b60008167ffffffffffffffff811115611fc957634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015611ff3576020820181803683370190505b5090505b841561206c576120086001836139c6565b9150612015600a86613a5f565b61202090603061397b565b60f81b81838151811061204357634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350612065600a86613993565b9450611ff7565b949350505050565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b6001600160a01b03163b151590565b606061206c848484604051806060016040528060298152602001613b32602991396124b5565b804710156120f75760405162461bcd60e51b81526004016107aa9061331f565b6000826001600160a01b03168260405161211090610780565b60006040518083038185875af1925050503d806000811461214d576040519150601f19603f3d011682016040523d82523d6000602084013e612152565b606091505b50509050806108625760405162461bcd60e51b81526004016107aa906132c2565b6000604051806080016040528060438152602001613aef60439139805160209182012083518483015160408087015180519086012090516121b49501612ef4565b604051602081830303815290604052805190602001209050919050565b60006121db610b61565b826040516020016121b4929190612d97565b6121f78383612575565b612204600084848461239a565b6108625760405162461bcd60e51b81526004016107aa9061303a565b6001600160a01b0382166000908152600d60205260409020546122555760405162461bcd60e51b81526004016107aa906137d3565b6001600160a01b0382166000908152600d60205260409020546122799082906139a7565b341015610cbb5760405162461bcd60e51b81526004016107aa90612f80565b600c5415610cbb576001600160a01b0382166000908152600b60205260409020546122d55760405162461bcd60e51b81526004016107aa90612f49565b6001600160a01b0382166000908152600b602052604090205481111561230d5760405162461bcd60e51b81526004016107aa90613204565b6001600160a01b0382166000908152600b6020526040812080548392906123359084906139c6565b90915550505050565b60003330141561239557600080368080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152505050503601516001600160a01b031691506107809050565b503390565b60006123ae846001600160a01b03166120a2565b156124aa57836001600160a01b031663150b7a026123ca611892565b8786866040518563ffffffff1660e01b81526004016123ec9493929190612e1f565b602060405180830381600087803b15801561240657600080fd5b505af1925050508015612436575060408051601f3d908101601f1916820190925261243391810190612bcf565b60015b612490573d808015612464576040519150601f19603f3d011682016040523d82523d6000602084013e612469565b606091505b5080516124885760405162461bcd60e51b81526004016107aa9061303a565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061206c565b506001949350505050565b6060824710156124d75760405162461bcd60e51b81526004016107aa90613356565b6124e0856120a2565b6124fc5760405162461bcd60e51b81526004016107aa9061373b565b600080866001600160a01b031685876040516125189190612cd4565b60006040518083038185875af1925050503d8060008114612555576040519150601f19603f3d011682016040523d82523d6000602084013e61255a565b606091505b509150915061256a82828661265c565b979650505050505050565b6001600160a01b03821661259b5760405162461bcd60e51b81526004016107aa906135b2565b6125a481611875565b156125c15760405162461bcd60e51b81526004016107aa90613177565b6125cd60008383610862565b6001600160a01b03821660009081526003602052604081208054600192906125f690849061397b565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4610cbb60008383610862565b6060831561266b5750816119b6565b82511561267b5782518084602001fd5b8160405162461bcd60e51b81526004016107aa9190612f36565b8280548282559060005260206000209081019282156126ea579160200282015b828111156126ea57825182546001600160a01b0319166001600160a01b039091161782556020909201916001909101906126b5565b506126f6929150612788565b5090565b82805461270690613a09565b90600052602060002090601f01602090048101928261272857600085556126ea565b82601f1061274157805160ff19168380011785556126ea565b828001600101855582156126ea579182015b828111156126ea578251825591602001919060010190612753565b5080546000825590600052602060002090810190610f5f91905b5b808211156126f65760008155600101612789565b600067ffffffffffffffff8311156127b7576127b7613a9f565b6127ca601f8401601f1916602001613926565b90508281528383830111156127de57600080fd5b828260208301376000602084830101529392505050565b600082601f830112612805578081fd5b8135602061281a61281583613957565b613926565b8281528181019085830183850287018401881015612836578586fd5b855b8581101561285d57813561284b81613ab5565b84529284019290840190600101612838565b5090979650505050505050565b600082601f83011261287a578081fd5b8135602061288a61281583613957565b82815281810190858301838502870184018810156128a6578586fd5b855b8581101561285d578135845292840192908401906001016128a8565b600082601f8301126128d4578081fd5b6119b68383356020850161279d565b6000602082840312156128f4578081fd5b81356119b681613ab5565b60008060408385031215612911578081fd5b823561291c81613ab5565b9150602083013561292c81613ab5565b809150509250929050565b60008060006060848603121561294b578081fd5b833561295681613ab5565b9250602084013561296681613ab5565b929592945050506040919091013590565b6000806000806080858703121561298c578081fd5b843561299781613ab5565b935060208501356129a781613ab5565b925060408501359150606085013567ffffffffffffffff8111156129c9578182fd5b6129d5878288016128c4565b91505092959194509250565b600080604083850312156129f3578182fd5b82356129fe81613ab5565b9150602083013561292c81613aca565b600080600080600060a08688031215612a25578081fd5b8535612a3081613ab5565b9450602086013567ffffffffffffffff811115612a4b578182fd5b612a57888289016128c4565b9450506040860135925060608601359150608086013560ff81168114612a7b578182fd5b809150509295509295909350565b60008060408385031215612a9b578182fd5b8235612aa681613ab5565b946020939093013593505050565b60008060408385031215612ac6578182fd5b823567ffffffffffffffff80821115612add578384fd5b612ae9868387016127f5565b93506020850135915080821115612afe578283fd5b50612b0b8582860161286a565b9150509250929050565b60008060008060808587031215612b2a578182fd5b843567ffffffffffffffff80821115612b41578384fd5b612b4d888389016127f5565b9550602087013594506040870135915080821115612b69578384fd5b612b75888389016127f5565b93506060870135915080821115612b8a578283fd5b506129d58782880161286a565b600060208284031215612ba8578081fd5b81516119b681613aca565b600060208284031215612bc4578081fd5b81356119b681613ad8565b600060208284031215612be0578081fd5b81516119b681613ad8565b600060208284031215612bfc578081fd5b81516119b681613ab5565b600060208284031215612c18578081fd5b813567ffffffffffffffff811115612c2e578182fd5b8201601f81018413612c3e578182fd5b6114c88482356020840161279d565b600060208284031215612c5e578081fd5b5035919050565b6000815180845260208085019450808401835b83811015612c9d5781516001600160a01b031687529582019590820190600101612c78565b509495945050505050565b60008151808452612cc08160208601602086016139dd565b601f01601f19169290920160200192915050565b60008251612ce68184602087016139dd565b9190910192915050565b60008351612d028184602088016139dd565b60609390931b6bffffffffffffffffffffffff19169190920190815260140192915050565b60008351612d398184602088016139dd565b835190830190612d4d8183602088016139dd565b64173539b7b760d91b9101908152600501949350505050565b60008251612d788184602087016139dd565b6c31b7b73a3930b1ba173539b7b760991b920191825250600d01919050565b61190160f01b81526002810192909252602282015260420190565b6001600160a01b0391909116815260200190565b6001600160a01b039384168152919092166020820152604081019190915260600190565b6001600160a01b03848116825283166020820152606060408201819052600090612e1690830184612ca8565b95945050505050565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612e5290830184612ca8565b9695505050505050565b6001600160a01b03929092168252602082015260400190565b600060408252612e886040830185612c65565b828103602084810191909152845180835285820192820190845b8181101561285d57845183529383019391830191600101612ea2565b600060408252612ed16040830185612c65565b90508260208301529392505050565b901515815260200190565b90815260200190565b93845260208401929092526001600160a01b03166040830152606082015260800190565b93845260ff9290921660208401526040830152606082015260800190565b6000602082526119b66020830184612ca8565b6020808252601f908201527f43757272656e742075736572206973206e6f742077686974656c697374656400604082015260600190565b6020808252818101527f496e73756666696369656e7420616d6f756e742c2063616e6e6f74206d696e74604082015260600190565b60208082526013908201527213585e081cdd5c1c1b1e48195e18d959591959606a1b604082015260600190565b602080825260159082015274139bc81859191c995cdcd95cc81a5b9c1d5d1d1959605a1b604082015260600190565b6020808252600f908201526e496e76616c6964206164647265737360881b604082015260600190565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b60208082526026908201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160408201526564647265737360d01b606082015260800190565b6020808252601c908201527f46756e6374696f6e2063616c6c206e6f74207375636365737366756c00000000604082015260600190565b6020808252600f908201526e151c985b9cd9995c8819985a5b1959608a1b604082015260600190565b60208082526025908201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060408201526437bbb732b960d91b606082015260800190565b6020808252601c908201527f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000604082015260600190565b6020808252600e908201526d125b9d985b1a5908185b5bdd5b9d60921b604082015260600190565b602080825260149082015273141c9a58d9481a5cc81b9bdd081e595d081cd95d60621b604082015260600190565b60208082526023908201527f43757272656e742075736572206578636565647320616c6c6f7761626c65206d6040820152621a5b9d60ea1b606082015260800190565b60208082526024908201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646040820152637265737360e01b606082015260800190565b60208082526019908201527f4552433732313a20617070726f766520746f2063616c6c657200000000000000604082015260600190565b6020808252603a908201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260408201527f6563697069656e74206d61792068617665207265766572746564000000000000606082015260800190565b6020808252601d908201527f416464726573733a20696e73756666696369656e742062616c616e6365000000604082015260600190565b60208082526026908201527f416464726573733a20696e73756666696369656e742062616c616e636520666f6040820152651c8818d85b1b60d21b606082015260800190565b6020808252602c908201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252601c908201527f4661696c656420746f20617070726f7665207769746864726177616c00000000604082015260600190565b60208082526025908201527f4e61746976654d6574615472616e73616374696f6e3a20494e56414c49445f5360408201526424a3a722a960d91b606082015260800190565b60208082526038908201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760408201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000606082015260800190565b6020808252602a908201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604082015269726f206164647265737360b01b606082015260800190565b602080825260169082015275546f6b656e206164647265737320697320656d70747960501b604082015260600190565b60208082526029908201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460408201526832b73a103a37b5b2b760b91b606082015260800190565b602080825260149082015273546f6b656e20707269636520697320656d70747960601b604082015260600190565b6020808252818101527f4552433732313a206d696e7420746f20746865207a65726f2061646472657373604082015260600190565b6020808252602c908201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860408201526b34b9ba32b73a103a37b5b2b760a11b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526021908201527f5369676e657220616e64207369676e617475726520646f206e6f74206d6174636040820152600d60fb1b606082015260800190565b60208082526021908201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656040820152603960f91b606082015260800190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601d908201527f416464726573733a2063616c6c20746f206e6f6e2d636f6e7472616374000000604082015260600190565b6020808252601a908201527f496e76616c6964207769746864726177616c2061646472657373000000000000604082015260600190565b60208082526010908201526f13585e081cd85b19481c995858da195960821b604082015260600190565b6020808252601c908201527f5072696365206973206e6f742073657420666f72206d696e74696e6700000000604082015260600190565b6020808252602a908201527f496e76616c6964207175616e746974792c2073686f756c6420626520677265616040820152690746572207468616e20360b41b606082015260800190565b60208082526030908201527f4572726f722063616e6e6f7420636c6f73652c204e6f2057686974656c69737460408201526f081859191c995cdcd95cc8185919195960821b606082015260800190565b6020808252602d908201527f4572726f722c20707269636520646f6573206e6f7420636f6e7461696e206e6160408201526c746976652063757272656e637960981b606082015260800190565b6020808252818101527f507269636520616e64206164647265737320646f6573206e6f74206d61746368604082015260600190565b604051601f8201601f1916810167ffffffffffffffff8111828210171561394f5761394f613a9f565b604052919050565b600067ffffffffffffffff82111561397157613971613a9f565b5060209081020190565b6000821982111561398e5761398e613a73565b500190565b6000826139a2576139a2613a89565b500490565b60008160001904831182151516156139c1576139c1613a73565b500290565b6000828210156139d8576139d8613a73565b500390565b60005b838110156139f85781810151838201526020016139e0565b838111156110c85750506000910152565b600281046001821680613a1d57607f821691505b60208210811415613a3e57634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415613a5857613a58613a73565b5060010190565b600082613a6e57613a6e613a89565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b0381168114610f5f57600080fd5b8015158114610f5f57600080fd5b6001600160e01b031981168114610f5f57600080fdfe4d6574615472616e73616374696f6e2875696e74323536206e6f6e63652c616464726573732066726f6d2c62797465732066756e6374696f6e5369676e617475726529416464726573733a206c6f772d6c6576656c2063616c6c20776974682076616c7565206661696c6564a264697066735822122004b963a2dc9ca7050467442e0de18d54b11d7551453e15be483ab36053fae2d564736f6c63430008010033

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

000000000000000000000000a5409ec958c83c3f309868babaca7c86dcb077c1

-----Decoded View---------------
Arg [0] : proxyAddress (address): 0xa5409ec958C83C3f309868babACA7c86DCB077c1

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 000000000000000000000000a5409ec958c83c3f309868babaca7c86dcb077c1


Deployed Bytecode Sourcemap

65444:2867:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;25273:305;;;;;;;;;;-1:-1:-1;25273:305:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;26218:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;27777:221::-;;;;;;;;;;-1:-1:-1;27777:221:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;27300:411::-;;;;;;;;;;-1:-1:-1;27300:411:0;;;;;:::i;:::-;;:::i;:::-;;53959:1151;;;;;;:::i;:::-;;:::i;65883:43::-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;50957:::-;;;;;;;;;;;;;:::i;57205:30::-;;;;;;;;;;;;;:::i;58279:744::-;;;;;;;;;;-1:-1:-1;58279:744:0;;;;;:::i;:::-;;:::i;51966:101::-;;;;;;;;;;;;;:::i;66484:295::-;;;;;;;;;;-1:-1:-1;66484:295:0;;;;;:::i;:::-;;:::i;28527:339::-;;;;;;;;;;-1:-1:-1;28527:339:0;;;;;:::i;:::-;;:::i;55536:107::-;;;;;;;;;;-1:-1:-1;55536:107:0;;;;;:::i;:::-;;:::i;66092:111::-;;;;;;;;;;-1:-1:-1;66092:111:0;;;;;:::i;:::-;;:::i;52075:161::-;;;;;;;;;;;;;:::i;60859:257::-;;;;;;;;;;-1:-1:-1;60859:257:0;;;;;:::i;:::-;;:::i;28937:185::-;;;;;;;;;;-1:-1:-1;28937:185:0;;;;;:::i;:::-;;:::i;25912:239::-;;;;;;;;;;-1:-1:-1;25912:239:0;;;;;:::i;:::-;;:::i;25642:208::-;;;;;;;;;;-1:-1:-1;25642:208:0;;;;;:::i;:::-;;:::i;40170:103::-;;;;;;;;;;;;;:::i;57939:332::-;;;;;;;;;;-1:-1:-1;57939:332:0;;;;;:::i;:::-;;:::i;39519:87::-;;;;;;;;;;;;;:::i;26387:104::-;;;;;;;;;;;;;:::i;57165:33::-;;;;;;;;;;;;;:::i;67927:173::-;;;;;;:::i;:::-;;:::i;68108:200::-;;;;;;;;;;-1:-1:-1;68108:200:0;;;;;:::i;:::-;;:::i;57279:75::-;;;;;;;;;;;;;:::i;28070:155::-;;;;;;;;;;-1:-1:-1;28070:155:0;;;;;:::i;:::-;;:::i;60294:557::-;;;;;;;;;;-1:-1:-1;60294:557:0;;;;;:::i;:::-;;:::i;29193:328::-;;;;;;;;;;-1:-1:-1;29193:328:0;;;;;:::i;:::-;;:::i;65807:67::-;;;;;;;;;;;;;:::i;62316:350::-;;;;;;;;;;-1:-1:-1;62316:350:0;;;;;:::i;:::-;;:::i;61201:1107::-;;;;;;;;;;-1:-1:-1;61201:1107:0;;;;;:::i;:::-;;:::i;66211:104::-;;;;;;;;;;;;;:::i;57242:28::-;;;;;;;;;;;;;:::i;66323:153::-;;;;;;;;;;;;;:::i;62874:445::-;;;;;;;;;;-1:-1:-1;62874:445:0;;;;;:::i;:::-;;:::i;65766:32::-;;;;;;;;;;;;;:::i;40428:201::-;;;;;;;;;;-1:-1:-1;40428:201:0;;;;;:::i;:::-;;:::i;66787:1132::-;;;;;;:::i;:::-;;:::i;25273:305::-;25375:4;-1:-1:-1;;;;;;25412:40:0;;-1:-1:-1;;;25412:40:0;;:105;;-1:-1:-1;;;;;;;25469:48:0;;-1:-1:-1;;;25469:48:0;25412:105;:158;;;;25534:36;25558:11;25534:23;:36::i;:::-;25392:178;;25273:305;;;;:::o;26218:100::-;26272:13;26305:5;26298:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26218:100;;:::o;27777:221::-;27853:7;27881:16;27889:7;27881;:16::i;:::-;27873:73;;;;-1:-1:-1;;;27873:73:0;;;;;;;:::i;:::-;;;;;;;;;-1:-1:-1;27966:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;27966:24:0;;27777:221::o;27300:411::-;27381:13;27397:23;27412:7;27397:14;:23::i;:::-;27381:39;;27445:5;-1:-1:-1;;;;;27439:11:0;:2;-1:-1:-1;;;;;27439:11:0;;;27431:57;;;;-1:-1:-1;;;27431:57:0;;;;;;;:::i;:::-;27539:5;-1:-1:-1;;;;;27523:21:0;:12;:10;:12::i;:::-;-1:-1:-1;;;;;27523:21:0;;:62;;;;27548:37;27565:5;27572:12;:10;:12::i;27548:37::-;27501:168;;;;-1:-1:-1;;;27501:168:0;;;;;;;:::i;:::-;27682:21;27691:2;27695:7;27682:8;:21::i;:::-;27300:411;;;:::o;53959:1151::-;54217:152;;;54160:12;54217:152;;;;;-1:-1:-1;;;;;54255:19:0;;54185:29;54255:19;;;:6;:19;;;;;;;;;54217:152;;;;;;;;;;;54404:45;54262:11;54217:152;54432:4;54438;54444;54404:6;:45::i;:::-;54382:128;;;;-1:-1:-1;;;54382:128:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;54599:19:0;;;;;;:6;:19;;;;;;:26;;54623:1;54599:23;:26::i;:::-;-1:-1:-1;;;;;54577:19:0;;;;;;:6;:19;;;;;;;:48;;;;54643:126;;;;;54584:11;;54715:10;;54741:17;;54643:126;:::i;:::-;;;;;;;;54880:12;54894:23;54929:4;-1:-1:-1;;;;;54921:18:0;54971:17;54990:11;54954:48;;;;;;;;;:::i;:::-;;;;-1:-1:-1;;54954:48:0;;;;;;;;;;54921:92;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;54879:134;;;;55032:7;55024:48;;;;-1:-1:-1;;;55024:48:0;;;;;;;:::i;:::-;55092:10;53959:1151;-1:-1:-1;;;;;;;;53959:1151:0:o;65883:43::-;65922:4;65883:43;:::o;50957:::-;;;;;;;;;;;;;;-1:-1:-1;;;50957:43:0;;;;:::o;57205:30::-;;;;:::o;58279:744::-;39750:12;:10;:12::i;:::-;-1:-1:-1;;;;;39739:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;39739:23:0;;39731:68;;;;-1:-1:-1;;;39731:68:0;;;;;;;:::i;:::-;58521:1:::1;58495:16;:23;:27;58487:61;;;;-1:-1:-1::0;;;58487:61:0::1;;;;;;;:::i;:::-;58578:1;58567:8;:12;58559:67;;;;-1:-1:-1::0;;;58559:67:0::1;;;;;;;:::i;:::-;58639:34;58648:12;58662:10;58639:8;:34::i;:::-;58705:21;58686:226;58761:16;:23;58745:13;:39;58686:226;;;58892:8;58841:9;:15;;:48;58857:16;58874:13;58857:31;;;;;;-1:-1:-1::0;;;58857:31:0::1;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;58841:48:0::1;-1:-1:-1::0;;;;;58841:48:0::1;;;;;;;;;;;;:59;;;;58799:15;;;;;:::i;:::-;;;;58686:226;;;-1:-1:-1::0;58922:37:0;;::::1;::::0;:18;;:37:::1;::::0;::::1;::::0;::::1;:::i;:::-;;58975:40;58988:16;59006:8;58975:40;;;;;;;:::i;:::-;;;;;;;;58279:744:::0;;;;:::o;51966:101::-;52044:15;;51966:101;:::o;66484:295::-;39750:12;:10;:12::i;:::-;-1:-1:-1;;;;;39739:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;39739:23:0;;39731:68;;;;-1:-1:-1;;;39731:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;66603:32:0;::::1;66595:71;;;;-1:-1:-1::0;;;66595:71:0::1;;;;;;;:::i;:::-;66677:17;:38:::0;;-1:-1:-1;;;;;;66677:38:0::1;-1:-1:-1::0;;;;;66677:38:0;::::1;::::0;;::::1;::::0;;;66731:40:::1;::::0;::::1;::::0;-1:-1:-1;;66731:40:0::1;66484:295:::0;:::o;28527:339::-;28722:41;28741:12;:10;:12::i;:::-;28755:7;28722:18;:41::i;:::-;28714:103;;;;-1:-1:-1;;;28714:103:0;;;;;;;:::i;:::-;28830:28;28840:4;28846:2;28850:7;28830:9;:28::i;55536:107::-;-1:-1:-1;;;;;55623:12:0;55589:13;55623:12;;;:6;:12;;;;;;;55536:107::o;66092:111::-;39750:12;:10;:12::i;:::-;-1:-1:-1;;;;;39739:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;39739:23:0;;39731:68;;;;-1:-1:-1;;;39731:68:0;;;;;;;:::i;:::-;66173:22;;::::1;::::0;:9:::1;::::0;:22:::1;::::0;::::1;::::0;::::1;:::i;:::-;;66092:111:::0;:::o;52075:161::-;52189:9;52075:161;:::o;60859:257::-;60922:7;-1:-1:-1;;;;;60950:25:0;;60942:53;;;;-1:-1:-1;;;60942:53:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;61014:28:0;;61045:1;61014:28;;;:5;:28;;;;;;61006:65;;;;-1:-1:-1;;;61006:65:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;;61089:19:0;;;;;:5;:19;;;;;;;60859:257::o;28937:185::-;29075:39;29092:4;29098:2;29102:7;29075:39;;;;;;;;;;;;:16;:39::i;25912:239::-;25984:7;26020:16;;;:7;:16;;;;;;-1:-1:-1;;;;;26020:16:0;26055:19;26047:73;;;;-1:-1:-1;;;26047:73:0;;;;;;;:::i;25642:208::-;25714:7;-1:-1:-1;;;;;25742:19:0;;25734:74;;;;-1:-1:-1;;;25734:74:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;;25826:16:0;;;;;:9;:16;;;;;;;25642:208::o;40170:103::-;39750:12;:10;:12::i;:::-;-1:-1:-1;;;;;39739:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;39739:23:0;;39731:68;;;;-1:-1:-1;;;39731:68:0;;;;;;;:::i;:::-;40235:30:::1;40262:1;40235:18;:30::i;:::-;40170:103::o:0;57939:332::-;39750:12;:10;:12::i;:::-;-1:-1:-1;;;;;39739:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;39739:23:0;;39731:68;;;;-1:-1:-1;;;39731:68:0;;;;;;;:::i;:::-;58019:9:::1;::::0;:14;;:41:::1;;;58049:11;;58037:9;;:23;58019:41;57997:110;;;;-1:-1:-1::0;;;57997:110:0::1;;;;;;;:::i;:::-;58143:14;:16:::0;;58118:22:::1;::::0;;58143:16:::1;::::0;::::1;:::i;:::-;;;;;58118:41;;58170:29;58180:2;58184:14;58170:9;:29::i;:::-;58210:11;:13:::0;;;:11:::1;:13;::::0;::::1;:::i;:::-;;;;;;58244:2;-1:-1:-1::0;;;;;58239:24:0::1;;58248:14;58239:24;;;;;;:::i;:::-;;;;;;;;39810:1;57939:332:::0;:::o;39519:87::-;39592:6;;-1:-1:-1;;;;;39592:6:0;39519:87;:::o;26387:104::-;26443:13;26476:7;26469:14;;;;;:::i;57165:33::-;;;;:::o;67927:173::-;65922:4;68016:8;68002:11;;:22;;;;:::i;:::-;:38;;67994:67;;;;-1:-1:-1;;;67994:67:0;;;;;;;:::i;:::-;68072:20;68083:8;68072:10;:20::i;:::-;67927:173;:::o;68108:200::-;65922:4;68210:8;68196:11;;:22;;;;:::i;:::-;:38;;68188:67;;;;-1:-1:-1;;;68188:67:0;;;;;;;:::i;:::-;68266:34;68284:5;68291:8;68266:17;:34::i;57279:75::-;57312:42;57279:75;:::o;28070:155::-;28165:52;28184:12;:10;:12::i;:::-;28198:8;28208;28165:18;:52::i;60294:557::-;39750:12;:10;:12::i;:::-;-1:-1:-1;;;;;39739:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;39739:23:0;;39731:68;;;;-1:-1:-1;;;39731:68:0;;;;;;;:::i;:::-;60458:18;:25;60436:127:::1;;;;-1:-1:-1::0;;;60436:127:0::1;;;;;;;:::i;:::-;60579:13;60574:189;60606:18:::0;:25;60598:33;::::1;60574:189;;;60657:19;60679:9;:18;;60698:5;60679:25;;;;;;-1:-1:-1::0;;;60679:25:0::1;;;;;;;;;;::::0;;;::::1;::::0;;;;;::::1;::::0;-1:-1:-1;;;;;60679:25:0::1;60719:28:::0;;:9:::1;:28:::0;;;;;:32;-1:-1:-1;60633:7:0;::::1;::::0;::::1;:::i;:::-;;;;60574:189;;;-1:-1:-1::0;60773:25:0::1;60780:18:::0;::::1;60773:25;:::i;:::-;60809:34;60818:12;60832:10;60809:8;:34::i;29193:328::-:0;29368:41;29387:12;:10;:12::i;:::-;29401:7;29368:18;:41::i;:::-;29360:103;;;;-1:-1:-1;;;29360:103:0;;;;;;;:::i;:::-;29474:39;29488:4;29494:2;29498:7;29507:5;29474:13;:39::i;:::-;29193:328;;;;:::o;65807:67::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;62316:350::-;62417:13;62532:14;:12;:14::i;:::-;62569:25;62586:7;62569:16;:25::i;:::-;62493:150;;;;;;;;;:::i;:::-;;;;;;;;;;;;;62448:210;;62316:350;;;:::o;61201:1107::-;39750:12;:10;:12::i;:::-;-1:-1:-1;;;;;39739:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;39739:23:0;;39731:68;;;;-1:-1:-1;;;39731:68:0;;;;;;;:::i;:::-;61362:1:::1;61340:12;:19;:23;61332:58;;;;-1:-1:-1::0;;;61332:58:0::1;;;;;;;:::i;:::-;61429:1;61409:10;:17;:21;61401:54;;;;-1:-1:-1::0;;;61401:54:0::1;;;;;;;:::i;:::-;61509:12;:19;61488:10;:17;:40;61466:122;;;;-1:-1:-1::0;;;61466:122:0::1;;;;;;;:::i;:::-;61601:21;61646:13:::0;61641:190:::1;61673:12;:19;61665:5;:27;61641:190;;;57312:42;-1:-1:-1::0;;;;;61722:38:0::1;:12;61735:5;61722:19;;;;;;-1:-1:-1::0;;;61722:19:0::1;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;61722:38:0::1;;61718:102;;;61800:4;61781:23;;61718:102;61694:7:::0;::::1;::::0;::::1;:::i;:::-;;;;61641:190;;;;61865:16;61843:111;;;;-1:-1:-1::0;;;61843:111:0::1;;;;;;;:::i;:::-;61972:13;61967:284;61999:12;:19;61991:5;:27;61967:284;;;62090:1;62070:10;62081:5;62070:17;;;;;;-1:-1:-1::0;;;62070:17:0::1;;;;;;;;;;;;;;;:21;62044:125;;;;-1:-1:-1::0;;;62044:125:0::1;;;;;;;:::i;:::-;62222:10;62233:5;62222:17;;;;;;-1:-1:-1::0;;;62222:17:0::1;;;;;;;;;;;;;;;62184:5;:35;62198:12;62211:5;62198:19;;;;;;-1:-1:-1::0;;;62198:19:0::1;;;;;;;;;;;;;;;-1:-1:-1::0;;;;;62184:35:0::1;-1:-1:-1::0;;;;;62184:35:0::1;;;;;;;;;;;;:55;;;;62020:7;;;;;:::i;:::-;;;;61967:284;;;;62266:34;62275:12;62289:10;62266:34;;;;;;;:::i;:::-;;;;;;;;39810:1;61201:1107:::0;;:::o;66211:104::-;66265:13;66298:9;66291:16;;;;;:::i;57242:28::-;;;;:::o;66323:153::-;66378:13;66435:14;:12;:14::i;:::-;66418:49;;;;;;;;:::i;:::-;;;;;;;;;;;;;66404:64;;66323:153;:::o;62874:445::-;63128:20;;63172:28;;-1:-1:-1;;;63172:28:0;;62999:4;;-1:-1:-1;;;;;63128:20:0;;;;63164:49;;;;63128:20;;63172:21;;:28;;63194:5;;63172:28;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;;;;;63164:49:0;;63160:93;;;63237:4;63230:11;;;;;63160:93;63272:39;63295:5;63302:8;63272:22;:39::i;:::-;63265:46;;;62874:445;;;;;:::o;65766:32::-;;;-1:-1:-1;;;;;65766:32:0;;:::o;40428:201::-;39750:12;:10;:12::i;:::-;-1:-1:-1;;;;;39739:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;39739:23:0;;39731:68;;;;-1:-1:-1;;;39731:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;40517:22:0;::::1;40509:73;;;;-1:-1:-1::0;;;40509:73:0::1;;;;;;;:::i;:::-;40593:28;40612:8;40593:18;:28::i;66787:1132::-:0;39750:12;:10;:12::i;:::-;-1:-1:-1;;;;;39739:23:0;:7;:5;:7::i;:::-;-1:-1:-1;;;;;39739:23:0;;39731:68;;;;-1:-1:-1;;;39731:68:0;;;;;;;:::i;:::-;66930:1:::1;66921:6;:10;66913:37;;;;-1:-1:-1::0;;;66913:37:0::1;;;;;;;:::i;:::-;66998:17;::::0;66961:15:::1;::::0;66979:37:::1;::::0;-1:-1:-1;;;;;66998:17:0::1;66979:18;:37::i;:::-;66961:55:::0;-1:-1:-1;;;;;;67031:22:0;::::1;57312:42;67031:22;67027:458;;;67074:10;67070:328;;;67157:17;::::0;67197:43:::1;::::0;;;;;::::1;::::0;::::1;::::0;;;::::1;::::0;::::1;::::0;;-1:-1:-1;;;;;67197:43:0::1;-1:-1:-1::0;;;67197:43:0::1;::::0;;67105:183:::1;::::0;-1:-1:-1;;;;;67157:17:0::1;::::0;67263:6;67105:29:::1;:183::i;:::-;;67070:328;;;67355:17;::::0;67329:53:::1;::::0;-1:-1:-1;;;;;67355:17:0::1;67375:6:::0;67329:17:::1;:53::i;:::-;67426:17;::::0;67417:35:::1;::::0;67445:6;;-1:-1:-1;;;;;67426:17:0::1;::::0;67417:35:::1;::::0;67426:17:::1;::::0;67417:35:::1;67467:7;;;67027:458;67517:12:::0;67541:307;::::1;;;67601:17;::::0;67587:40:::1;::::0;-1:-1:-1;;;67587:40:0;;67572:12:::1;::::0;-1:-1:-1;;;;;67587:13:0;;::::1;::::0;::::1;::::0;:40:::1;::::0;67601:17:::1;::::0;67620:6;;67587:40:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;67572:55;;67650:7;67642:48;;;;-1:-1:-1::0;;;67642:48:0::1;;;;;;;:::i;:::-;67714:17;::::0;67705:57:::1;::::0;-1:-1:-1;;;67705:57:0;;-1:-1:-1;;;;;67714:17:0;;::::1;::::0;67705:42:::1;::::0;:57:::1;::::0;67748:5;;67755:6;;67705:57:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;67541:307;;;;67810:17;::::0;67795:41:::1;::::0;-1:-1:-1;;;67795:41:0;;-1:-1:-1;;;;;67795:14:0;;::::1;::::0;::::1;::::0;:41:::1;::::0;67810:17;;::::1;::::0;67829:6;;67795:41:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;67541:307;67878:17;::::0;67863:48:::1;::::0;67904:6;;-1:-1:-1;;;;;67863:48:0;;::::1;::::0;67878:17;::::1;::::0;67863:48:::1;::::0;67878:17:::1;::::0;67863:48:::1;39810:1;;66787:1132:::0;;:::o;23247:157::-;-1:-1:-1;;;;;;23356:40:0;;-1:-1:-1;;;23356:40:0;23247:157;;;:::o;31031:127::-;31096:4;31120:16;;;:7;:16;;;;;;-1:-1:-1;;;;;31120:16:0;:30;;;31031:127::o;19946:98::-;20026:10;19946:98;:::o;35177:174::-;35252:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;35252:29:0;-1:-1:-1;;;;;35252:29:0;;;;;;;;:24;;35306:23;35252:24;35306:14;:23::i;:::-;-1:-1:-1;;;;;35297:46:0;;;;;;;;;;;35177:174;;:::o;55651:486::-;55829:4;-1:-1:-1;;;;;55854:20:0;;55846:70;;;;-1:-1:-1;;;55846:70:0;;;;;;;:::i;:::-;55970:159;55998:47;56017:27;56037:6;56017:19;:27::i;:::-;55998:18;:47::i;:::-;56064:4;56087;56110;55970:159;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;55947:182:0;:6;-1:-1:-1;;;;;55947:182:0;;55927:202;;55651:486;;;;;;;:::o;45342:98::-;45400:7;45427:5;45431:1;45427;:5;:::i;:::-;45420:12;45342:98;-1:-1:-1;;;45342:98:0:o;31325:348::-;31418:4;31443:16;31451:7;31443;:16::i;:::-;31435:73;;;;-1:-1:-1;;;31435:73:0;;;;;;;:::i;:::-;31519:13;31535:23;31550:7;31535:14;:23::i;:::-;31519:39;;31588:5;-1:-1:-1;;;;;31577:16:0;:7;-1:-1:-1;;;;;31577:16:0;;:51;;;;31621:7;-1:-1:-1;;;;;31597:31:0;:20;31609:7;31597:11;:20::i;:::-;-1:-1:-1;;;;;31597:31:0;;31577:51;:87;;;;31632:32;31649:5;31656:7;31632:16;:32::i;34434:625::-;34593:4;-1:-1:-1;;;;;34566:31:0;:23;34581:7;34566:14;:23::i;:::-;-1:-1:-1;;;;;34566:31:0;;34558:81;;;;-1:-1:-1;;;34558:81:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;34658:16:0;;34650:65;;;;-1:-1:-1;;;34650:65:0;;;;;;;:::i;:::-;34728:39;34749:4;34755:2;34759:7;34728:20;:39::i;:::-;34832:29;34849:1;34853:7;34832:8;:29::i;:::-;-1:-1:-1;;;;;34874:15:0;;;;;;:9;:15;;;;;:20;;34893:1;;34874:15;:20;;34893:1;;34874:20;:::i;:::-;;;;-1:-1:-1;;;;;;;34905:13:0;;;;;;:9;:13;;;;;:18;;34922:1;;34905:13;:18;;34922:1;;34905:18;:::i;:::-;;;;-1:-1:-1;;34934:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;34934:21:0;-1:-1:-1;;;;;34934:21:0;;;;;;;;;34973:27;;34934:16;;34973:27;;;;;;;35013:38;35033:4;35039:2;35043:7;35013:19;:38::i;40789:191::-;40882:6;;;-1:-1:-1;;;;;40899:17:0;;;-1:-1:-1;;;;;;40899:17:0;;;;;;;40932:40;;40882:6;;;40899:17;40882:6;;40932:40;;40863:16;;40932:40;40789:191;;:::o;32015:110::-;32091:26;32101:2;32105:7;32091:26;;;;;;;;;;;;:9;:26::i;59031:465::-;59133:9;;59117:11;;59106:22;;:8;:22;:::i;:::-;59105:37;;59097:69;;;;-1:-1:-1;;;59097:69:0;;;;;;;:::i;:::-;59179:40;57312:42;59210:8;59179:13;:40::i;:::-;59232:39;59248:12;:10;:12::i;:::-;59262:8;59232:15;:39::i;:::-;59299:8;59284:11;;:23;;;;;;;:::i;:::-;;;;-1:-1:-1;59323:13:0;;-1:-1:-1;59318:171:0;59350:8;59342:5;:16;59318:171;;;59384:39;59394:12;:10;:12::i;:::-;59408:14;;59384:9;:39::i;:::-;59460:14;:16;;59448:10;;59443:34;;59460:16;:14;:16;;;:::i;:::-;;;;;59443:34;;;;;;:::i;:::-;;;;;;;;59360:7;;;;:::i;:::-;;;;59318:171;;59504:782;59619:9;;59603:11;;59592:22;;:8;:22;:::i;:::-;59591:37;;59583:69;;;;-1:-1:-1;;;59583:69:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;59673:21:0;;59697:1;59673:21;;;:5;:21;;;;;;59665:66;;;;-1:-1:-1;;;59665:66:0;;;;;;;:::i;:::-;59744:39;59760:12;:10;:12::i;59744:39::-;-1:-1:-1;;;;;59853:21:0;;59836:14;59853:21;;;:5;:21;;;;;;;59900:18;59933:11;:9;:11::i;:::-;59967:4;59987:17;59998:6;59987:8;:17;:::i;:::-;59900:115;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;59885:130;;60034:7;60026:35;;;;-1:-1:-1;;;60026:35:0;;;;;;;:::i;:::-;60089:8;60074:11;;:23;;;;;;;:::i;:::-;;;;-1:-1:-1;60113:13:0;;-1:-1:-1;60108:171:0;60140:8;60132:5;:16;60108:171;;;60174:39;60184:12;:10;:12::i;60174:39::-;60250:14;:16;;60238:10;;60233:34;;60250:16;:14;:16;;;:::i;:::-;;;;;60233:34;;;;;;:::i;:::-;;;;;;;;60150:7;;;;:::i;:::-;;;;60108:171;;;;59504:782;;;;:::o;35493:315::-;35648:8;-1:-1:-1;;;;;35639:17:0;:5;-1:-1:-1;;;;;35639:17:0;;;35631:55;;;;-1:-1:-1;;;35631:55:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;35697:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;:46;;-1:-1:-1;;35697:46:0;;;;;;;35759:41;;;;;35697:46;;35759:41;:::i;:::-;;;;;;;;35493:315;;;:::o;30403:::-;30560:28;30570:4;30576:2;30580:7;30560:9;:28::i;:::-;30607:48;30630:4;30636:2;30640:7;30649:5;30607:22;:48::i;:::-;30599:111;;;;-1:-1:-1;;;30599:111:0;;;;;;;:::i;20539:723::-;20595:13;20816:10;20812:53;;-1:-1:-1;20843:10:0;;;;;;;;;;;;-1:-1:-1;;;20843:10:0;;;;;;20812:53;20890:5;20875:12;20931:78;20938:9;;20931:78;;20964:8;;;;:::i;:::-;;-1:-1:-1;20987:10:0;;-1:-1:-1;20995:2:0;20987:10;;:::i;:::-;;;20931:78;;;21019:19;21051:6;21041:17;;;;;;-1:-1:-1;;;21041:17:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21041:17:0;;21019:39;;21069:154;21076:10;;21069:154;;21103:11;21113:1;21103:11;;:::i;:::-;;-1:-1:-1;21172:10:0;21180:2;21172:5;:10;:::i;:::-;21159:24;;:2;:24;:::i;:::-;21146:39;;21129:6;21136;21129:14;;;;;;-1:-1:-1;;;21129:14:0;;;;;;;;;;;;:56;-1:-1:-1;;;;;21129:56:0;;;;;;;;-1:-1:-1;21200:11:0;21209:2;21200:11;;:::i;:::-;;;21069:154;;;21247:6;20539:723;-1:-1:-1;;;;20539:723:0:o;28296:164::-;-1:-1:-1;;;;;28417:25:0;;;28393:4;28417:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;28296:164::o;11983:326::-;-1:-1:-1;;;;;12278:19:0;;:23;;;11983:326::o;15332:260::-;15465:12;15497:87;15519:6;15527:4;15533:5;15497:87;;;;;;;;;;;;;;;;;:21;:87::i;13244:317::-;13359:6;13334:21;:31;;13326:73;;;;-1:-1:-1;;;13326:73:0;;;;;;;:::i;:::-;13413:12;13431:9;-1:-1:-1;;;;;13431:14:0;13453:6;13431:33;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13412:52;;;13483:7;13475:78;;;;-1:-1:-1;;;13475:78:0;;;;;;;:::i;55118:410::-;55228:7;53295:100;;;;;;;;;;;;;;;;;53275:127;;;;;;;55382:12;;55417:11;;;;55461:24;;;;;55451:35;;;;;;55301:204;;;;;;:::i;:::-;;;;;;;;;;;;;55273:247;;;;;;55253:267;;55118:410;;;:::o;52605:258::-;52704:7;52806:20;:18;:20::i;:::-;52828:11;52777:63;;;;;;;;;:::i;32352:321::-;32482:18;32488:2;32492:7;32482:5;:18::i;:::-;32533:54;32564:1;32568:2;32572:7;32581:5;32533:22;:54::i;:::-;32511:154;;;;-1:-1:-1;;;32511:154:0;;;;;;;:::i;63791:373::-;-1:-1:-1;;;;;63923:28:0;;63954:1;63923:28;;;:5;:28;;;;;;63901:110;;;;-1:-1:-1;;;63901:110:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;64057:28:0;;;;;;:5;:28;;;;;;:39;;64088:8;;64057:39;:::i;:::-;64044:9;:52;;64022:134;;;;-1:-1:-1;;;64022:134:0;;;;;;;:::i;63327:456::-;63407:18;:25;:29;63403:373;;-1:-1:-1;;;;;63479:21:0;;63503:1;63479:21;;;:9;:21;;;;;;63453:118;;;;-1:-1:-1;;;63453:118:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;63624:21:0;;:15;:21;;;:9;:21;;;;;;63612:33;;;63586:130;;;;-1:-1:-1;;;63586:130:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;63731:21:0;;:15;:21;;;:9;:21;;;;;:33;;63756:8;;63731:15;:33;;63756:8;;63731:33;:::i;:::-;;;;-1:-1:-1;;63327:456:0;;:::o;49648:650::-;49719:22;49763:10;49785:4;49763:27;49759:508;;;49807:18;49828:8;;49807:29;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;49867:8:0;50078:17;50072:24;-1:-1:-1;;;;;50046:134:0;;-1:-1:-1;49906:289:0;;-1:-1:-1;49906:289:0;;-1:-1:-1;50244:10:0;49648:650;:::o;36373:799::-;36528:4;36549:15;:2;-1:-1:-1;;;;;36549:13:0;;:15::i;:::-;36545:620;;;36601:2;-1:-1:-1;;;;;36585:36:0;;36622:12;:10;:12::i;:::-;36636:4;36642:7;36651:5;36585:72;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;36585:72:0;;;;;;;;-1:-1:-1;;36585:72:0;;;;;;;;;;;;:::i;:::-;;;36581:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;36827:13:0;;36823:272;;36870:60;;-1:-1:-1;;;36870:60:0;;;;;;;:::i;36823:272::-;37045:6;37039:13;37030:6;37026:2;37022:15;37015:38;36581:529;-1:-1:-1;;;;;;36708:51:0;-1:-1:-1;;;36708:51:0;;-1:-1:-1;36701:58:0;;36545:620;-1:-1:-1;37149:4:0;36373:799;;;;;;:::o;15848:510::-;16018:12;16076:5;16051:21;:30;;16043:81;;;;-1:-1:-1;;;16043:81:0;;;;;;;:::i;:::-;16143:18;16154:6;16143:10;:18::i;:::-;16135:60;;;;-1:-1:-1;;;16135:60:0;;;;;;;:::i;:::-;16209:12;16223:23;16250:6;-1:-1:-1;;;;;16250:11:0;16269:5;16276:4;16250:31;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;16208:73;;;;16299:51;16316:7;16325:10;16337:12;16299:16;:51::i;:::-;16292:58;15848:510;-1:-1:-1;;;;;;;15848:510:0:o;33009:439::-;-1:-1:-1;;;;;33089:16:0;;33081:61;;;;-1:-1:-1;;;33081:61:0;;;;;;;:::i;:::-;33162:16;33170:7;33162;:16::i;:::-;33161:17;33153:58;;;;-1:-1:-1;;;33153:58:0;;;;;;;:::i;:::-;33224:45;33253:1;33257:2;33261:7;33224:20;:45::i;:::-;-1:-1:-1;;;;;33282:13:0;;;;;;:9;:13;;;;;:18;;33299:1;;33282:13;:18;;33299:1;;33282:18;:::i;:::-;;;;-1:-1:-1;;33311:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;33311:21:0;-1:-1:-1;;;;;33311:21:0;;;;;;;;33350:33;;33311:16;;;33350:33;;33311:16;;33350:33;33396:44;33424:1;33428:2;33432:7;33396:19;:44::i;18534:712::-;18684:12;18713:7;18709:530;;;-1:-1:-1;18744:10:0;18737:17;;18709:530;18858:17;;:21;18854:374;;19056:10;19050:17;19117:15;19104:10;19100:2;19096:19;19089:44;19004:148;19199:12;19192:20;;-1:-1:-1;;;19192:20:0;;;;;;;;:::i;-1:-1:-1:-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:408:1;;114:18;106:6;103:30;100:2;;;136:18;;:::i;:::-;174:57;219:2;198:15;;-1:-1:-1;;194:29:1;225:4;190:40;174:57;:::i;:::-;165:66;;254:6;247:5;240:21;294:3;285:6;280:3;276:16;273:25;270:2;;;311:1;308;301:12;270:2;360:6;355:3;348:4;341:5;337:16;324:43;414:1;407:4;398:6;391:5;387:18;383:29;376:40;90:332;;;;;:::o;427:783::-;;540:3;533:4;525:6;521:17;517:27;507:2;;562:5;555;548:20;507:2;602:6;589:20;628:4;652:66;668:49;714:2;668:49;:::i;:::-;652:66;:::i;:::-;752:15;;;783:12;;;;815:15;;;861:11;;;849:24;;845:33;;842:42;-1:-1:-1;839:2:1;;;901:5;894;887:20;839:2;927:5;941:240;955:2;952:1;949:9;941:240;;;1026:3;1013:17;1043:33;1070:5;1043:33;:::i;:::-;1089:18;;1127:12;;;;1159;;;;973:1;966:9;941:240;;;-1:-1:-1;1199:5:1;;497:713;-1:-1:-1;;;;;;;497:713:1:o;1215:706::-;;1328:3;1321:4;1313:6;1309:17;1305:27;1295:2;;1350:5;1343;1336:20;1295:2;1390:6;1377:20;1416:4;1440:66;1456:49;1502:2;1456:49;:::i;1440:66::-;1540:15;;;1571:12;;;;1603:15;;;1649:11;;;1637:24;;1633:33;;1630:42;-1:-1:-1;1627:2:1;;;1689:5;1682;1675:20;1627:2;1715:5;1729:163;1743:2;1740:1;1737:9;1729:163;;;1800:17;;1788:30;;1838:12;;;;1870;;;;1761:1;1754:9;1729:163;;1926:232;;2023:3;2016:4;2008:6;2004:17;2000:27;1990:2;;2045:5;2038;2031:20;1990:2;2071:81;2148:3;2139:6;2126:20;2119:4;2111:6;2107:17;2071:81;:::i;2163:259::-;;2275:2;2263:9;2254:7;2250:23;2246:32;2243:2;;;2296:6;2288;2281:22;2243:2;2340:9;2327:23;2359:33;2386:5;2359:33;:::i;2427:402::-;;;2556:2;2544:9;2535:7;2531:23;2527:32;2524:2;;;2577:6;2569;2562:22;2524:2;2621:9;2608:23;2640:33;2667:5;2640:33;:::i;:::-;2692:5;-1:-1:-1;2749:2:1;2734:18;;2721:32;2762:35;2721:32;2762:35;:::i;:::-;2816:7;2806:17;;;2514:315;;;;;:::o;2834:470::-;;;;2980:2;2968:9;2959:7;2955:23;2951:32;2948:2;;;3001:6;2993;2986:22;2948:2;3045:9;3032:23;3064:33;3091:5;3064:33;:::i;:::-;3116:5;-1:-1:-1;3173:2:1;3158:18;;3145:32;3186:35;3145:32;3186:35;:::i;:::-;2938:366;;3240:7;;-1:-1:-1;;;3294:2:1;3279:18;;;;3266:32;;2938:366::o;3309:691::-;;;;;3481:3;3469:9;3460:7;3456:23;3452:33;3449:2;;;3503:6;3495;3488:22;3449:2;3547:9;3534:23;3566:33;3593:5;3566:33;:::i;:::-;3618:5;-1:-1:-1;3675:2:1;3660:18;;3647:32;3688:35;3647:32;3688:35;:::i;:::-;3742:7;-1:-1:-1;3796:2:1;3781:18;;3768:32;;-1:-1:-1;3851:2:1;3836:18;;3823:32;3878:18;3867:30;;3864:2;;;3915:6;3907;3900:22;3864:2;3943:51;3986:7;3977:6;3966:9;3962:22;3943:51;:::i;:::-;3933:61;;;3439:561;;;;;;;:::o;4005:396::-;;;4131:2;4119:9;4110:7;4106:23;4102:32;4099:2;;;4152:6;4144;4137:22;4099:2;4196:9;4183:23;4215:33;4242:5;4215:33;:::i;:::-;4267:5;-1:-1:-1;4324:2:1;4309:18;;4296:32;4337;4296;4337;:::i;4406:792::-;;;;;;4593:3;4581:9;4572:7;4568:23;4564:33;4561:2;;;4615:6;4607;4600:22;4561:2;4659:9;4646:23;4678:33;4705:5;4678:33;:::i;:::-;4730:5;-1:-1:-1;4786:2:1;4771:18;;4758:32;4813:18;4802:30;;4799:2;;;4850:6;4842;4835:22;4799:2;4878:51;4921:7;4912:6;4901:9;4897:22;4878:51;:::i;:::-;4868:61;;;4976:2;4965:9;4961:18;4948:32;4938:42;;5027:2;5016:9;5012:18;4999:32;4989:42;;5083:3;5072:9;5068:19;5055:33;5132:4;5123:7;5119:18;5110:7;5107:31;5097:2;;5157:6;5149;5142:22;5097:2;5185:7;5175:17;;;4551:647;;;;;;;;:::o;5203:327::-;;;5332:2;5320:9;5311:7;5307:23;5303:32;5300:2;;;5353:6;5345;5338:22;5300:2;5397:9;5384:23;5416:33;5443:5;5416:33;:::i;:::-;5468:5;5520:2;5505:18;;;;5492:32;;-1:-1:-1;;;5290:240:1:o;5535:637::-;;;5714:2;5702:9;5693:7;5689:23;5685:32;5682:2;;;5735:6;5727;5720:22;5682:2;5780:9;5767:23;5809:18;5850:2;5842:6;5839:14;5836:2;;;5871:6;5863;5856:22;5836:2;5899:67;5958:7;5949:6;5938:9;5934:22;5899:67;:::i;:::-;5889:77;;6019:2;6008:9;6004:18;5991:32;5975:48;;6048:2;6038:8;6035:16;6032:2;;;6069:6;6061;6054:22;6032:2;;6097:69;6158:7;6147:8;6136:9;6132:24;6097:69;:::i;:::-;6087:79;;;5672:500;;;;;:::o;6177:948::-;;;;;6415:3;6403:9;6394:7;6390:23;6386:33;6383:2;;;6437:6;6429;6422:22;6383:2;6482:9;6469:23;6511:18;6552:2;6544:6;6541:14;6538:2;;;6573:6;6565;6558:22;6538:2;6601:67;6660:7;6651:6;6640:9;6636:22;6601:67;:::i;:::-;6591:77;;6715:2;6704:9;6700:18;6687:32;6677:42;;6772:2;6761:9;6757:18;6744:32;6728:48;;6801:2;6791:8;6788:16;6785:2;;;6822:6;6814;6807:22;6785:2;6850:69;6911:7;6900:8;6889:9;6885:24;6850:69;:::i;:::-;6840:79;;6972:2;6961:9;6957:18;6944:32;6928:48;;7001:2;6991:8;6988:16;6985:2;;;7022:6;7014;7007:22;6985:2;;7050:69;7111:7;7100:8;7089:9;7085:24;7050:69;:::i;7130:257::-;;7250:2;7238:9;7229:7;7225:23;7221:32;7218:2;;;7271:6;7263;7256:22;7218:2;7308:9;7302:16;7327:30;7351:5;7327:30;:::i;7392:257::-;;7503:2;7491:9;7482:7;7478:23;7474:32;7471:2;;;7524:6;7516;7509:22;7471:2;7568:9;7555:23;7587:32;7613:5;7587:32;:::i;7654:261::-;;7776:2;7764:9;7755:7;7751:23;7747:32;7744:2;;;7797:6;7789;7782:22;7744:2;7834:9;7828:16;7853:32;7879:5;7853:32;:::i;8265:292::-;;8417:2;8405:9;8396:7;8392:23;8388:32;8385:2;;;8438:6;8430;8423:22;8385:2;8475:9;8469:16;8494:33;8521:5;8494:33;:::i;8562:482::-;;8684:2;8672:9;8663:7;8659:23;8655:32;8652:2;;;8705:6;8697;8690:22;8652:2;8750:9;8737:23;8783:18;8775:6;8772:30;8769:2;;;8820:6;8812;8805:22;8769:2;8848:22;;8901:4;8893:13;;8889:27;-1:-1:-1;8879:2:1;;8935:6;8927;8920:22;8879:2;8963:75;9030:7;9025:2;9012:16;9007:2;9003;8999:11;8963:75;:::i;9049:190::-;;9161:2;9149:9;9140:7;9136:23;9132:32;9129:2;;;9182:6;9174;9167:22;9129:2;-1:-1:-1;9210:23:1;;9119:120;-1:-1:-1;9119:120:1:o;9244:469::-;;9341:5;9335:12;9368:6;9363:3;9356:19;9394:4;9423:2;9418:3;9414:12;9407:19;;9460:2;9453:5;9449:14;9481:3;9493:195;9507:6;9504:1;9501:13;9493:195;;;9572:13;;-1:-1:-1;;;;;9568:39:1;9556:52;;9628:12;;;;9663:15;;;;9604:1;9522:9;9493:195;;;-1:-1:-1;9704:3:1;;9311:402;-1:-1:-1;;;;;9311:402:1:o;9718:259::-;;9799:5;9793:12;9826:6;9821:3;9814:19;9842:63;9898:6;9891:4;9886:3;9882:14;9875:4;9868:5;9864:16;9842:63;:::i;:::-;9959:2;9938:15;-1:-1:-1;;9934:29:1;9925:39;;;;9966:4;9921:50;;9769:208;-1:-1:-1;;9769:208:1:o;9982:274::-;;10149:6;10143:13;10165:53;10211:6;10206:3;10199:4;10191:6;10187:17;10165:53;:::i;:::-;10234:16;;;;;10119:137;-1:-1:-1;;10119:137:1:o;10261:415::-;;10456:6;10450:13;10472:53;10518:6;10513:3;10506:4;10498:6;10494:17;10472:53;:::i;:::-;10594:2;10590:15;;;;-1:-1:-1;;10586:53:1;10547:16;;;;10572:68;;;10667:2;10656:14;;10426:250;-1:-1:-1;;10426:250:1:o;10681:637::-;;10999:6;10993:13;11015:53;11061:6;11056:3;11049:4;11041:6;11037:17;11015:53;:::i;:::-;11131:13;;11090:16;;;;11153:57;11131:13;11090:16;11187:4;11175:17;;11153:57;:::i;:::-;-1:-1:-1;;;11232:20:1;;11261:22;;;11310:1;11299:13;;10969:349;-1:-1:-1;;;;10969:349:1:o;11323:452::-;;11593:6;11587:13;11609:53;11655:6;11650:3;11643:4;11635:6;11631:17;11609:53;:::i;:::-;-1:-1:-1;;;11684:16:1;;11709:30;;;-1:-1:-1;11766:2:1;11755:14;;11563:212;-1:-1:-1;11563:212:1:o;11780:392::-;-1:-1:-1;;;12038:27:1;;12090:1;12081:11;;12074:27;;;;12126:2;12117:12;;12110:28;12163:2;12154:12;;12028:144::o;12387:203::-;-1:-1:-1;;;;;12551:32:1;;;;12533:51;;12521:2;12506:18;;12488:102::o;12595:383::-;-1:-1:-1;;;;;12861:15:1;;;12843:34;;12913:15;;;;12908:2;12893:18;;12886:43;12960:2;12945:18;;12938:34;;;;12793:2;12778:18;;12760:218::o;12983:433::-;-1:-1:-1;;;;;13240:15:1;;;13222:34;;13292:15;;13287:2;13272:18;;13265:43;13344:2;13339;13324:18;;13317:30;;;12983:433;;13364:46;;13391:18;;13383:6;13364:46;:::i;:::-;13356:54;13174:242;-1:-1:-1;;;;;13174:242:1:o;13421:490::-;-1:-1:-1;;;;;13690:15:1;;;13672:34;;13742:15;;13737:2;13722:18;;13715:43;13789:2;13774:18;;13767:34;;;13837:3;13832:2;13817:18;;13810:31;;;13421:490;;13858:47;;13885:19;;13877:6;13858:47;:::i;:::-;13850:55;13624:287;-1:-1:-1;;;;;;13624:287:1:o;13916:274::-;-1:-1:-1;;;;;14108:32:1;;;;14090:51;;14172:2;14157:18;;14150:34;14078:2;14063:18;;14045:145::o;14195:813::-;;14452:2;14441:9;14434:21;14478:62;14536:2;14525:9;14521:18;14513:6;14478:62;:::i;:::-;14597:22;;;14559:2;14577:18;;;14570:50;;;;14669:13;;14691:22;;;14767:15;;;;14729;;;14800:4;14813:169;14827:6;14824:1;14821:13;14813:169;;;14888:13;;14876:26;;14957:15;;;;14922:12;;;;14849:1;14842:9;14813:169;;15013:338;;15220:2;15209:9;15202:21;15240:62;15298:2;15287:9;15283:18;15275:6;15240:62;:::i;:::-;15232:70;;15338:6;15333:2;15322:9;15318:18;15311:34;15192:159;;;;;:::o;15356:187::-;15521:14;;15514:22;15496:41;;15484:2;15469:18;;15451:92::o;15548:177::-;15694:25;;;15682:2;15667:18;;15649:76::o;15730:417::-;15961:25;;;16017:2;16002:18;;15995:34;;;;-1:-1:-1;;;;;16065:32:1;16060:2;16045:18;;16038:60;16129:2;16114:18;;16107:34;15948:3;15933:19;;15915:232::o;16152:398::-;16379:25;;;16452:4;16440:17;;;;16435:2;16420:18;;16413:45;16489:2;16474:18;;16467:34;16532:2;16517:18;;16510:34;16366:3;16351:19;;16333:217::o;16555:219::-;;16702:2;16691:9;16684:21;16722:46;16764:2;16753:9;16749:18;16741:6;16722:46;:::i;17297:355::-;17499:2;17481:21;;;17538:2;17518:18;;;17511:30;17577:33;17572:2;17557:18;;17550:61;17643:2;17628:18;;17471:181::o;17657:356::-;17859:2;17841:21;;;17878:18;;;17871:30;17937:34;17932:2;17917:18;;17910:62;18004:2;17989:18;;17831:182::o;18018:343::-;18220:2;18202:21;;;18259:2;18239:18;;;18232:30;-1:-1:-1;;;18293:2:1;18278:18;;18271:49;18352:2;18337:18;;18192:169::o;18366:345::-;18568:2;18550:21;;;18607:2;18587:18;;;18580:30;-1:-1:-1;;;18641:2:1;18626:18;;18619:51;18702:2;18687:18;;18540:171::o;18716:339::-;18918:2;18900:21;;;18957:2;18937:18;;;18930:30;-1:-1:-1;;;18991:2:1;18976:18;;18969:45;19046:2;19031:18;;18890:165::o;19060:414::-;19262:2;19244:21;;;19301:2;19281:18;;;19274:30;19340:34;19335:2;19320:18;;19313:62;-1:-1:-1;;;19406:2:1;19391:18;;19384:48;19464:3;19449:19;;19234:240::o;19479:402::-;19681:2;19663:21;;;19720:2;19700:18;;;19693:30;19759:34;19754:2;19739:18;;19732:62;-1:-1:-1;;;19825:2:1;19810:18;;19803:36;19871:3;19856:19;;19653:228::o;19886:352::-;20088:2;20070:21;;;20127:2;20107:18;;;20100:30;20166;20161:2;20146:18;;20139:58;20229:2;20214:18;;20060:178::o;20243:339::-;20445:2;20427:21;;;20484:2;20464:18;;;20457:30;-1:-1:-1;;;20518:2:1;20503:18;;20496:45;20573:2;20558:18;;20417:165::o;20587:401::-;20789:2;20771:21;;;20828:2;20808:18;;;20801:30;20867:34;20862:2;20847:18;;20840:62;-1:-1:-1;;;20933:2:1;20918:18;;20911:35;20978:3;20963:19;;20761:227::o;20993:352::-;21195:2;21177:21;;;21234:2;21214:18;;;21207:30;21273;21268:2;21253:18;;21246:58;21336:2;21321:18;;21167:178::o;21350:338::-;21552:2;21534:21;;;21591:2;21571:18;;;21564:30;-1:-1:-1;;;21625:2:1;21610:18;;21603:44;21679:2;21664:18;;21524:164::o;21693:344::-;21895:2;21877:21;;;21934:2;21914:18;;;21907:30;-1:-1:-1;;;21968:2:1;21953:18;;21946:50;22028:2;22013:18;;21867:170::o;22042:399::-;22244:2;22226:21;;;22283:2;22263:18;;;22256:30;22322:34;22317:2;22302:18;;22295:62;-1:-1:-1;;;22388:2:1;22373:18;;22366:33;22431:3;22416:19;;22216:225::o;22446:400::-;22648:2;22630:21;;;22687:2;22667:18;;;22660:30;22726:34;22721:2;22706:18;;22699:62;-1:-1:-1;;;22792:2:1;22777:18;;22770:34;22836:3;22821:19;;22620:226::o;22851:349::-;23053:2;23035:21;;;23092:2;23072:18;;;23065:30;23131:27;23126:2;23111:18;;23104:55;23191:2;23176:18;;23025:175::o;23205:422::-;23407:2;23389:21;;;23446:2;23426:18;;;23419:30;23485:34;23480:2;23465:18;;23458:62;23556:28;23551:2;23536:18;;23529:56;23617:3;23602:19;;23379:248::o;23632:353::-;23834:2;23816:21;;;23873:2;23853:18;;;23846:30;23912:31;23907:2;23892:18;;23885:59;23976:2;23961:18;;23806:179::o;23990:402::-;24192:2;24174:21;;;24231:2;24211:18;;;24204:30;24270:34;24265:2;24250:18;;24243:62;-1:-1:-1;;;24336:2:1;24321:18;;24314:36;24382:3;24367:19;;24164:228::o;24397:408::-;24599:2;24581:21;;;24638:2;24618:18;;;24611:30;24677:34;24672:2;24657:18;;24650:62;-1:-1:-1;;;24743:2:1;24728:18;;24721:42;24795:3;24780:19;;24571:234::o;24810:352::-;25012:2;24994:21;;;25051:2;25031:18;;;25024:30;25090;25085:2;25070:18;;25063:58;25153:2;25138:18;;24984:178::o;25167:401::-;25369:2;25351:21;;;25408:2;25388:18;;;25381:30;25447:34;25442:2;25427:18;;25420:62;-1:-1:-1;;;25513:2:1;25498:18;;25491:35;25558:3;25543:19;;25341:227::o;25573:420::-;25775:2;25757:21;;;25814:2;25794:18;;;25787:30;25853:34;25848:2;25833:18;;25826:62;25924:26;25919:2;25904:18;;25897:54;25983:3;25968:19;;25747:246::o;25998:406::-;26200:2;26182:21;;;26239:2;26219:18;;;26212:30;26278:34;26273:2;26258:18;;26251:62;-1:-1:-1;;;26344:2:1;26329:18;;26322:40;26394:3;26379:19;;26172:232::o;26409:346::-;26611:2;26593:21;;;26650:2;26630:18;;;26623:30;-1:-1:-1;;;26684:2:1;26669:18;;26662:52;26746:2;26731:18;;26583:172::o;26760:405::-;26962:2;26944:21;;;27001:2;26981:18;;;26974:30;27040:34;27035:2;27020:18;;27013:62;-1:-1:-1;;;27106:2:1;27091:18;;27084:39;27155:3;27140:19;;26934:231::o;27170:344::-;27372:2;27354:21;;;27411:2;27391:18;;;27384:30;-1:-1:-1;;;27445:2:1;27430:18;;27423:50;27505:2;27490:18;;27344:170::o;27519:356::-;27721:2;27703:21;;;27740:18;;;27733:30;27799:34;27794:2;27779:18;;27772:62;27866:2;27851:18;;27693:182::o;27880:408::-;28082:2;28064:21;;;28121:2;28101:18;;;28094:30;28160:34;28155:2;28140:18;;28133:62;-1:-1:-1;;;28226:2:1;28211:18;;28204:42;28278:3;28263:19;;28054:234::o;28293:356::-;28495:2;28477:21;;;28514:18;;;28507:30;28573:34;28568:2;28553:18;;28546:62;28640:2;28625:18;;28467:182::o;28654:397::-;28856:2;28838:21;;;28895:2;28875:18;;;28868:30;28934:34;28929:2;28914:18;;28907:62;-1:-1:-1;;;29000:2:1;28985:18;;28978:31;29041:3;29026:19;;28828:223::o;29056:397::-;29258:2;29240:21;;;29297:2;29277:18;;;29270:30;29336:34;29331:2;29316:18;;29309:62;-1:-1:-1;;;29402:2:1;29387:18;;29380:31;29443:3;29428:19;;29230:223::o;29458:413::-;29660:2;29642:21;;;29699:2;29679:18;;;29672:30;29738:34;29733:2;29718:18;;29711:62;-1:-1:-1;;;29804:2:1;29789:18;;29782:47;29861:3;29846:19;;29632:239::o;29876:353::-;30078:2;30060:21;;;30117:2;30097:18;;;30090:30;30156:31;30151:2;30136:18;;30129:59;30220:2;30205:18;;30050:179::o;30234:350::-;30436:2;30418:21;;;30475:2;30455:18;;;30448:30;30514:28;30509:2;30494:18;;30487:56;30575:2;30560:18;;30408:176::o;30589:340::-;30791:2;30773:21;;;30830:2;30810:18;;;30803:30;-1:-1:-1;;;30864:2:1;30849:18;;30842:46;30920:2;30905:18;;30763:166::o;30934:352::-;31136:2;31118:21;;;31175:2;31155:18;;;31148:30;31214;31209:2;31194:18;;31187:58;31277:2;31262:18;;31108:178::o;31291:406::-;31493:2;31475:21;;;31532:2;31512:18;;;31505:30;31571:34;31566:2;31551:18;;31544:62;-1:-1:-1;;;31637:2:1;31622:18;;31615:40;31687:3;31672:19;;31465:232::o;31702:412::-;31904:2;31886:21;;;31943:2;31923:18;;;31916:30;31982:34;31977:2;31962:18;;31955:62;-1:-1:-1;;;32048:2:1;32033:18;;32026:46;32104:3;32089:19;;31876:238::o;32119:409::-;32321:2;32303:21;;;32360:2;32340:18;;;32333:30;32399:34;32394:2;32379:18;;32372:62;-1:-1:-1;;;32465:2:1;32450:18;;32443:43;32518:3;32503:19;;32293:235::o;32533:356::-;32735:2;32717:21;;;32754:18;;;32747:30;32813:34;32808:2;32793:18;;32786:62;32880:2;32865:18;;32707:182::o;33076:275::-;33147:2;33141:9;33212:2;33193:13;;-1:-1:-1;;33189:27:1;33177:40;;33247:18;33232:34;;33268:22;;;33229:62;33226:2;;;33294:18;;:::i;:::-;33330:2;33323:22;33121:230;;-1:-1:-1;33121:230:1:o;33356:192::-;;33455:18;33447:6;33444:30;33441:2;;;33477:18;;:::i;:::-;-1:-1:-1;33537:4:1;33518:17;;;33514:28;;33431:117::o;33553:128::-;;33624:1;33620:6;33617:1;33614:13;33611:2;;;33630:18;;:::i;:::-;-1:-1:-1;33666:9:1;;33601:80::o;33686:120::-;;33752:1;33742:2;;33757:18;;:::i;:::-;-1:-1:-1;33791:9:1;;33732:74::o;33811:168::-;;33917:1;33913;33909:6;33905:14;33902:1;33899:21;33894:1;33887:9;33880:17;33876:45;33873:2;;;33924:18;;:::i;:::-;-1:-1:-1;33964:9:1;;33863:116::o;33984:125::-;;34052:1;34049;34046:8;34043:2;;;34057:18;;:::i;:::-;-1:-1:-1;34094:9:1;;34033:76::o;34114:258::-;34186:1;34196:113;34210:6;34207:1;34204:13;34196:113;;;34286:11;;;34280:18;34267:11;;;34260:39;34232:2;34225:10;34196:113;;;34327:6;34324:1;34321:13;34318:2;;;-1:-1:-1;;34362:1:1;34344:16;;34337:27;34167:205::o;34377:380::-;34462:1;34452:12;;34509:1;34499:12;;;34520:2;;34574:4;34566:6;34562:17;34552:27;;34520:2;34627;34619:6;34616:14;34596:18;34593:38;34590:2;;;34673:10;34668:3;34664:20;34661:1;34654:31;34708:4;34705:1;34698:15;34736:4;34733:1;34726:15;34590:2;;34432:325;;;:::o;34762:135::-;;-1:-1:-1;;34822:17:1;;34819:2;;;34842:18;;:::i;:::-;-1:-1:-1;34889:1:1;34878:13;;34809:88::o;34902:112::-;;34960:1;34950:2;;34965:18;;:::i;:::-;-1:-1:-1;34999:9:1;;34940:74::o;35019:127::-;35080:10;35075:3;35071:20;35068:1;35061:31;35111:4;35108:1;35101:15;35135:4;35132:1;35125:15;35151:127;35212:10;35207:3;35203:20;35200:1;35193:31;35243:4;35240:1;35233:15;35267:4;35264:1;35257:15;35283:127;35344:10;35339:3;35335:20;35332:1;35325:31;35375:4;35372:1;35365:15;35399:4;35396:1;35389:15;35415:133;-1:-1:-1;;;;;35492:31:1;;35482:42;;35472:2;;35538:1;35535;35528:12;35553:120;35641:5;35634:13;35627:21;35620:5;35617:32;35607:2;;35663:1;35660;35653:12;35678:133;-1:-1:-1;;;;;;35754:32:1;;35744:43;;35734:2;;35801:1;35798;35791:12

Swarm Source

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