Token FantomPup Punks

 

Overview ERC-721

Total Supply:
564 PUPPUNK

Holders:
108 addresses

Transfers:
-

Loading
[ Download CSV Export  ] 
Loading
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
FantomPupPunks

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-11-13
*/

// File: @uniswap/v2-core/contracts/interfaces/IUniswapV2Pair.sol


pragma solidity >=0.5.0;

interface IUniswapV2Pair {
    event Approval(address indexed owner, address indexed spender, uint value);
    event Transfer(address indexed from, address indexed to, uint value);

    function name() external pure returns (string memory);
    function symbol() external pure returns (string memory);
    function decimals() external pure returns (uint8);
    function totalSupply() external view returns (uint);
    function balanceOf(address owner) external view returns (uint);
    function allowance(address owner, address spender) external view returns (uint);

    function approve(address spender, uint value) external returns (bool);
    function transfer(address to, uint value) external returns (bool);
    function transferFrom(address from, address to, uint value) external returns (bool);

    function DOMAIN_SEPARATOR() external view returns (bytes32);
    function PERMIT_TYPEHASH() external pure returns (bytes32);
    function nonces(address owner) external view returns (uint);

    function permit(address owner, address spender, uint value, uint deadline, uint8 v, bytes32 r, bytes32 s) external;

    event Mint(address indexed sender, uint amount0, uint amount1);
    event Burn(address indexed sender, uint amount0, uint amount1, address indexed to);
    event Swap(
        address indexed sender,
        uint amount0In,
        uint amount1In,
        uint amount0Out,
        uint amount1Out,
        address indexed to
    );
    event Sync(uint112 reserve0, uint112 reserve1);

    function MINIMUM_LIQUIDITY() external pure returns (uint);
    function factory() external view returns (address);
    function token0() external view returns (address);
    function token1() external view returns (address);
    function getReserves() external view returns (uint112 reserve0, uint112 reserve1, uint32 blockTimestampLast);
    function price0CumulativeLast() external view returns (uint);
    function price1CumulativeLast() external view returns (uint);
    function kLast() external view returns (uint);

    function mint(address to) external returns (uint liquidity);
    function burn(address to) external returns (uint amount0, uint amount1);
    function swap(uint amount0Out, uint amount1Out, address to, bytes calldata data) external;
    function skim(address to) external;
    function sync() external;

    function initialize(address, address) external;
}

// File: @openzeppelin/contracts/security/ReentrancyGuard.sol



pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    /**
     * @dev Prevents a contract from calling itself, directly or indirectly.
     * Calling a `nonReentrant` function from another `nonReentrant`
     * function is not supported. It is possible to prevent this from happening
     * by making the `nonReentrant` function external, and make it call a
     * `private` function that does the actual work.
     */
    modifier nonReentrant() {
        // On the first call to nonReentrant, _notEntered will be true
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");

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

        _;

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

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



pragma solidity ^0.8.0;

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

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

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

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

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

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



pragma solidity ^0.8.0;

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

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

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



pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

// File: @openzeppelin/contracts/security/Pausable.sol



pragma solidity ^0.8.0;


/**
 * @dev Contract module which allows children to implement an emergency stop
 * mechanism that can be triggered by an authorized account.
 *
 * This module is used through inheritance. It will make available the
 * modifiers `whenNotPaused` and `whenPaused`, which can be applied to
 * the functions of your contract. Note that they will not be pausable by
 * simply including this module, only once the modifiers are put in place.
 */
abstract contract Pausable is Context {
    /**
     * @dev Emitted when the pause is triggered by `account`.
     */
    event Paused(address account);

    /**
     * @dev Emitted when the pause is lifted by `account`.
     */
    event Unpaused(address account);

    bool private _paused;

    /**
     * @dev Initializes the contract in unpaused state.
     */
    constructor() {
        _paused = false;
    }

    /**
     * @dev Returns true if the contract is paused, and false otherwise.
     */
    function paused() public view virtual returns (bool) {
        return _paused;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is not paused.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    modifier whenNotPaused() {
        require(!paused(), "Pausable: paused");
        _;
    }

    /**
     * @dev Modifier to make a function callable only when the contract is paused.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    modifier whenPaused() {
        require(paused(), "Pausable: not paused");
        _;
    }

    /**
     * @dev Triggers stopped state.
     *
     * Requirements:
     *
     * - The contract must not be paused.
     */
    function _pause() internal virtual whenNotPaused {
        _paused = true;
        emit Paused(_msgSender());
    }

    /**
     * @dev Returns to normal state.
     *
     * Requirements:
     *
     * - The contract must be paused.
     */
    function _unpause() internal virtual whenPaused {
        _paused = false;
        emit Unpaused(_msgSender());
    }
}

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



pragma solidity ^0.8.0;

/**
 * @dev Collection of functions related to the address type
 */
library Address {
    /**
     * @dev Returns true if `account` is a contract.
     *
     * [IMPORTANT]
     * ====
     * It is unsafe to assume that an address for which this function returns
     * false is an externally-owned account (EOA) and not a contract.
     *
     * Among others, `isContract` will return false for the following
     * types of addresses:
     *
     *  - an externally-owned account
     *  - a contract in construction
     *  - an address where a contract will be created
     *  - an address where a contract lived, but was destroyed
     * ====
     */
    function isContract(address account) internal view returns (bool) {
        // This method relies on extcodesize, which returns 0 for contracts in
        // construction, since the code is only stored at the end of the
        // constructor execution.

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

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

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

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

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

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

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

        (bool success, bytes memory returndata) = target.call{value: value}(data);
        return verifyCallResult(success, returndata, errorMessage);
    }

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a static call.
     *
     * _Available since v3.3._
     */
    function functionStaticCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal view returns (bytes memory) {
        require(isContract(target), "Address: static call to non-contract");

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

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

    /**
     * @dev Same as {xref-Address-functionCall-address-bytes-string-}[`functionCall`],
     * but performing a delegate call.
     *
     * _Available since v3.4._
     */
    function functionDelegateCall(
        address target,
        bytes memory data,
        string memory errorMessage
    ) internal returns (bytes memory) {
        require(isContract(target), "Address: delegate call to non-contract");

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

    /**
     * @dev Tool to verifies that a low level call was successful, and revert if it wasn't, either by bubbling the
     * revert reason using the provided one.
     *
     * _Available since v4.3._
     */
    function verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) internal pure returns (bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

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

// File: @openzeppelin/contracts/token/ERC721/IERC721Receiver.sol



pragma solidity ^0.8.0;

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

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



pragma solidity ^0.8.0;

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

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



pragma solidity ^0.8.0;


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

// File: @openzeppelin/contracts/token/ERC721/IERC721.sol



pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

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

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

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

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

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



pragma solidity ^0.8.0;


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

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

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

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



pragma solidity ^0.8.0;


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

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

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

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



pragma solidity ^0.8.0;








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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        address owner = _owners[tokenId];
        require(owner != address(0), "ERC721: owner query for nonexistent token");
        return owner;
    }

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

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

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721Metadata: URI query for nonexistent token");

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

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

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

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

        _operatorApprovals[_msgSender()][operator] = approved;
        emit ApprovalForAll(_msgSender(), operator, approved);
    }

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(from, to, tokenId);
    }

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

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

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

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



pragma solidity ^0.8.0;



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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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



pragma solidity ^0.8.0;



/**
 * @dev ERC721 token with pausable token transfers, minting and burning.
 *
 * Useful for scenarios such as preventing trades until the end of an evaluation
 * period, or having an emergency switch for freezing all token transfers in the
 * event of a large bug.
 */
abstract contract ERC721Pausable is ERC721, Pausable {
    /**
     * @dev See {ERC721-_beforeTokenTransfer}.
     *
     * Requirements:
     *
     * - the contract must not be paused.
     */
    function _beforeTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual override {
        super._beforeTokenTransfer(from, to, tokenId);

        require(!paused(), "ERC721Pausable: token transfer while paused");
    }
}

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



pragma solidity ^0.8.0;



/**
 * @title ERC721 Burnable Token
 * @dev ERC721 Token that can be irreversibly burned (destroyed).
 */
abstract contract ERC721Burnable is Context, ERC721 {
    /**
     * @dev Burns `tokenId`. See {ERC721-_burn}.
     *
     * Requirements:
     *
     * - The caller must own `tokenId` or be an approved operator.
     */
    function burn(uint256 tokenId) public virtual {
        //solhint-disable-next-line max-line-length
        require(_isApprovedOrOwner(_msgSender(), tokenId), "ERC721Burnable: caller is not owner nor approved");
        _burn(tokenId);
    }
}

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



pragma solidity ^0.8.0;


/**
 * @dev ERC721 token with storage based token URI management.
 */
abstract contract ERC721URIStorage is ERC721 {
    using Strings for uint256;

    // Optional mapping for token URIs
    mapping(uint256 => string) private _tokenURIs;

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        require(_exists(tokenId), "ERC721URIStorage: URI query for nonexistent token");

        string memory _tokenURI = _tokenURIs[tokenId];
        string memory base = _baseURI();

        // If there is no base URI, return the token URI.
        if (bytes(base).length == 0) {
            return _tokenURI;
        }
        // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
        if (bytes(_tokenURI).length > 0) {
            return string(abi.encodePacked(base, _tokenURI));
        }

        return super.tokenURI(tokenId);
    }

    /**
     * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
        require(_exists(tokenId), "ERC721URIStorage: URI set of nonexistent token");
        _tokenURIs[tokenId] = _tokenURI;
    }

    /**
     * @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 override {
        super._burn(tokenId);

        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }
    }
}

// File: @openzeppelin/contracts/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;
    }
}

// File: contracts/FantomPupPunks.sol



// @title: PolyPup Punks NFT
// @author: Neothon

//	.______     ______    __      ____    ____ .______    __    __  .______      .______    __    __  .__   __.  __  ___      _______.
//	|   _  \   /  __  \  |  |     \   \  /   / |   _  \  |  |  |  | |   _  \     |   _  \  |  |  |  | |  \ |  | |  |/  /     /       |
//	|  |_)  | |  |  |  | |  |      \   \/   /  |  |_)  | |  |  |  | |  |_)  |    |  |_)  | |  |  |  | |   \|  | |  '  /     |   (----`
//	|   ___/  |  |  |  | |  |       \_    _/   |   ___/  |  |  |  | |   ___/     |   ___/  |  |  |  | |  . `  | |    <       \   \
//	|  |      |  `--'  | |  `----.    |  |     |  |      |  `--'  | |  |         |  |      |  `--'  | |  |\   | |  .  \  .----)   |
//	| _|       \______/  |_______|    |__|     | _|       \______/  | _|         | _|       \______/  |__| \__| |__|\__\ |_______/

pragma solidity ^0.8.4;












contract FantomPupPunks is
	ERC721Pausable,
	ERC721Burnable,
	Ownable,
	ERC721Enumerable,
	ReentrancyGuard
{
	using Counters for Counters.Counter;

	bool private sale;

	uint256 public constant TOKEN_LIMIT = 5555;
	uint256 public mintPrice = 30 ether;
	uint256 public constant MAX_MINT_AT_ONCE = 10;
	address payable public immutable developer;
	string public baseTokenURI;

	Counters.Counter private _numberOfTokens;

	// Random index assignment
	uint256 internal nonce = 0;
	uint256[TOKEN_LIMIT] internal indices;
	address public constant pairAddress =
		0xa572BdF049382F1F98f9a430788dadD51A303969; // USDC/WETH QuickSwap Pair Address

	/**
	 * Event emitted when poly pup punk minted
	 */

	event PolyPupPunkMinted(uint256 indexed id);

	/**
	 * Event emitted when the public sale begins.
	 */
	event SaleBegins();

	/**
	 * Event emitted when base uri is updated
	 */
	event BaseURIUpdated();

	/**
	 * Event emitted when price updated
	 */
	event MintPriceUpdated();

	constructor(string memory baseURI, address payable _developer)
		ERC721('FantomPup Punks', 'PUPPUNK')
	{
		setBaseURI(baseURI);
		developer = _developer;
		pause(true);
		sale = false;
	}

	/**
	 * Start sale only owner allowed
	 */
	function startSale() external onlyOwner {
		sale = true;
		pause(false);
		emit SaleBegins();
	}

	/**
	 * Function modifier to pause sale if owner is not calling the function.
	 */
	modifier saleIsOpen() {
		require(_totalSupply() <= TOKEN_LIMIT, 'Sale ended');
		if (_msgSender() != owner()) {
			require(!paused(), 'Pausable: paused');
		}
		_;
	}

	modifier validNFToken(uint256 _tokenId) {
		require(_exists(_tokenId), 'Invalid token.');
		_;
	}

	/**
	 * Public method to start minting PolyPup Punks
	 */

	function mint(uint256 _count) external payable nonReentrant {
		uint256 total = _totalSupply();
		require(sale == true, 'Sale has not yet started');
		require(total + _count <= TOKEN_LIMIT, 'Max limit');
		require(_count <= MAX_MINT_AT_ONCE, 'Exceeds number');
		require(msg.value == price(_count), 'Value below price');
		require(tx.origin == msg.sender, 'Caller cannot be a contract'); // Only EOA can mint and not a contract

		for (uint256 i = 0; i < _count; i++) {
			_mintAnElement(msg.sender);
		}

		Address.sendValue(developer, msg.value);
	}

	function _mintAnElement(address _to) private {
		uint256 id = _randomIndex();
		_numberOfTokens.increment();

		_safeMint(_to, id);
		emit PolyPupPunkMinted(id);
	}

	/**
	 * Returns a random index within the unminited token id range
	 */
	function _randomIndex() internal returns (uint256) {
		uint256 totalSize = TOKEN_LIMIT - _numberOfTokens.current();
		//Fetching current balances of USDC/WETH QS Pair for increasing Randomness Entropy
		(uint256 balance1, uint256 balance2) = getCurrentBalanceQSPair();
		uint256 index = uint256(
			keccak256(
				abi.encodePacked(
					nonce,
					msg.sender,
					balance1,
					balance2,
					block.difficulty,
					block.timestamp
				)
			)
		) % totalSize;
		uint256 value = 0;
		if (indices[index] != 0) {
			value = indices[index];
		} else {
			value = index;
		}

		// Move last value to selected position
		if (indices[totalSize - 1] == 0) {
			// Array position not initialized, so use position
			indices[index] = totalSize - 1;
		} else {
			// Array position holds a value so use that
			indices[index] = indices[totalSize - 1];
		}
		nonce++;
		// Don't allow a zero index, start counting at 1
		return value + 1;
	}

	/**
	 * @dev Getting current reserves of USDC and WETH pairs on QuickSwap
	 */
	function getCurrentBalanceQSPair() public view returns (uint256, uint256) {
		IUniswapV2Pair pair = IUniswapV2Pair(
			pairAddress // Address of USDC/WETH Pair on QuickSwap
		);
		(uint256 res0, uint256 res1, ) = pair.getReserves();
		return (res0, res1);
	}

	/** Returns total minted at that point of time */
	function totalMint() external view returns (uint256) {
		return _totalSupply();
	}

	/** Returns total price for total numbrer of minting */
	function price(uint256 _count) public view returns (uint256) {
		return mintPrice * _count;
	}

	/** Defining Internal Methods */

	/**
	 * Returns the total current supply
	 */
	function _totalSupply() internal view returns (uint256) {
		return _numberOfTokens.current();
	}

	/*
	 * Function set base URI. Only Contract Owner can do this
	 */
	function setBaseURI(string memory baseURI) public onlyOwner {
		baseTokenURI = baseURI;
		emit BaseURIUpdated();
	}

	/*
	 * Function set base URI. Only Contract Owner can do this
	 */
	function setMintPrice(uint256 _price) public onlyOwner {
		mintPrice = _price;
		emit MintPriceUpdated();
	}

	/**
	 * @dev A distinct URI (RFC 3986) for a given NFT.
	 * @param _tokenId Id for which we want uri.
	 * @return _tokenId URI of _tokenId.
	 */
	function tokenURI(uint256 _tokenId)
		public
		view
		virtual
		override
		validNFToken(_tokenId)
		returns (string memory)
	{
		// returning only baseTokenURI followed by the ID.
		return string(abi.encodePacked(baseTokenURI, Strings.toString(_tokenId)));
	}

	/**
	 * Pause and unpause sale
	 */
	function pause(bool val) public onlyOwner {
		// Allowing pause only if the sale hasn't started
		if (val == true && sale == false) {
			_pause();
			return;
		}
		_unpause();
	}

	// return NFTs in owner wallet
	function walletOfOwner(address _owner)
		external
		view
		returns (uint256[] memory)
	{
		uint256 tokenCount = balanceOf(_owner);

		uint256[] memory tokenIds = new uint256[](tokenCount);
		for (uint256 i = 0; i < tokenCount; i++) {
			tokenIds[i] = tokenOfOwnerByIndex(_owner, i);
		}

		return tokenIds;
	}

	function _beforeTokenTransfer(
		address from,
		address to,
		uint256 tokenId
	) internal virtual override(ERC721, ERC721Enumerable, ERC721Pausable) {
		super._beforeTokenTransfer(from, to, tokenId);
	}

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

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"baseURI","type":"string"},{"internalType":"address payable","name":"_developer","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":[],"name":"BaseURIUpdated","type":"event"},{"anonymous":false,"inputs":[],"name":"MintPriceUpdated","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":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"uint256","name":"id","type":"uint256"}],"name":"PolyPupPunkMinted","type":"event"},{"anonymous":false,"inputs":[],"name":"SaleBegins","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":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"MAX_MINT_AT_ONCE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"TOKEN_LIMIT","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"baseTokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"burn","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"developer","outputs":[{"internalType":"address payable","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getCurrentBalanceQSPair","outputs":[{"internalType":"uint256","name":"","type":"uint256"},{"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":[{"internalType":"uint256","name":"_count","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"mintPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pairAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bool","name":"val","type":"bool"}],"name":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_count","type":"uint256"}],"name":"price","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_price","type":"uint256"}],"name":"setMintPrice","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalMint","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"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":"_owner","type":"address"}],"name":"walletOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"}]

60a06040526801a055690d9db80000600d5560006010553480156200002357600080fd5b5060405162005c9b38038062005c9b83398181016040528101906200004991906200071e565b6040518060400160405280600f81526020017f46616e746f6d5075702050756e6b7300000000000000000000000000000000008152506040518060400160405280600781526020017f50555050554e4b000000000000000000000000000000000000000000000000008152508160009080519060200190620000cd929190620005e5565b508060019080519060200190620000e6929190620005e5565b5050506000600660006101000a81548160ff0219169083151502179055506200012462000118620001a960201b60201c565b620001b160201b60201c565b6001600b819055506200013d826200027760201b60201c565b8073ffffffffffffffffffffffffffffffffffffffff1660808173ffffffffffffffffffffffffffffffffffffffff1660601b815250506200018660016200034e60201b60201c565b6000600c60006101000a81548160ff021916908315150217905550505062000adf565b600033905090565b6000600660019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b62000287620001a960201b60201c565b73ffffffffffffffffffffffffffffffffffffffff16620002ad6200043560201b60201c565b73ffffffffffffffffffffffffffffffffffffffff161462000306576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620002fd906200085f565b60405180910390fd5b80600e90805190602001906200031e929190620005e5565b507fa1731ca444c73d019f0dbb4ee5546c98730f4ffcdaa1c29776ab542aa64d5e1b60405160405180910390a150565b6200035e620001a960201b60201c565b73ffffffffffffffffffffffffffffffffffffffff16620003846200043560201b60201c565b73ffffffffffffffffffffffffffffffffffffffff1614620003dd576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620003d4906200085f565b60405180910390fd5b6001151581151514801562000405575060001515600c60009054906101000a900460ff161515145b1562000421576200041b6200045f60201b60201c565b62000432565b620004316200051760201b60201c565b5b50565b6000600660019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6200046f620005ce60201b60201c565b15620004b2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401620004a9906200083d565b60405180910390fd5b6001600660006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258620004fe620001a960201b60201c565b6040516200050d9190620007fe565b60405180910390a1565b62000527620005ce60201b60201c565b62000569576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040162000560906200081b565b60405180910390fd5b6000600660006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa620005b5620001a960201b60201c565b604051620005c49190620007fe565b60405180910390a1565b6000600660009054906101000a900460ff16905090565b828054620005f3906200096f565b90600052602060002090601f01602090048101928262000617576000855562000663565b82601f106200063257805160ff191683800117855562000663565b8280016001018555821562000663579182015b828111156200066257825182559160200191906001019062000645565b5b50905062000672919062000676565b5090565b5b808211156200069157600081600090555060010162000677565b5090565b6000620006ac620006a684620008aa565b62000881565b905082815260208101848484011115620006c557600080fd5b620006d284828562000939565b509392505050565b600081519050620006eb8162000ac5565b92915050565b600082601f8301126200070357600080fd5b81516200071584826020860162000695565b91505092915050565b600080604083850312156200073257600080fd5b600083015167ffffffffffffffff8111156200074d57600080fd5b6200075b85828601620006f1565b92505060206200076e85828601620006da565b9150509250929050565b6200078381620008f1565b82525050565b600062000798601483620008e0565b9150620007a58262000a4a565b602082019050919050565b6000620007bf601083620008e0565b9150620007cc8262000a73565b602082019050919050565b6000620007e6602083620008e0565b9150620007f38262000a9c565b602082019050919050565b600060208201905062000815600083018462000778565b92915050565b60006020820190508181036000830152620008368162000789565b9050919050565b600060208201905081810360008301526200085881620007b0565b9050919050565b600060208201905081810360008301526200087a81620007d7565b9050919050565b60006200088d620008a0565b90506200089b8282620009a5565b919050565b6000604051905090565b600067ffffffffffffffff821115620008c857620008c762000a0a565b5b620008d38262000a39565b9050602081019050919050565b600082825260208201905092915050565b6000620008fe8262000919565b9050919050565b6000620009128262000919565b9050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b60005b83811015620009595780820151818401526020810190506200093c565b8381111562000969576000848401525b50505050565b600060028204905060018216806200098857607f821691505b602082108114156200099f576200099e620009db565b5b50919050565b620009b08262000a39565b810181811067ffffffffffffffff82111715620009d257620009d162000a0a565b5b80604052505050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b62000ad08162000905565b811462000adc57600080fd5b50565b60805160601c61519662000b0560003960008181611492015261180d01526151966000f3fe60806040526004361061020f5760003560e01c80636352211e11610118578063b66a0e5d116100a0578063d547cfb71161006f578063d547cfb7146107a4578063e825b213146107cf578063e985e9c5146107fb578063f2fde38b14610838578063f4a0a528146108615761020f565b8063b66a0e5d146106fc578063b88d4fde14610713578063c87b56dd1461073c578063ca4b208b146107795761020f565b80638da5cb5b116100e75780638da5cb5b1461063657806395d89b4114610661578063a0712d681461068c578063a22cb465146106a8578063a8b08982146106d15761020f565b80636352211e1461057a5780636817c76c146105b757806370a08231146105e2578063715018a61461061f5761020f565b806326a49e371161019b578063438b63001161016a578063438b6300146104815780634f6ccce7146104be57806355f804b3146104fb57806359a7715a146105245780635c975abb1461054f5761020f565b806326a49e37146103b55780632f745c59146103f257806342842e0e1461042f57806342966c68146104585761020f565b806306fdde03116101e257806306fdde03146102d0578063081812fc146102fb578063095ea7b31461033857806318160ddd1461036157806323b872dd1461038c5761020f565b806301ffc9a71461021457806302329a2914610251578063031bd4c41461027a57806305394dcc146102a5575b600080fd5b34801561022057600080fd5b5061023b600480360381019061023691906137af565b61088a565b6040516102489190614055565b60405180910390f35b34801561025d57600080fd5b5061027860048036038101906102739190613786565b61089c565b005b34801561028657600080fd5b5061028f61095d565b60405161029c9190614452565b60405180910390f35b3480156102b157600080fd5b506102ba610963565b6040516102c79190614452565b60405180910390f35b3480156102dc57600080fd5b506102e5610968565b6040516102f29190614070565b60405180910390f35b34801561030757600080fd5b50610322600480360381019061031d9190613891565b6109fa565b60405161032f9190613fb1565b60405180910390f35b34801561034457600080fd5b5061035f600480360381019061035a919061374a565b610a7f565b005b34801561036d57600080fd5b50610376610b97565b6040516103839190614452565b60405180910390f35b34801561039857600080fd5b506103b360048036038101906103ae9190613644565b610ba4565b005b3480156103c157600080fd5b506103dc60048036038101906103d79190613891565b610c04565b6040516103e99190614452565b60405180910390f35b3480156103fe57600080fd5b506104196004803603810190610414919061374a565b610c1b565b6040516104269190614452565b60405180910390f35b34801561043b57600080fd5b5061045660048036038101906104519190613644565b610cc0565b005b34801561046457600080fd5b5061047f600480360381019061047a9190613891565b610ce0565b005b34801561048d57600080fd5b506104a860048036038101906104a391906135df565b610d3c565b6040516104b59190614033565b60405180910390f35b3480156104ca57600080fd5b506104e560048036038101906104e09190613891565b610e36565b6040516104f29190614452565b60405180910390f35b34801561050757600080fd5b50610522600480360381019061051d9190613801565b610ecd565b005b34801561053057600080fd5b50610539610f8f565b6040516105469190614452565b60405180910390f35b34801561055b57600080fd5b50610564610f9e565b6040516105719190614055565b60405180910390f35b34801561058657600080fd5b506105a1600480360381019061059c9190613891565b610fb5565b6040516105ae9190613fb1565b60405180910390f35b3480156105c357600080fd5b506105cc611067565b6040516105d99190614452565b60405180910390f35b3480156105ee57600080fd5b50610609600480360381019061060491906135df565b61106d565b6040516106169190614452565b60405180910390f35b34801561062b57600080fd5b50610634611125565b005b34801561064257600080fd5b5061064b6111ad565b6040516106589190613fb1565b60405180910390f35b34801561066d57600080fd5b506106766111d7565b6040516106839190614070565b60405180910390f35b6106a660048036038101906106a19190613891565b611269565b005b3480156106b457600080fd5b506106cf60048036038101906106ca919061370e565b6114c3565b005b3480156106dd57600080fd5b506106e6611644565b6040516106f39190613fb1565b60405180910390f35b34801561070857600080fd5b5061071161165c565b005b34801561071f57600080fd5b5061073a60048036038101906107359190613693565b61172b565b005b34801561074857600080fd5b50610763600480360381019061075e9190613891565b61178d565b6040516107709190614070565b60405180910390f35b34801561078557600080fd5b5061078e61180b565b60405161079b9190613fcc565b60405180910390f35b3480156107b057600080fd5b506107b961182f565b6040516107c69190614070565b60405180910390f35b3480156107db57600080fd5b506107e46118bd565b6040516107f292919061446d565b60405180910390f35b34801561080757600080fd5b50610822600480360381019061081d9190613608565b61198c565b60405161082f9190614055565b60405180910390f35b34801561084457600080fd5b5061085f600480360381019061085a91906135df565b611a20565b005b34801561086d57600080fd5b5061088860048036038101906108839190613891565b611b18565b005b600061089582611bca565b9050919050565b6108a4611c44565b73ffffffffffffffffffffffffffffffffffffffff166108c26111ad565b73ffffffffffffffffffffffffffffffffffffffff1614610918576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161090f90614312565b60405180910390fd5b6001151581151514801561093f575060001515600c60009054906101000a900460ff161515145b156109515761094c611c4c565b61095a565b610959611cef565b5b50565b6115b381565b600a81565b606060008054610977906147c0565b80601f01602080910402602001604051908101604052809291908181526020018280546109a3906147c0565b80156109f05780601f106109c5576101008083540402835291602001916109f0565b820191906000526020600020905b8154815290600101906020018083116109d357829003601f168201915b5050505050905090565b6000610a0582611d91565b610a44576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a3b906142f2565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610a8a82610fb5565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610afb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610af290614392565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610b1a611c44565b73ffffffffffffffffffffffffffffffffffffffff161480610b495750610b4881610b43611c44565b61198c565b5b610b88576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b7f90614272565b60405180910390fd5b610b928383611dfd565b505050565b6000600980549050905090565b610bb5610baf611c44565b82611eb6565b610bf4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610beb906143d2565b60405180910390fd5b610bff838383611f94565b505050565b600081600d54610c149190614640565b9050919050565b6000610c268361106d565b8210610c67576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c5e906140f2565b60405180910390fd5b600760008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002054905092915050565b610cdb8383836040518060200160405280600081525061172b565b505050565b610cf1610ceb611c44565b82611eb6565b610d30576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d2790614432565b60405180910390fd5b610d39816121f0565b50565b60606000610d498361106d565b905060008167ffffffffffffffff811115610d8d577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b604051908082528060200260200182016040528015610dbb5781602001602082028036833780820191505090505b50905060005b82811015610e2b57610dd38582610c1b565b828281518110610e0c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010181815250508080610e2390614823565b915050610dc1565b508092505050919050565b6000610e40610b97565b8210610e81576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e78906143f2565b60405180910390fd5b60098281548110610ebb577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002001549050919050565b610ed5611c44565b73ffffffffffffffffffffffffffffffffffffffff16610ef36111ad565b73ffffffffffffffffffffffffffffffffffffffff1614610f49576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f4090614312565b60405180910390fd5b80600e9080519060200190610f5f9291906133d9565b507fa1731ca444c73d019f0dbb4ee5546c98730f4ffcdaa1c29776ab542aa64d5e1b60405160405180910390a150565b6000610f99612301565b905090565b6000600660009054906101000a900460ff16905090565b6000806002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff16141561105e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611055906142b2565b60405180910390fd5b80915050919050565b600d5481565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156110de576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016110d590614292565b60405180910390fd5b600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020549050919050565b61112d611c44565b73ffffffffffffffffffffffffffffffffffffffff1661114b6111ad565b73ffffffffffffffffffffffffffffffffffffffff16146111a1576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119890614312565b60405180910390fd5b6111ab6000612312565b565b6000600660019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b6060600180546111e6906147c0565b80601f0160208091040260200160405190810160405280929190818152602001828054611212906147c0565b801561125f5780601f106112345761010080835404028352916020019161125f565b820191906000526020600020905b81548152906001019060200180831161124257829003601f168201915b5050505050905090565b6002600b5414156112af576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112a690614412565b60405180910390fd5b6002600b8190555060006112c1612301565b905060011515600c60009054906101000a900460ff16151514611319576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611310906143b2565b60405180910390fd5b6115b3828261132891906145b9565b1115611369576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611360906141f2565b60405180910390fd5b600a8211156113ad576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113a4906140d2565b60405180910390fd5b6113b682610c04565b34146113f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016113ee90614352565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff163273ffffffffffffffffffffffffffffffffffffffff1614611465576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161145c90614372565b60405180910390fd5b60005b8281101561148c57611479336123d8565b808061148490614823565b915050611468565b506114b77f000000000000000000000000000000000000000000000000000000000000000034612429565b506001600b8190555050565b6114cb611c44565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611539576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611530906141b2565b60405180910390fd5b8060056000611546611c44565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166115f3611c44565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516116389190614055565b60405180910390a35050565b73a572bdf049382f1f98f9a430788dadd51a30396981565b611664611c44565b73ffffffffffffffffffffffffffffffffffffffff166116826111ad565b73ffffffffffffffffffffffffffffffffffffffff16146116d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016116cf90614312565b60405180910390fd5b6001600c60006101000a81548160ff0219169083151502179055506116fd600061089c565b7f771cfe172460b7d64cc46cca57a1e1f40f52b47cf1d16fe30c78a2935b3dd58060405160405180910390a1565b61173c611736611c44565b83611eb6565b61177b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611772906143d2565b60405180910390fd5b6117878484848461251d565b50505050565b60608161179981611d91565b6117d8576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016117cf90614172565b60405180910390fd5b600e6117e384612579565b6040516020016117f4929190613f08565b604051602081830303815290604052915050919050565b7f000000000000000000000000000000000000000000000000000000000000000081565b600e805461183c906147c0565b80601f0160208091040260200160405190810160405280929190818152602001828054611868906147c0565b80156118b55780601f1061188a576101008083540402835291602001916118b5565b820191906000526020600020905b81548152906001019060200180831161189857829003601f168201915b505050505081565b600080600073a572bdf049382f1f98f9a430788dadd51a30396990506000808273ffffffffffffffffffffffffffffffffffffffff16630902f1ac6040518163ffffffff1660e01b815260040160606040518083038186803b15801561192257600080fd5b505afa158015611936573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061195a9190613842565b506dffffffffffffffffffffffffffff1691506dffffffffffffffffffffffffffff1691508181945094505050509091565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b611a28611c44565b73ffffffffffffffffffffffffffffffffffffffff16611a466111ad565b73ffffffffffffffffffffffffffffffffffffffff1614611a9c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a9390614312565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611b0c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b0390614132565b60405180910390fd5b611b1581612312565b50565b611b20611c44565b73ffffffffffffffffffffffffffffffffffffffff16611b3e6111ad565b73ffffffffffffffffffffffffffffffffffffffff1614611b94576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b8b90614312565b60405180910390fd5b80600d819055507f093eeb4ffef1f103746759abc772fa9098af7ad32353b2abd9e1fb703e8a913b60405160405180910390a150565b60007f780e9d63000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161480611c3d5750611c3c82612726565b5b9050919050565b600033905090565b611c54610f9e565b15611c94576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611c8b90614252565b60405180910390fd5b6001600660006101000a81548160ff0219169083151502179055507f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611cd8611c44565b604051611ce59190613fb1565b60405180910390a1565b611cf7610f9e565b611d36576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d2d906140b2565b60405180910390fd5b6000600660006101000a81548160ff0219169083151502179055507f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa611d7a611c44565b604051611d879190613fb1565b60405180910390a1565b60008073ffffffffffffffffffffffffffffffffffffffff166002600084815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1614159050919050565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611e7083610fb5565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611ec182611d91565b611f00576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ef790614232565b60405180910390fd5b6000611f0b83610fb5565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611f7a57508373ffffffffffffffffffffffffffffffffffffffff16611f62846109fa565b73ffffffffffffffffffffffffffffffffffffffff16145b80611f8b5750611f8a818561198c565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611fb482610fb5565b73ffffffffffffffffffffffffffffffffffffffff161461200a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161200190614332565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561207a576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161207190614192565b60405180910390fd5b612085838383612808565b612090600082611dfd565b6001600360008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008282546120e0919061469a565b925050819055506001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461213791906145b9565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60006121fb82610fb5565b905061220981600084612808565b612214600083611dfd565b6001600360008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206000828254612264919061469a565b925050819055506002600083815260200190815260200160002060006101000a81549073ffffffffffffffffffffffffffffffffffffffff021916905581600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600061230d600f612818565b905090565b6000600660019054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905081600660016101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508173ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35050565b60006123e2612826565b90506123ee600f612a7f565b6123f88282612a95565b807f0b4f7fd7d572650e7234b9e49323857217a4bc3821ea6fca0839ed26e044e83960405160405180910390a25050565b8047101561246c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161246390614212565b60405180910390fd5b60008273ffffffffffffffffffffffffffffffffffffffff168260405161249290613f2c565b60006040518083038185875af1925050503d80600081146124cf576040519150601f19603f3d011682016040523d82523d6000602084013e6124d4565b606091505b5050905080612518576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161250f906141d2565b60405180910390fd5b505050565b612528848484611f94565b61253484848484612ab3565b612573576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161256a90614112565b60405180910390fd5b50505050565b606060008214156125c1576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612721565b600082905060005b600082146125f35780806125dc90614823565b915050600a826125ec919061460f565b91506125c9565b60008167ffffffffffffffff811115612635577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156126675781602001600182028036833780820191505090505b5090505b6000851461271a57600182612680919061469a565b9150600a8561268f919061489a565b603061269b91906145b9565b60f81b8183815181106126d7577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a85612713919061460f565b945061266b565b8093505050505b919050565b60007f80ac58cd000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614806127f157507f5b5e139f000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916145b80612801575061280082612c4a565b5b9050919050565b612813838383612cb4565b505050565b600081600001549050919050565b600080612833600f612818565b6115b3612840919061469a565b905060008061284d6118bd565b91509150600083601054338585444260405160200161287196959493929190613f41565b6040516020818303038152906040528051906020012060001c612894919061489a565b90506000806011836115b381106128d4577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b01541461291f576011826115b38110612916577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b01549050612923565b8190505b60006011600187612934919061469a565b6115b3811061296c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b015414156129c657600185612981919061469a565b6011836115b381106129bc577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b0181905550612a50565b60116001866129d5919061469a565b6115b38110612a0d577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b01546011836115b38110612a4a577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b01819055505b60106000815480929190612a6390614823565b9190505550600181612a7591906145b9565b9550505050505090565b6001816000016000828254019250508190555050565b612aaf828260405180602001604052806000815250612dc8565b5050565b6000612ad48473ffffffffffffffffffffffffffffffffffffffff16612e23565b15612c3d578373ffffffffffffffffffffffffffffffffffffffff1663150b7a02612afd611c44565b8786866040518563ffffffff1660e01b8152600401612b1f9493929190613fe7565b602060405180830381600087803b158015612b3957600080fd5b505af1925050508015612b6a57506040513d601f19601f82011682018060405250810190612b6791906137d8565b60015b612bed573d8060008114612b9a576040519150601f19603f3d011682016040523d82523d6000602084013e612b9f565b606091505b50600081511415612be5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612bdc90614112565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614915050612c42565b600190505b949350505050565b60007f01ffc9a7000000000000000000000000000000000000000000000000000000007bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916827bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916149050919050565b612cbf838383612e36565b600073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415612d0257612cfd81612e8e565b612d41565b8173ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614612d4057612d3f8382612ed7565b5b5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612d8457612d7f81613044565b612dc3565b8273ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614612dc257612dc18282613187565b5b5b505050565b612dd28383613206565b612ddf6000848484612ab3565b612e1e576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e1590614112565b60405180910390fd5b505050565b600080823b905060008111915050919050565b612e418383836133d4565b612e49610f9e565b15612e89576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612e8090614092565b60405180910390fd5b505050565b600980549050600a600083815260200190815260200160002081905550600981908060018154018082558091505060019003906000526020600020016000909190919091505550565b60006001612ee48461106d565b612eee919061469a565b9050600060086000848152602001908152602001600020549050818114612fd3576000600760008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002054905080600760008773ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600084815260200190815260200160002081905550816008600083815260200190815260200160002081905550505b6008600084815260200190815260200160002060009055600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008381526020019081526020016000206000905550505050565b60006001600980549050613058919061469a565b90506000600a60008481526020019081526020016000205490506000600983815481106130ae577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080600983815481106130f6577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020018190555081600a600083815260200190815260200160002081905550600a600085815260200190815260200160002060009055600980548061316b577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b6001900381819060005260206000200160009055905550505050565b60006131928361106d565b905081600760008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600083815260200190815260200160002081905550806008600084815260200190815260200160002081905550505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415613276576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161326d906142d2565b60405180910390fd5b61327f81611d91565b156132bf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016132b690614152565b60405180910390fd5b6132cb60008383612808565b6001600360008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff168152602001908152602001600020600082825461331b91906145b9565b92505081905550816002600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b505050565b8280546133e5906147c0565b90600052602060002090601f016020900481019282613407576000855561344e565b82601f1061342057805160ff191683800117855561344e565b8280016001018555821561344e579182015b8281111561344d578251825591602001919060010190613432565b5b50905061345b919061345f565b5090565b5b80821115613478576000816000905550600101613460565b5090565b600061348f61348a846144bb565b614496565b9050828152602081018484840111156134a757600080fd5b6134b284828561477e565b509392505050565b60006134cd6134c8846144ec565b614496565b9050828152602081018484840111156134e557600080fd5b6134f084828561477e565b509392505050565b600081359050613507816150d6565b92915050565b60008135905061351c816150ed565b92915050565b60008135905061353181615104565b92915050565b60008151905061354681615104565b92915050565b600082601f83011261355d57600080fd5b813561356d84826020860161347c565b91505092915050565b600082601f83011261358757600080fd5b81356135978482602086016134ba565b91505092915050565b6000815190506135af8161511b565b92915050565b6000813590506135c481615132565b92915050565b6000815190506135d981615149565b92915050565b6000602082840312156135f157600080fd5b60006135ff848285016134f8565b91505092915050565b6000806040838503121561361b57600080fd5b6000613629858286016134f8565b925050602061363a858286016134f8565b9150509250929050565b60008060006060848603121561365957600080fd5b6000613667868287016134f8565b9350506020613678868287016134f8565b9250506040613689868287016135b5565b9150509250925092565b600080600080608085870312156136a957600080fd5b60006136b7878288016134f8565b94505060206136c8878288016134f8565b93505060406136d9878288016135b5565b925050606085013567ffffffffffffffff8111156136f657600080fd5b6137028782880161354c565b91505092959194509250565b6000806040838503121561372157600080fd5b600061372f858286016134f8565b92505060206137408582860161350d565b9150509250929050565b6000806040838503121561375d57600080fd5b600061376b858286016134f8565b925050602061377c858286016135b5565b9150509250929050565b60006020828403121561379857600080fd5b60006137a68482850161350d565b91505092915050565b6000602082840312156137c157600080fd5b60006137cf84828501613522565b91505092915050565b6000602082840312156137ea57600080fd5b60006137f884828501613537565b91505092915050565b60006020828403121561381357600080fd5b600082013567ffffffffffffffff81111561382d57600080fd5b61383984828501613576565b91505092915050565b60008060006060848603121561385757600080fd5b6000613865868287016135a0565b9350506020613876868287016135a0565b9250506040613887868287016135ca565b9150509250925092565b6000602082840312156138a357600080fd5b60006138b1848285016135b5565b91505092915050565b60006138c68383613ed3565b60208301905092915050565b6138db816146e0565b82525050565b6138ea816146ce565b82525050565b6139016138fc826146ce565b61486c565b82525050565b600061391282614542565b61391c8185614570565b93506139278361451d565b8060005b8381101561395857815161393f88826138ba565b975061394a83614563565b92505060018101905061392b565b5085935050505092915050565b61396e816146f2565b82525050565b600061397f8261454d565b6139898185614581565b935061399981856020860161478d565b6139a281614987565b840191505092915050565b60006139b882614558565b6139c2818561459d565b93506139d281856020860161478d565b6139db81614987565b840191505092915050565b60006139f182614558565b6139fb81856145ae565b9350613a0b81856020860161478d565b80840191505092915050565b60008154613a24816147c0565b613a2e81866145ae565b94506001821660008114613a495760018114613a5a57613a8d565b60ff19831686528186019350613a8d565b613a638561452d565b60005b83811015613a8557815481890152600182019150602081019050613a66565b838801955050505b50505092915050565b6000613aa3602b8361459d565b9150613aae826149a5565b604082019050919050565b6000613ac660148361459d565b9150613ad1826149f4565b602082019050919050565b6000613ae9600e8361459d565b9150613af482614a1d565b602082019050919050565b6000613b0c602b8361459d565b9150613b1782614a46565b604082019050919050565b6000613b2f60328361459d565b9150613b3a82614a95565b604082019050919050565b6000613b5260268361459d565b9150613b5d82614ae4565b604082019050919050565b6000613b75601c8361459d565b9150613b8082614b33565b602082019050919050565b6000613b98600e8361459d565b9150613ba382614b5c565b602082019050919050565b6000613bbb60248361459d565b9150613bc682614b85565b604082019050919050565b6000613bde60198361459d565b9150613be982614bd4565b602082019050919050565b6000613c01603a8361459d565b9150613c0c82614bfd565b604082019050919050565b6000613c2460098361459d565b9150613c2f82614c4c565b602082019050919050565b6000613c47601d8361459d565b9150613c5282614c75565b602082019050919050565b6000613c6a602c8361459d565b9150613c7582614c9e565b604082019050919050565b6000613c8d60108361459d565b9150613c9882614ced565b602082019050919050565b6000613cb060388361459d565b9150613cbb82614d16565b604082019050919050565b6000613cd3602a8361459d565b9150613cde82614d65565b604082019050919050565b6000613cf660298361459d565b9150613d0182614db4565b604082019050919050565b6000613d1960208361459d565b9150613d2482614e03565b602082019050919050565b6000613d3c602c8361459d565b9150613d4782614e2c565b604082019050919050565b6000613d5f60208361459d565b9150613d6a82614e7b565b602082019050919050565b6000613d8260298361459d565b9150613d8d82614ea4565b604082019050919050565b6000613da560118361459d565b9150613db082614ef3565b602082019050919050565b6000613dc8601b8361459d565b9150613dd382614f1c565b602082019050919050565b6000613deb60218361459d565b9150613df682614f45565b604082019050919050565b6000613e0e60188361459d565b9150613e1982614f94565b602082019050919050565b6000613e31600083614592565b9150613e3c82614fbd565b600082019050919050565b6000613e5460318361459d565b9150613e5f82614fc0565b604082019050919050565b6000613e77602c8361459d565b9150613e828261500f565b604082019050919050565b6000613e9a601f8361459d565b9150613ea58261505e565b602082019050919050565b6000613ebd60308361459d565b9150613ec882615087565b604082019050919050565b613edc81614764565b82525050565b613eeb81614764565b82525050565b613f02613efd82614764565b614890565b82525050565b6000613f148285613a17565b9150613f2082846139e6565b91508190509392505050565b6000613f3782613e24565b9150819050919050565b6000613f4d8289613ef1565b602082019150613f5d82886138f0565b601482019150613f6d8287613ef1565b602082019150613f7d8286613ef1565b602082019150613f8d8285613ef1565b602082019150613f9d8284613ef1565b602082019150819050979650505050505050565b6000602082019050613fc660008301846138e1565b92915050565b6000602082019050613fe160008301846138d2565b92915050565b6000608082019050613ffc60008301876138e1565b61400960208301866138e1565b6140166040830185613ee2565b81810360608301526140288184613974565b905095945050505050565b6000602082019050818103600083015261404d8184613907565b905092915050565b600060208201905061406a6000830184613965565b92915050565b6000602082019050818103600083015261408a81846139ad565b905092915050565b600060208201905081810360008301526140ab81613a96565b9050919050565b600060208201905081810360008301526140cb81613ab9565b9050919050565b600060208201905081810360008301526140eb81613adc565b9050919050565b6000602082019050818103600083015261410b81613aff565b9050919050565b6000602082019050818103600083015261412b81613b22565b9050919050565b6000602082019050818103600083015261414b81613b45565b9050919050565b6000602082019050818103600083015261416b81613b68565b9050919050565b6000602082019050818103600083015261418b81613b8b565b9050919050565b600060208201905081810360008301526141ab81613bae565b9050919050565b600060208201905081810360008301526141cb81613bd1565b9050919050565b600060208201905081810360008301526141eb81613bf4565b9050919050565b6000602082019050818103600083015261420b81613c17565b9050919050565b6000602082019050818103600083015261422b81613c3a565b9050919050565b6000602082019050818103600083015261424b81613c5d565b9050919050565b6000602082019050818103600083015261426b81613c80565b9050919050565b6000602082019050818103600083015261428b81613ca3565b9050919050565b600060208201905081810360008301526142ab81613cc6565b9050919050565b600060208201905081810360008301526142cb81613ce9565b9050919050565b600060208201905081810360008301526142eb81613d0c565b9050919050565b6000602082019050818103600083015261430b81613d2f565b9050919050565b6000602082019050818103600083015261432b81613d52565b9050919050565b6000602082019050818103600083015261434b81613d75565b9050919050565b6000602082019050818103600083015261436b81613d98565b9050919050565b6000602082019050818103600083015261438b81613dbb565b9050919050565b600060208201905081810360008301526143ab81613dde565b9050919050565b600060208201905081810360008301526143cb81613e01565b9050919050565b600060208201905081810360008301526143eb81613e47565b9050919050565b6000602082019050818103600083015261440b81613e6a565b9050919050565b6000602082019050818103600083015261442b81613e8d565b9050919050565b6000602082019050818103600083015261444b81613eb0565b9050919050565b60006020820190506144676000830184613ee2565b92915050565b60006040820190506144826000830185613ee2565b61448f6020830184613ee2565b9392505050565b60006144a06144b1565b90506144ac82826147f2565b919050565b6000604051905090565b600067ffffffffffffffff8211156144d6576144d5614958565b5b6144df82614987565b9050602081019050919050565b600067ffffffffffffffff82111561450757614506614958565b5b61451082614987565b9050602081019050919050565b6000819050602082019050919050565b60008190508160005260206000209050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b60006145c482614764565b91506145cf83614764565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115614604576146036148cb565b5b828201905092915050565b600061461a82614764565b915061462583614764565b925082614635576146346148fa565b5b828204905092915050565b600061464b82614764565b915061465683614764565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561468f5761468e6148cb565b5b828202905092915050565b60006146a582614764565b91506146b083614764565b9250828210156146c3576146c26148cb565b5b828203905092915050565b60006146d982614744565b9050919050565b60006146eb82614744565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b60006dffffffffffffffffffffffffffff82169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b600063ffffffff82169050919050565b82818337600083830152505050565b60005b838110156147ab578082015181840152602081019050614790565b838111156147ba576000848401525b50505050565b600060028204905060018216806147d857607f821691505b602082108114156147ec576147eb614929565b5b50919050565b6147fb82614987565b810181811067ffffffffffffffff8211171561481a57614819614958565b5b80604052505050565b600061482e82614764565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415614861576148606148cb565b5b600182019050919050565b60006148778261487e565b9050919050565b600061488982614998565b9050919050565b6000819050919050565b60006148a582614764565b91506148b083614764565b9250826148c0576148bf6148fa565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b60008160601b9050919050565b7f4552433732315061757361626c653a20746f6b656e207472616e73666572207760008201527f68696c6520706175736564000000000000000000000000000000000000000000602082015250565b7f5061757361626c653a206e6f7420706175736564000000000000000000000000600082015250565b7f45786365656473206e756d626572000000000000000000000000000000000000600082015250565b7f455243373231456e756d657261626c653a206f776e657220696e646578206f7560008201527f74206f6620626f756e6473000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f496e76616c696420746f6b656e2e000000000000000000000000000000000000600082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260008201527f6563697069656e74206d61792068617665207265766572746564000000000000602082015250565b7f4d6178206c696d69740000000000000000000000000000000000000000000000600082015250565b7f416464726573733a20696e73756666696369656e742062616c616e6365000000600082015250565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f5061757361626c653a2070617573656400000000000000000000000000000000600082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b7f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460008201527f656e7420746f6b656e0000000000000000000000000000000000000000000000602082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008201527f73206e6f74206f776e0000000000000000000000000000000000000000000000602082015250565b7f56616c75652062656c6f77207072696365000000000000000000000000000000600082015250565b7f43616c6c65722063616e6e6f74206265206120636f6e74726163740000000000600082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f53616c6520686173206e6f742079657420737461727465640000000000000000600082015250565b50565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b7f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60008201527f7574206f6620626f756e64730000000000000000000000000000000000000000602082015250565b7f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00600082015250565b7f4552433732314275726e61626c653a2063616c6c6572206973206e6f74206f7760008201527f6e6572206e6f7220617070726f76656400000000000000000000000000000000602082015250565b6150df816146ce565b81146150ea57600080fd5b50565b6150f6816146f2565b811461510157600080fd5b50565b61510d816146fe565b811461511857600080fd5b50565b6151248161472a565b811461512f57600080fd5b50565b61513b81614764565b811461514657600080fd5b50565b6151528161476e565b811461515d57600080fd5b5056fea2646970667358221220f9458170a6432b69cbea145dd57c4645abc95558315f6ba3645b747d55f363ce64736f6c634300080400330000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000022e72098480a4fbf0412c9c70c6a90162c4a000000000000000000000000000000000000000000000000000000000000002b68747470733a2f2f70757070756e6b732e73332e616d617a6f6e6177732e636f6d2f66746d2f6a736f6e2f000000000000000000000000000000000000000000

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

0000000000000000000000000000000000000000000000000000000000000040000000000000000000000000000022e72098480a4fbf0412c9c70c6a90162c4a000000000000000000000000000000000000000000000000000000000000002b68747470733a2f2f70757070756e6b732e73332e616d617a6f6e6177732e636f6d2f66746d2f6a736f6e2f000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : baseURI (string): https://puppunks.s3.amazonaws.com/ftm/json/
Arg [1] : _developer (address): 0x000022e72098480a4fbf0412c9c70c6a90162c4a

-----Encoded View---------------
5 Constructor Arguments found :
Arg [0] : 0000000000000000000000000000000000000000000000000000000000000040
Arg [1] : 000000000000000000000000000022e72098480a4fbf0412c9c70c6a90162c4a
Arg [2] : 000000000000000000000000000000000000000000000000000000000000002b
Arg [3] : 68747470733a2f2f70757070756e6b732e73332e616d617a6f6e6177732e636f
Arg [4] : 6d2f66746d2f6a736f6e2f000000000000000000000000000000000000000000


Deployed ByteCode Sourcemap

56488:6238:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62536:187;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;61772:185;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;56669:42;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56754:45;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32360:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33919:221;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;33442:411;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;45108:113;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;34809:339;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;60635:96;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;44776:256;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;35219:185;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;51954:245;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;61995:322;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;45298:233;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60997:118;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;60488:84;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;11502:86;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32054:239;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56715:35;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;31784:208;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;9799:94;;;;;;;;;;;;;:::i;:::-;;9148:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;32529:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58293:564;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;34212:295;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57027:83;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57754:100;;;;;;;;;;;;;:::i;:::-;;35475:328;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;61458:269;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56803:42;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56849:26;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;60167:264;;;;;;;;;;;;;:::i;:::-;;;;;;;;:::i;:::-;;;;;;;;34578:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;10048:192;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;61191:111;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;62536:187;62662:4;62682:36;62706:11;62682:23;:36::i;:::-;62675:43;;62536:187;;;:::o;61772:185::-;9379:12;:10;:12::i;:::-;9368:23;;:7;:5;:7::i;:::-;:23;;;9360:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;61883:4:::1;61876:11;;:3;:11;;;:28;;;;;61899:5;61891:13;;:4;;;;;;;;;;;:13;;;61876:28;61872:66;;;61912:8;:6;:8::i;:::-;61926:7;;61872:66;61942:10;:8;:10::i;:::-;9439:1;61772:185:::0;:::o;56669:42::-;56707:4;56669:42;:::o;56754:45::-;56797:2;56754:45;:::o;32360:100::-;32414:13;32447:5;32440:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32360:100;:::o;33919:221::-;33995:7;34023:16;34031:7;34023;:16::i;:::-;34015:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;34108:15;:24;34124:7;34108:24;;;;;;;;;;;;;;;;;;;;;34101:31;;33919:221;;;:::o;33442:411::-;33523:13;33539:23;33554:7;33539:14;:23::i;:::-;33523:39;;33587:5;33581:11;;:2;:11;;;;33573:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;33681:5;33665:21;;:12;:10;:12::i;:::-;:21;;;:62;;;;33690:37;33707:5;33714:12;:10;:12::i;:::-;33690:16;:37::i;:::-;33665:62;33643:168;;;;;;;;;;;;:::i;:::-;;;;;;;;;33824:21;33833:2;33837:7;33824:8;:21::i;:::-;33442:411;;;:::o;45108:113::-;45169:7;45196:10;:17;;;;45189:24;;45108:113;:::o;34809:339::-;35004:41;35023:12;:10;:12::i;:::-;35037:7;35004:18;:41::i;:::-;34996:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;35112:28;35122:4;35128:2;35132:7;35112:9;:28::i;:::-;34809:339;;;:::o;60635:96::-;60687:7;60720:6;60708:9;;:18;;;;:::i;:::-;60701:25;;60635:96;;;:::o;44776:256::-;44873:7;44909:23;44926:5;44909:16;:23::i;:::-;44901:5;:31;44893:87;;;;;;;;;;;;:::i;:::-;;;;;;;;;44998:12;:19;45011:5;44998:19;;;;;;;;;;;;;;;:26;45018:5;44998:26;;;;;;;;;;;;44991:33;;44776:256;;;;:::o;35219:185::-;35357:39;35374:4;35380:2;35384:7;35357:39;;;;;;;;;;;;:16;:39::i;:::-;35219:185;;;:::o;51954:245::-;52072:41;52091:12;:10;:12::i;:::-;52105:7;52072:18;:41::i;:::-;52064:102;;;;;;;;;;;;:::i;:::-;;;;;;;;;52177:14;52183:7;52177:5;:14::i;:::-;51954:245;:::o;61995:322::-;62066:16;62091:18;62112:17;62122:6;62112:9;:17::i;:::-;62091:38;;62136:25;62178:10;62164:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;62136:53;;62199:9;62194:97;62218:10;62214:1;:14;62194:97;;;62255:30;62275:6;62283:1;62255:19;:30::i;:::-;62241:8;62250:1;62241:11;;;;;;;;;;;;;;;;;;;;;:44;;;;;62230:3;;;;;:::i;:::-;;;;62194:97;;;;62304:8;62297:15;;;;61995:322;;;:::o;45298:233::-;45373:7;45409:30;:28;:30::i;:::-;45401:5;:38;45393:95;;;;;;;;;;;;:::i;:::-;;;;;;;;;45506:10;45517:5;45506:17;;;;;;;;;;;;;;;;;;;;;;;;45499:24;;45298:233;;;:::o;60997:118::-;9379:12;:10;:12::i;:::-;9368:23;;:7;:5;:7::i;:::-;:23;;;9360:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;61077:7:::1;61062:12;:22;;;;;;;;;;;;:::i;:::-;;61094:16;;;;;;;;;;60997:118:::0;:::o;60488:84::-;60532:7;60553:14;:12;:14::i;:::-;60546:21;;60488:84;:::o;11502:86::-;11549:4;11573:7;;;;;;;;;;;11566:14;;11502:86;:::o;32054:239::-;32126:7;32146:13;32162:7;:16;32170:7;32162:16;;;;;;;;;;;;;;;;;;;;;32146:32;;32214:1;32197:19;;:5;:19;;;;32189:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;32280:5;32273:12;;;32054:239;;;:::o;56715:35::-;;;;:::o;31784:208::-;31856:7;31901:1;31884:19;;:5;:19;;;;31876:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;31968:9;:16;31978:5;31968:16;;;;;;;;;;;;;;;;31961:23;;31784:208;;;:::o;9799:94::-;9379:12;:10;:12::i;:::-;9368:23;;:7;:5;:7::i;:::-;:23;;;9360:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;9864:21:::1;9882:1;9864:9;:21::i;:::-;9799:94::o:0;9148:87::-;9194:7;9221:6;;;;;;;;;;;9214:13;;9148:87;:::o;32529:104::-;32585:13;32618:7;32611:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;32529:104;:::o;58293:564::-;4296:1;4892:7;;:19;;4884:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;4296:1;5025:7;:18;;;;58358:13:::1;58374:14;:12;:14::i;:::-;58358:30;;58409:4;58401:12;;:4;;;;;;;;;;;:12;;;58393:49;;;;;;;;;;;;:::i;:::-;;;;;;;;;56707:4;58463:6;58455:5;:14;;;;:::i;:::-;:29;;58447:51;;;;;;;;;;;;:::i;:::-;;;;;;;;;56797:2;58511:6;:26;;58503:53;;;;;;;;;;;;:::i;:::-;;;;;;;;;58582:13;58588:6;58582:5;:13::i;:::-;58569:9;:26;58561:56;;;;;;;;;;;;:::i;:::-;;;;;;;;;58643:10;58630:23;;:9;:23;;;58622:63;;;;;;;;;;;;:::i;:::-;;;;;;;;;58737:9;58732:75;58756:6;58752:1;:10;58732:75;;;58775:26;58790:10;58775:14;:26::i;:::-;58764:3;;;;;:::i;:::-;;;;58732:75;;;;58813:39;58831:9;58842;58813:17;:39::i;:::-;5056:1;4252::::0;5204:7;:22;;;;58293:564;:::o;34212:295::-;34327:12;:10;:12::i;:::-;34315:24;;:8;:24;;;;34307:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;34427:8;34382:18;:32;34401:12;:10;:12::i;:::-;34382:32;;;;;;;;;;;;;;;:42;34415:8;34382:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;34480:8;34451:48;;34466:12;:10;:12::i;:::-;34451:48;;;34490:8;34451:48;;;;;;:::i;:::-;;;;;;;;34212:295;;:::o;57027:83::-;57068:42;57027:83;:::o;57754:100::-;9379:12;:10;:12::i;:::-;9368:23;;:7;:5;:7::i;:::-;:23;;;9360:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;57806:4:::1;57799;;:11;;;;;;;;;;;;;;;;;;57815:12;57821:5;57815;:12::i;:::-;57837;;;;;;;;;;57754:100::o:0;35475:328::-;35650:41;35669:12;:10;:12::i;:::-;35683:7;35650:18;:41::i;:::-;35642:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;35756:39;35770:4;35776:2;35780:7;35789:5;35756:13;:39::i;:::-;35475:328;;;;:::o;61458:269::-;61573:13;61551:8;58177:17;58185:8;58177:7;:17::i;:::-;58169:44;;;;;;;;;;;;:::i;:::-;;;;;;;;;61680:12:::1;61694:26;61711:8;61694:16;:26::i;:::-;61663:58;;;;;;;;;:::i;:::-;;;;;;;;;;;;;61649:73;;61458:269:::0;;;;:::o;56803:42::-;;;:::o;56849:26::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;60167:264::-;60223:7;60232;60246:19;57068:42;60246:100;;60352:12;60366;60384:4;:16;;;:18;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;60351:51;;;;;;;;;60415:4;60421;60407:19;;;;;;;60167:264;;:::o;34578:164::-;34675:4;34699:18;:25;34718:5;34699:25;;;;;;;;;;;;;;;:35;34725:8;34699:35;;;;;;;;;;;;;;;;;;;;;;;;;34692:42;;34578:164;;;;:::o;10048:192::-;9379:12;:10;:12::i;:::-;9368:23;;:7;:5;:7::i;:::-;:23;;;9360:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;10157:1:::1;10137:22;;:8;:22;;;;10129:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;10213:19;10223:8;10213:9;:19::i;:::-;10048:192:::0;:::o;61191:111::-;9379:12;:10;:12::i;:::-;9368:23;;:7;:5;:7::i;:::-;:23;;;9360:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;61263:6:::1;61251:9;:18;;;;61279;;;;;;;;;;61191:111:::0;:::o;44468:224::-;44570:4;44609:35;44594:50;;;:11;:50;;;;:90;;;;44648:36;44672:11;44648:23;:36::i;:::-;44594:90;44587:97;;44468:224;;;:::o;7936:98::-;7989:7;8016:10;8009:17;;7936:98;:::o;12302:118::-;11828:8;:6;:8::i;:::-;11827:9;11819:38;;;;;;;;;;;;:::i;:::-;;;;;;;;;12372:4:::1;12362:7;;:14;;;;;;;;;;;;;;;;;;12392:20;12399:12;:10;:12::i;:::-;12392:20;;;;;;:::i;:::-;;;;;;;;12302:118::o:0;12561:120::-;12105:8;:6;:8::i;:::-;12097:41;;;;;;;;;;;;:::i;:::-;;;;;;;;;12630:5:::1;12620:7;;:15;;;;;;;;;;;;;;;;;;12651:22;12660:12;:10;:12::i;:::-;12651:22;;;;;;:::i;:::-;;;;;;;;12561:120::o:0;37313:127::-;37378:4;37430:1;37402:30;;:7;:16;37410:7;37402:16;;;;;;;;;;;;;;;;;;;;;:30;;;;37395:37;;37313:127;;;:::o;41295:174::-;41397:2;41370:15;:24;41386:7;41370:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;41453:7;41449:2;41415:46;;41424:23;41439:7;41424:14;:23::i;:::-;41415:46;;;;;;;;;;;;41295:174;;:::o;37607:348::-;37700:4;37725:16;37733:7;37725;:16::i;:::-;37717:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;37801:13;37817:23;37832:7;37817:14;:23::i;:::-;37801:39;;37870:5;37859:16;;:7;:16;;;:51;;;;37903:7;37879:31;;:20;37891:7;37879:11;:20::i;:::-;:31;;;37859:51;:87;;;;37914:32;37931:5;37938:7;37914:16;:32::i;:::-;37859:87;37851:96;;;37607:348;;;;:::o;40599:578::-;40758:4;40731:31;;:23;40746:7;40731:14;:23::i;:::-;:31;;;40723:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;40841:1;40827:16;;:2;:16;;;;40819:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;40897:39;40918:4;40924:2;40928:7;40897:20;:39::i;:::-;41001:29;41018:1;41022:7;41001:8;:29::i;:::-;41062:1;41043:9;:15;41053:4;41043:15;;;;;;;;;;;;;;;;:20;;;;;;;:::i;:::-;;;;;;;;41091:1;41074:9;:13;41084:2;41074:13;;;;;;;;;;;;;;;;:18;;;;;;;:::i;:::-;;;;;;;;41122:2;41103:7;:16;41111:7;41103:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;41161:7;41157:2;41142:27;;41151:4;41142:27;;;;;;;;;;;;40599:578;;;:::o;39902:360::-;39962:13;39978:23;39993:7;39978:14;:23::i;:::-;39962:39;;40014:48;40035:5;40050:1;40054:7;40014:20;:48::i;:::-;40103:29;40120:1;40124:7;40103:8;:29::i;:::-;40165:1;40145:9;:16;40155:5;40145:16;;;;;;;;;;;;;;;;:21;;;;;;;:::i;:::-;;;;;;;;40184:7;:16;40192:7;40184:16;;;;;;;;;;;;40177:23;;;;;;;;;;;40246:7;40242:1;40218:36;;40227:5;40218:36;;;;;;;;;;;;39902:360;;:::o;60823:98::-;60870:7;60891:25;:15;:23;:25::i;:::-;60884:32;;60823:98;:::o;10248:173::-;10304:16;10323:6;;;;;;;;;;;10304:25;;10349:8;10340:6;;:17;;;;;;;;;;;;;;;;;;10404:8;10373:40;;10394:8;10373:40;;;;;;;;;;;;10248:173;;:::o;58862:170::-;58912:10;58925:14;:12;:14::i;:::-;58912:27;;58944;:15;:25;:27::i;:::-;58978:18;58988:3;58993:2;58978:9;:18::i;:::-;59024:2;59006:21;;;;;;;;;;58862:170;;:::o;14776:317::-;14891:6;14866:21;:31;;14858:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;14945:12;14963:9;:14;;14985:6;14963:33;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14944:52;;;15015:7;15007:78;;;;;;;;;;;;:::i;:::-;;;;;;;;;14776:317;;;:::o;36685:315::-;36842:28;36852:4;36858:2;36862:7;36842:9;:28::i;:::-;36889:48;36912:4;36918:2;36922:7;36931:5;36889:22;:48::i;:::-;36881:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;36685:315;;;;:::o;5552:723::-;5608:13;5838:1;5829:5;:10;5825:53;;;5856:10;;;;;;;;;;;;;;;;;;;;;5825:53;5888:12;5903:5;5888:20;;5919:14;5944:78;5959:1;5951:4;:9;5944:78;;5977:8;;;;;:::i;:::-;;;;6008:2;6000:10;;;;;:::i;:::-;;;5944:78;;;6032:19;6064:6;6054:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6032:39;;6082:154;6098:1;6089:5;:10;6082:154;;6126:1;6116:11;;;;;:::i;:::-;;;6193:2;6185:5;:10;;;;:::i;:::-;6172:2;:24;;;;:::i;:::-;6159:39;;6142:6;6149;6142:14;;;;;;;;;;;;;;;;;;;:56;;;;;;;;;;;6222:2;6213:11;;;;;:::i;:::-;;;6082:154;;;6260:6;6246:21;;;;;5552:723;;;;:::o;31415:305::-;31517:4;31569:25;31554:40;;;:11;:40;;;;:105;;;;31626:33;31611:48;;;:11;:48;;;;31554:105;:158;;;;31676:36;31700:11;31676:23;:36::i;:::-;31554:158;31534:178;;31415:305;;;:::o;62322:209::-;62481:45;62508:4;62514:2;62518:7;62481:26;:45::i;:::-;62322:209;;;:::o;54947:114::-;55012:7;55039;:14;;;55032:21;;54947:114;;;:::o;59113:966::-;59155:7;59169:17;59203:25;:15;:23;:25::i;:::-;56707:4;59189:39;;;;:::i;:::-;59169:59;;59320:16;59338;59358:25;:23;:25::i;:::-;59319:64;;;;59388:13;59580:9;59457:5;;59470:10;59488:8;59504;59520:16;59544:15;59433:133;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;59417:155;;;;;;59404:173;;:185;;;;:::i;:::-;59388:201;;59594:13;59638:1;59620:7;59628:5;59620:14;;;;;;;;;;;;;;;;;:19;59616:90;;59655:7;59663:5;59655:14;;;;;;;;;;;;;;;;;59647:22;;59616:90;;;59695:5;59687:13;;59616:90;59785:1;59759:7;59779:1;59767:9;:13;;;;:::i;:::-;59759:22;;;;;;;;;;;;;;;;;:27;59755:235;;;59878:1;59866:9;:13;;;;:::i;:::-;59849:7;59857:5;59849:14;;;;;;;;;;;;;;;;:30;;;;59755:235;;;59962:7;59982:1;59970:9;:13;;;;:::i;:::-;59962:22;;;;;;;;;;;;;;;;;59945:7;59953:5;59945:14;;;;;;;;;;;;;;;;:39;;;;59755:235;59994:5;;:7;;;;;;;;;:::i;:::-;;;;;;60073:1;60065:5;:9;;;;:::i;:::-;60058:16;;;;;;;59113:966;:::o;55069:127::-;55176:1;55158:7;:14;;;:19;;;;;;;;;;;55069:127;:::o;38297:110::-;38373:26;38383:2;38387:7;38373:26;;;;;;;;;;;;:9;:26::i;:::-;38297:110;;:::o;42034:799::-;42189:4;42210:15;:2;:13;;;:15::i;:::-;42206:620;;;42262:2;42246:36;;;42283:12;:10;:12::i;:::-;42297:4;42303:7;42312:5;42246:72;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;42242:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42505:1;42488:6;:13;:18;42484:272;;;42531:60;;;;;;;;;;:::i;:::-;;;;;;;;42484:272;42706:6;42700:13;42691:6;42687:2;42683:15;42676:38;42242:529;42379:41;;;42369:51;;;:6;:51;;;;42362:58;;;;;42206:620;42810:4;42803:11;;42034:799;;;;;;;:::o;23394:157::-;23479:4;23518:25;23503:40;;;:11;:40;;;;23496:47;;23394:157;;;:::o;46144:589::-;46288:45;46315:4;46321:2;46325:7;46288:26;:45::i;:::-;46366:1;46350:18;;:4;:18;;;46346:187;;;46385:40;46417:7;46385:31;:40::i;:::-;46346:187;;;46455:2;46447:10;;:4;:10;;;46443:90;;46474:47;46507:4;46513:7;46474:32;:47::i;:::-;46443:90;46346:187;46561:1;46547:16;;:2;:16;;;46543:183;;;46580:45;46617:7;46580:36;:45::i;:::-;46543:183;;;46653:4;46647:10;;:2;:10;;;46643:83;;46674:40;46702:2;46706:7;46674:27;:40::i;:::-;46643:83;46543:183;46144:589;;;:::o;38634:321::-;38764:18;38770:2;38774:7;38764:5;:18::i;:::-;38815:54;38846:1;38850:2;38854:7;38863:5;38815:22;:54::i;:::-;38793:154;;;;;;;;;;;;:::i;:::-;;;;;;;;;38634:321;;;:::o;13454:387::-;13514:4;13722:12;13789:7;13777:20;13769:28;;13832:1;13825:4;:8;13818:15;;;13454:387;;;:::o;51215:275::-;51359:45;51386:4;51392:2;51396:7;51359:26;:45::i;:::-;51426:8;:6;:8::i;:::-;51425:9;51417:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;51215:275;;;:::o;47456:164::-;47560:10;:17;;;;47533:15;:24;47549:7;47533:24;;;;;;;;;;;:44;;;;47588:10;47604:7;47588:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;47456:164;:::o;48247:988::-;48513:22;48563:1;48538:22;48555:4;48538:16;:22::i;:::-;:26;;;;:::i;:::-;48513:51;;48575:18;48596:17;:26;48614:7;48596:26;;;;;;;;;;;;48575:47;;48743:14;48729:10;:28;48725:328;;48774:19;48796:12;:18;48809:4;48796:18;;;;;;;;;;;;;;;:34;48815:14;48796:34;;;;;;;;;;;;48774:56;;48880:11;48847:12;:18;48860:4;48847:18;;;;;;;;;;;;;;;:30;48866:10;48847:30;;;;;;;;;;;:44;;;;48997:10;48964:17;:30;48982:11;48964:30;;;;;;;;;;;:43;;;;48725:328;;49149:17;:26;49167:7;49149:26;;;;;;;;;;;49142:33;;;49193:12;:18;49206:4;49193:18;;;;;;;;;;;;;;;:34;49212:14;49193:34;;;;;;;;;;;49186:41;;;48247:988;;;;:::o;49530:1079::-;49783:22;49828:1;49808:10;:17;;;;:21;;;;:::i;:::-;49783:46;;49840:18;49861:15;:24;49877:7;49861:24;;;;;;;;;;;;49840:45;;50212:19;50234:10;50245:14;50234:26;;;;;;;;;;;;;;;;;;;;;;;;50212:48;;50298:11;50273:10;50284;50273:22;;;;;;;;;;;;;;;;;;;;;;;:36;;;;50409:10;50378:15;:28;50394:11;50378:28;;;;;;;;;;;:41;;;;50550:15;:24;50566:7;50550:24;;;;;;;;;;;50543:31;;;50585:10;:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;49530:1079;;;;:::o;47034:221::-;47119:14;47136:20;47153:2;47136:16;:20::i;:::-;47119:37;;47194:7;47167:12;:16;47180:2;47167:16;;;;;;;;;;;;;;;:24;47184:6;47167:24;;;;;;;;;;;:34;;;;47241:6;47212:17;:26;47230:7;47212:26;;;;;;;;;;;:35;;;;47034:221;;;:::o;39291:382::-;39385:1;39371:16;;:2;:16;;;;39363:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;39444:16;39452:7;39444;:16::i;:::-;39443:17;39435:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;39506:45;39535:1;39539:2;39543:7;39506:20;:45::i;:::-;39581:1;39564:9;:13;39574:2;39564:13;;;;;;;;;;;;;;;;:18;;;;;;;:::i;:::-;;;;;;;;39612:2;39593:7;:16;39601:7;39593:16;;;;;;;;;;;;:21;;;;;;;;;;;;;;;;;;39657:7;39653:2;39632:33;;39649:1;39632:33;;;;;;;;;;;;39291:382;;:::o;43405:126::-;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:343:1:-;84:5;109:65;125:48;166:6;125:48;:::i;:::-;109:65;:::i;:::-;100:74;;197:6;190:5;183:21;235:4;228:5;224:16;273:3;264:6;259:3;255:16;252:25;249:2;;;290:1;287;280:12;249:2;303:41;337:6;332:3;327;303:41;:::i;:::-;90:260;;;;;;:::o;356:345::-;434:5;459:66;475:49;517:6;475:49;:::i;:::-;459:66;:::i;:::-;450:75;;548:6;541:5;534:21;586:4;579:5;575:16;624:3;615:6;610:3;606:16;603:25;600:2;;;641:1;638;631:12;600:2;654:41;688:6;683:3;678;654:41;:::i;:::-;440:261;;;;;;:::o;707:139::-;753:5;791:6;778:20;769:29;;807:33;834:5;807:33;:::i;:::-;759:87;;;;:::o;852:133::-;895:5;933:6;920:20;911:29;;949:30;973:5;949:30;:::i;:::-;901:84;;;;:::o;991:137::-;1036:5;1074:6;1061:20;1052:29;;1090:32;1116:5;1090:32;:::i;:::-;1042:86;;;;:::o;1134:141::-;1190:5;1221:6;1215:13;1206:22;;1237:32;1263:5;1237:32;:::i;:::-;1196:79;;;;:::o;1294:271::-;1349:5;1398:3;1391:4;1383:6;1379:17;1375:27;1365:2;;1416:1;1413;1406:12;1365:2;1456:6;1443:20;1481:78;1555:3;1547:6;1540:4;1532:6;1528:17;1481:78;:::i;:::-;1472:87;;1355:210;;;;;:::o;1585:273::-;1641:5;1690:3;1683:4;1675:6;1671:17;1667:27;1657:2;;1708:1;1705;1698:12;1657:2;1748:6;1735:20;1773:79;1848:3;1840:6;1833:4;1825:6;1821:17;1773:79;:::i;:::-;1764:88;;1647:211;;;;;:::o;1864:143::-;1921:5;1952:6;1946:13;1937:22;;1968:33;1995:5;1968:33;:::i;:::-;1927:80;;;;:::o;2013:139::-;2059:5;2097:6;2084:20;2075:29;;2113:33;2140:5;2113:33;:::i;:::-;2065:87;;;;:::o;2158:141::-;2214:5;2245:6;2239:13;2230:22;;2261:32;2287:5;2261:32;:::i;:::-;2220:79;;;;:::o;2305:262::-;2364:6;2413:2;2401:9;2392:7;2388:23;2384:32;2381:2;;;2429:1;2426;2419:12;2381:2;2472:1;2497:53;2542:7;2533:6;2522:9;2518:22;2497:53;:::i;:::-;2487:63;;2443:117;2371:196;;;;:::o;2573:407::-;2641:6;2649;2698:2;2686:9;2677:7;2673:23;2669:32;2666:2;;;2714:1;2711;2704:12;2666:2;2757:1;2782:53;2827:7;2818:6;2807:9;2803:22;2782:53;:::i;:::-;2772:63;;2728:117;2884:2;2910:53;2955:7;2946:6;2935:9;2931:22;2910:53;:::i;:::-;2900:63;;2855:118;2656:324;;;;;:::o;2986:552::-;3063:6;3071;3079;3128:2;3116:9;3107:7;3103:23;3099:32;3096:2;;;3144:1;3141;3134:12;3096:2;3187:1;3212:53;3257:7;3248:6;3237:9;3233:22;3212:53;:::i;:::-;3202:63;;3158:117;3314:2;3340:53;3385:7;3376:6;3365:9;3361:22;3340:53;:::i;:::-;3330:63;;3285:118;3442:2;3468:53;3513:7;3504:6;3493:9;3489:22;3468:53;:::i;:::-;3458:63;;3413:118;3086:452;;;;;:::o;3544:809::-;3639:6;3647;3655;3663;3712:3;3700:9;3691:7;3687:23;3683:33;3680:2;;;3729:1;3726;3719:12;3680:2;3772:1;3797:53;3842:7;3833:6;3822:9;3818:22;3797:53;:::i;:::-;3787:63;;3743:117;3899:2;3925:53;3970:7;3961:6;3950:9;3946:22;3925:53;:::i;:::-;3915:63;;3870:118;4027:2;4053:53;4098:7;4089:6;4078:9;4074:22;4053:53;:::i;:::-;4043:63;;3998:118;4183:2;4172:9;4168:18;4155:32;4214:18;4206:6;4203:30;4200:2;;;4246:1;4243;4236:12;4200:2;4274:62;4328:7;4319:6;4308:9;4304:22;4274:62;:::i;:::-;4264:72;;4126:220;3670:683;;;;;;;:::o;4359:401::-;4424:6;4432;4481:2;4469:9;4460:7;4456:23;4452:32;4449:2;;;4497:1;4494;4487:12;4449:2;4540:1;4565:53;4610:7;4601:6;4590:9;4586:22;4565:53;:::i;:::-;4555:63;;4511:117;4667:2;4693:50;4735:7;4726:6;4715:9;4711:22;4693:50;:::i;:::-;4683:60;;4638:115;4439:321;;;;;:::o;4766:407::-;4834:6;4842;4891:2;4879:9;4870:7;4866:23;4862:32;4859:2;;;4907:1;4904;4897:12;4859:2;4950:1;4975:53;5020:7;5011:6;5000:9;4996:22;4975:53;:::i;:::-;4965:63;;4921:117;5077:2;5103:53;5148:7;5139:6;5128:9;5124:22;5103:53;:::i;:::-;5093:63;;5048:118;4849:324;;;;;:::o;5179:256::-;5235:6;5284:2;5272:9;5263:7;5259:23;5255:32;5252:2;;;5300:1;5297;5290:12;5252:2;5343:1;5368:50;5410:7;5401:6;5390:9;5386:22;5368:50;:::i;:::-;5358:60;;5314:114;5242:193;;;;:::o;5441:260::-;5499:6;5548:2;5536:9;5527:7;5523:23;5519:32;5516:2;;;5564:1;5561;5554:12;5516:2;5607:1;5632:52;5676:7;5667:6;5656:9;5652:22;5632:52;:::i;:::-;5622:62;;5578:116;5506:195;;;;:::o;5707:282::-;5776:6;5825:2;5813:9;5804:7;5800:23;5796:32;5793:2;;;5841:1;5838;5831:12;5793:2;5884:1;5909:63;5964:7;5955:6;5944:9;5940:22;5909:63;:::i;:::-;5899:73;;5855:127;5783:206;;;;:::o;5995:375::-;6064:6;6113:2;6101:9;6092:7;6088:23;6084:32;6081:2;;;6129:1;6126;6119:12;6081:2;6200:1;6189:9;6185:17;6172:31;6230:18;6222:6;6219:30;6216:2;;;6262:1;6259;6252:12;6216:2;6290:63;6345:7;6336:6;6325:9;6321:22;6290:63;:::i;:::-;6280:73;;6143:220;6071:299;;;;:::o;6376:594::-;6463:6;6471;6479;6528:2;6516:9;6507:7;6503:23;6499:32;6496:2;;;6544:1;6541;6534:12;6496:2;6587:1;6612:64;6668:7;6659:6;6648:9;6644:22;6612:64;:::i;:::-;6602:74;;6558:128;6725:2;6751:64;6807:7;6798:6;6787:9;6783:22;6751:64;:::i;:::-;6741:74;;6696:129;6864:2;6890:63;6945:7;6936:6;6925:9;6921:22;6890:63;:::i;:::-;6880:73;;6835:128;6486:484;;;;;:::o;6976:262::-;7035:6;7084:2;7072:9;7063:7;7059:23;7055:32;7052:2;;;7100:1;7097;7090:12;7052:2;7143:1;7168:53;7213:7;7204:6;7193:9;7189:22;7168:53;:::i;:::-;7158:63;;7114:117;7042:196;;;;:::o;7244:179::-;7313:10;7334:46;7376:3;7368:6;7334:46;:::i;:::-;7412:4;7407:3;7403:14;7389:28;;7324:99;;;;:::o;7429:142::-;7532:32;7558:5;7532:32;:::i;:::-;7527:3;7520:45;7510:61;;:::o;7577:118::-;7664:24;7682:5;7664:24;:::i;:::-;7659:3;7652:37;7642:53;;:::o;7701:157::-;7806:45;7826:24;7844:5;7826:24;:::i;:::-;7806:45;:::i;:::-;7801:3;7794:58;7784:74;;:::o;7894:732::-;8013:3;8042:54;8090:5;8042:54;:::i;:::-;8112:86;8191:6;8186:3;8112:86;:::i;:::-;8105:93;;8222:56;8272:5;8222:56;:::i;:::-;8301:7;8332:1;8317:284;8342:6;8339:1;8336:13;8317:284;;;8418:6;8412:13;8445:63;8504:3;8489:13;8445:63;:::i;:::-;8438:70;;8531:60;8584:6;8531:60;:::i;:::-;8521:70;;8377:224;8364:1;8361;8357:9;8352:14;;8317:284;;;8321:14;8617:3;8610:10;;8018:608;;;;;;;:::o;8632:109::-;8713:21;8728:5;8713:21;:::i;:::-;8708:3;8701:34;8691:50;;:::o;8747:360::-;8833:3;8861:38;8893:5;8861:38;:::i;:::-;8915:70;8978:6;8973:3;8915:70;:::i;:::-;8908:77;;8994:52;9039:6;9034:3;9027:4;9020:5;9016:16;8994:52;:::i;:::-;9071:29;9093:6;9071:29;:::i;:::-;9066:3;9062:39;9055:46;;8837:270;;;;;:::o;9113:364::-;9201:3;9229:39;9262:5;9229:39;:::i;:::-;9284:71;9348:6;9343:3;9284:71;:::i;:::-;9277:78;;9364:52;9409:6;9404:3;9397:4;9390:5;9386:16;9364:52;:::i;:::-;9441:29;9463:6;9441:29;:::i;:::-;9436:3;9432:39;9425:46;;9205:272;;;;;:::o;9483:377::-;9589:3;9617:39;9650:5;9617:39;:::i;:::-;9672:89;9754:6;9749:3;9672:89;:::i;:::-;9665:96;;9770:52;9815:6;9810:3;9803:4;9796:5;9792:16;9770:52;:::i;:::-;9847:6;9842:3;9838:16;9831:23;;9593:267;;;;;:::o;9890:845::-;9993:3;10030:5;10024:12;10059:36;10085:9;10059:36;:::i;:::-;10111:89;10193:6;10188:3;10111:89;:::i;:::-;10104:96;;10231:1;10220:9;10216:17;10247:1;10242:137;;;;10393:1;10388:341;;;;10209:520;;10242:137;10326:4;10322:9;10311;10307:25;10302:3;10295:38;10362:6;10357:3;10353:16;10346:23;;10242:137;;10388:341;10455:38;10487:5;10455:38;:::i;:::-;10515:1;10529:154;10543:6;10540:1;10537:13;10529:154;;;10617:7;10611:14;10607:1;10602:3;10598:11;10591:35;10667:1;10658:7;10654:15;10643:26;;10565:4;10562:1;10558:12;10553:17;;10529:154;;;10712:6;10707:3;10703:16;10696:23;;10395:334;;10209:520;;9997:738;;;;;;:::o;10741:366::-;10883:3;10904:67;10968:2;10963:3;10904:67;:::i;:::-;10897:74;;10980:93;11069:3;10980:93;:::i;:::-;11098:2;11093:3;11089:12;11082:19;;10887:220;;;:::o;11113:366::-;11255:3;11276:67;11340:2;11335:3;11276:67;:::i;:::-;11269:74;;11352:93;11441:3;11352:93;:::i;:::-;11470:2;11465:3;11461:12;11454:19;;11259:220;;;:::o;11485:366::-;11627:3;11648:67;11712:2;11707:3;11648:67;:::i;:::-;11641:74;;11724:93;11813:3;11724:93;:::i;:::-;11842:2;11837:3;11833:12;11826:19;;11631:220;;;:::o;11857:366::-;11999:3;12020:67;12084:2;12079:3;12020:67;:::i;:::-;12013:74;;12096:93;12185:3;12096:93;:::i;:::-;12214:2;12209:3;12205:12;12198:19;;12003:220;;;:::o;12229:366::-;12371:3;12392:67;12456:2;12451:3;12392:67;:::i;:::-;12385:74;;12468:93;12557:3;12468:93;:::i;:::-;12586:2;12581:3;12577:12;12570:19;;12375:220;;;:::o;12601:366::-;12743:3;12764:67;12828:2;12823:3;12764:67;:::i;:::-;12757:74;;12840:93;12929:3;12840:93;:::i;:::-;12958:2;12953:3;12949:12;12942:19;;12747:220;;;:::o;12973:366::-;13115:3;13136:67;13200:2;13195:3;13136:67;:::i;:::-;13129:74;;13212:93;13301:3;13212:93;:::i;:::-;13330:2;13325:3;13321:12;13314:19;;13119:220;;;:::o;13345:366::-;13487:3;13508:67;13572:2;13567:3;13508:67;:::i;:::-;13501:74;;13584:93;13673:3;13584:93;:::i;:::-;13702:2;13697:3;13693:12;13686:19;;13491:220;;;:::o;13717:366::-;13859:3;13880:67;13944:2;13939:3;13880:67;:::i;:::-;13873:74;;13956:93;14045:3;13956:93;:::i;:::-;14074:2;14069:3;14065:12;14058:19;;13863:220;;;:::o;14089:366::-;14231:3;14252:67;14316:2;14311:3;14252:67;:::i;:::-;14245:74;;14328:93;14417:3;14328:93;:::i;:::-;14446:2;14441:3;14437:12;14430:19;;14235:220;;;:::o;14461:366::-;14603:3;14624:67;14688:2;14683:3;14624:67;:::i;:::-;14617:74;;14700:93;14789:3;14700:93;:::i;:::-;14818:2;14813:3;14809:12;14802:19;;14607:220;;;:::o;14833:365::-;14975:3;14996:66;15060:1;15055:3;14996:66;:::i;:::-;14989:73;;15071:93;15160:3;15071:93;:::i;:::-;15189:2;15184:3;15180:12;15173:19;;14979:219;;;:::o;15204:366::-;15346:3;15367:67;15431:2;15426:3;15367:67;:::i;:::-;15360:74;;15443:93;15532:3;15443:93;:::i;:::-;15561:2;15556:3;15552:12;15545:19;;15350:220;;;:::o;15576:366::-;15718:3;15739:67;15803:2;15798:3;15739:67;:::i;:::-;15732:74;;15815:93;15904:3;15815:93;:::i;:::-;15933:2;15928:3;15924:12;15917:19;;15722:220;;;:::o;15948:366::-;16090:3;16111:67;16175:2;16170:3;16111:67;:::i;:::-;16104:74;;16187:93;16276:3;16187:93;:::i;:::-;16305:2;16300:3;16296:12;16289:19;;16094:220;;;:::o;16320:366::-;16462:3;16483:67;16547:2;16542:3;16483:67;:::i;:::-;16476:74;;16559:93;16648:3;16559:93;:::i;:::-;16677:2;16672:3;16668:12;16661:19;;16466:220;;;:::o;16692:366::-;16834:3;16855:67;16919:2;16914:3;16855:67;:::i;:::-;16848:74;;16931:93;17020:3;16931:93;:::i;:::-;17049:2;17044:3;17040:12;17033:19;;16838:220;;;:::o;17064:366::-;17206:3;17227:67;17291:2;17286:3;17227:67;:::i;:::-;17220:74;;17303:93;17392:3;17303:93;:::i;:::-;17421:2;17416:3;17412:12;17405:19;;17210:220;;;:::o;17436:366::-;17578:3;17599:67;17663:2;17658:3;17599:67;:::i;:::-;17592:74;;17675:93;17764:3;17675:93;:::i;:::-;17793:2;17788:3;17784:12;17777:19;;17582:220;;;:::o;17808:366::-;17950:3;17971:67;18035:2;18030:3;17971:67;:::i;:::-;17964:74;;18047:93;18136:3;18047:93;:::i;:::-;18165:2;18160:3;18156:12;18149:19;;17954:220;;;:::o;18180:366::-;18322:3;18343:67;18407:2;18402:3;18343:67;:::i;:::-;18336:74;;18419:93;18508:3;18419:93;:::i;:::-;18537:2;18532:3;18528:12;18521:19;;18326:220;;;:::o;18552:366::-;18694:3;18715:67;18779:2;18774:3;18715:67;:::i;:::-;18708:74;;18791:93;18880:3;18791:93;:::i;:::-;18909:2;18904:3;18900:12;18893:19;;18698:220;;;:::o;18924:366::-;19066:3;19087:67;19151:2;19146:3;19087:67;:::i;:::-;19080:74;;19163:93;19252:3;19163:93;:::i;:::-;19281:2;19276:3;19272:12;19265:19;;19070:220;;;:::o;19296:366::-;19438:3;19459:67;19523:2;19518:3;19459:67;:::i;:::-;19452:74;;19535:93;19624:3;19535:93;:::i;:::-;19653:2;19648:3;19644:12;19637:19;;19442:220;;;:::o;19668:366::-;19810:3;19831:67;19895:2;19890:3;19831:67;:::i;:::-;19824:74;;19907:93;19996:3;19907:93;:::i;:::-;20025:2;20020:3;20016:12;20009:19;;19814:220;;;:::o;20040:366::-;20182:3;20203:67;20267:2;20262:3;20203:67;:::i;:::-;20196:74;;20279:93;20368:3;20279:93;:::i;:::-;20397:2;20392:3;20388:12;20381:19;;20186:220;;;:::o;20412:398::-;20571:3;20592:83;20673:1;20668:3;20592:83;:::i;:::-;20585:90;;20684:93;20773:3;20684:93;:::i;:::-;20802:1;20797:3;20793:11;20786:18;;20575:235;;;:::o;20816:366::-;20958:3;20979:67;21043:2;21038:3;20979:67;:::i;:::-;20972:74;;21055:93;21144:3;21055:93;:::i;:::-;21173:2;21168:3;21164:12;21157:19;;20962:220;;;:::o;21188:366::-;21330:3;21351:67;21415:2;21410:3;21351:67;:::i;:::-;21344:74;;21427:93;21516:3;21427:93;:::i;:::-;21545:2;21540:3;21536:12;21529:19;;21334:220;;;:::o;21560:366::-;21702:3;21723:67;21787:2;21782:3;21723:67;:::i;:::-;21716:74;;21799:93;21888:3;21799:93;:::i;:::-;21917:2;21912:3;21908:12;21901:19;;21706:220;;;:::o;21932:366::-;22074:3;22095:67;22159:2;22154:3;22095:67;:::i;:::-;22088:74;;22171:93;22260:3;22171:93;:::i;:::-;22289:2;22284:3;22280:12;22273:19;;22078:220;;;:::o;22304:108::-;22381:24;22399:5;22381:24;:::i;:::-;22376:3;22369:37;22359:53;;:::o;22418:118::-;22505:24;22523:5;22505:24;:::i;:::-;22500:3;22493:37;22483:53;;:::o;22542:157::-;22647:45;22667:24;22685:5;22667:24;:::i;:::-;22647:45;:::i;:::-;22642:3;22635:58;22625:74;;:::o;22705:429::-;22882:3;22904:92;22992:3;22983:6;22904:92;:::i;:::-;22897:99;;23013:95;23104:3;23095:6;23013:95;:::i;:::-;23006:102;;23125:3;23118:10;;22886:248;;;;;:::o;23140:379::-;23324:3;23346:147;23489:3;23346:147;:::i;:::-;23339:154;;23510:3;23503:10;;23328:191;;;:::o;23525:961::-;23777:3;23792:75;23863:3;23854:6;23792:75;:::i;:::-;23892:2;23887:3;23883:12;23876:19;;23905:75;23976:3;23967:6;23905:75;:::i;:::-;24005:2;24000:3;23996:12;23989:19;;24018:75;24089:3;24080:6;24018:75;:::i;:::-;24118:2;24113:3;24109:12;24102:19;;24131:75;24202:3;24193:6;24131:75;:::i;:::-;24231:2;24226:3;24222:12;24215:19;;24244:75;24315:3;24306:6;24244:75;:::i;:::-;24344:2;24339:3;24335:12;24328:19;;24357:75;24428:3;24419:6;24357:75;:::i;:::-;24457:2;24452:3;24448:12;24441:19;;24477:3;24470:10;;23781:705;;;;;;;;;:::o;24492:222::-;24585:4;24623:2;24612:9;24608:18;24600:26;;24636:71;24704:1;24693:9;24689:17;24680:6;24636:71;:::i;:::-;24590:124;;;;:::o;24720:254::-;24829:4;24867:2;24856:9;24852:18;24844:26;;24880:87;24964:1;24953:9;24949:17;24940:6;24880:87;:::i;:::-;24834:140;;;;:::o;24980:640::-;25175:4;25213:3;25202:9;25198:19;25190:27;;25227:71;25295:1;25284:9;25280:17;25271:6;25227:71;:::i;:::-;25308:72;25376:2;25365:9;25361:18;25352:6;25308:72;:::i;:::-;25390;25458:2;25447:9;25443:18;25434:6;25390:72;:::i;:::-;25509:9;25503:4;25499:20;25494:2;25483:9;25479:18;25472:48;25537:76;25608:4;25599:6;25537:76;:::i;:::-;25529:84;;25180:440;;;;;;;:::o;25626:373::-;25769:4;25807:2;25796:9;25792:18;25784:26;;25856:9;25850:4;25846:20;25842:1;25831:9;25827:17;25820:47;25884:108;25987:4;25978:6;25884:108;:::i;:::-;25876:116;;25774:225;;;;:::o;26005:210::-;26092:4;26130:2;26119:9;26115:18;26107:26;;26143:65;26205:1;26194:9;26190:17;26181:6;26143:65;:::i;:::-;26097:118;;;;:::o;26221:313::-;26334:4;26372:2;26361:9;26357:18;26349:26;;26421:9;26415:4;26411:20;26407:1;26396:9;26392:17;26385:47;26449:78;26522:4;26513:6;26449:78;:::i;:::-;26441:86;;26339:195;;;;:::o;26540:419::-;26706:4;26744:2;26733:9;26729:18;26721:26;;26793:9;26787:4;26783:20;26779:1;26768:9;26764:17;26757:47;26821:131;26947:4;26821:131;:::i;:::-;26813:139;;26711:248;;;:::o;26965:419::-;27131:4;27169:2;27158:9;27154:18;27146:26;;27218:9;27212:4;27208:20;27204:1;27193:9;27189:17;27182:47;27246:131;27372:4;27246:131;:::i;:::-;27238:139;;27136:248;;;:::o;27390:419::-;27556:4;27594:2;27583:9;27579:18;27571:26;;27643:9;27637:4;27633:20;27629:1;27618:9;27614:17;27607:47;27671:131;27797:4;27671:131;:::i;:::-;27663:139;;27561:248;;;:::o;27815:419::-;27981:4;28019:2;28008:9;28004:18;27996:26;;28068:9;28062:4;28058:20;28054:1;28043:9;28039:17;28032:47;28096:131;28222:4;28096:131;:::i;:::-;28088:139;;27986:248;;;:::o;28240:419::-;28406:4;28444:2;28433:9;28429:18;28421:26;;28493:9;28487:4;28483:20;28479:1;28468:9;28464:17;28457:47;28521:131;28647:4;28521:131;:::i;:::-;28513:139;;28411:248;;;:::o;28665:419::-;28831:4;28869:2;28858:9;28854:18;28846:26;;28918:9;28912:4;28908:20;28904:1;28893:9;28889:17;28882:47;28946:131;29072:4;28946:131;:::i;:::-;28938:139;;28836:248;;;:::o;29090:419::-;29256:4;29294:2;29283:9;29279:18;29271:26;;29343:9;29337:4;29333:20;29329:1;29318:9;29314:17;29307:47;29371:131;29497:4;29371:131;:::i;:::-;29363:139;;29261:248;;;:::o;29515:419::-;29681:4;29719:2;29708:9;29704:18;29696:26;;29768:9;29762:4;29758:20;29754:1;29743:9;29739:17;29732:47;29796:131;29922:4;29796:131;:::i;:::-;29788:139;;29686:248;;;:::o;29940:419::-;30106:4;30144:2;30133:9;30129:18;30121:26;;30193:9;30187:4;30183:20;30179:1;30168:9;30164:17;30157:47;30221:131;30347:4;30221:131;:::i;:::-;30213:139;;30111:248;;;:::o;30365:419::-;30531:4;30569:2;30558:9;30554:18;30546:26;;30618:9;30612:4;30608:20;30604:1;30593:9;30589:17;30582:47;30646:131;30772:4;30646:131;:::i;:::-;30638:139;;30536:248;;;:::o;30790:419::-;30956:4;30994:2;30983:9;30979:18;30971:26;;31043:9;31037:4;31033:20;31029:1;31018:9;31014:17;31007:47;31071:131;31197:4;31071:131;:::i;:::-;31063:139;;30961:248;;;:::o;31215:419::-;31381:4;31419:2;31408:9;31404:18;31396:26;;31468:9;31462:4;31458:20;31454:1;31443:9;31439:17;31432:47;31496:131;31622:4;31496:131;:::i;:::-;31488:139;;31386:248;;;:::o;31640:419::-;31806:4;31844:2;31833:9;31829:18;31821:26;;31893:9;31887:4;31883:20;31879:1;31868:9;31864:17;31857:47;31921:131;32047:4;31921:131;:::i;:::-;31913:139;;31811:248;;;:::o;32065:419::-;32231:4;32269:2;32258:9;32254:18;32246:26;;32318:9;32312:4;32308:20;32304:1;32293:9;32289:17;32282:47;32346:131;32472:4;32346:131;:::i;:::-;32338:139;;32236:248;;;:::o;32490:419::-;32656:4;32694:2;32683:9;32679:18;32671:26;;32743:9;32737:4;32733:20;32729:1;32718:9;32714:17;32707:47;32771:131;32897:4;32771:131;:::i;:::-;32763:139;;32661:248;;;:::o;32915:419::-;33081:4;33119:2;33108:9;33104:18;33096:26;;33168:9;33162:4;33158:20;33154:1;33143:9;33139:17;33132:47;33196:131;33322:4;33196:131;:::i;:::-;33188:139;;33086:248;;;:::o;33340:419::-;33506:4;33544:2;33533:9;33529:18;33521:26;;33593:9;33587:4;33583:20;33579:1;33568:9;33564:17;33557:47;33621:131;33747:4;33621:131;:::i;:::-;33613:139;;33511:248;;;:::o;33765:419::-;33931:4;33969:2;33958:9;33954:18;33946:26;;34018:9;34012:4;34008:20;34004:1;33993:9;33989:17;33982:47;34046:131;34172:4;34046:131;:::i;:::-;34038:139;;33936:248;;;:::o;34190:419::-;34356:4;34394:2;34383:9;34379:18;34371:26;;34443:9;34437:4;34433:20;34429:1;34418:9;34414:17;34407:47;34471:131;34597:4;34471:131;:::i;:::-;34463:139;;34361:248;;;:::o;34615:419::-;34781:4;34819:2;34808:9;34804:18;34796:26;;34868:9;34862:4;34858:20;34854:1;34843:9;34839:17;34832:47;34896:131;35022:4;34896:131;:::i;:::-;34888:139;;34786:248;;;:::o;35040:419::-;35206:4;35244:2;35233:9;35229:18;35221:26;;35293:9;35287:4;35283:20;35279:1;35268:9;35264:17;35257:47;35321:131;35447:4;35321:131;:::i;:::-;35313:139;;35211:248;;;:::o;35465:419::-;35631:4;35669:2;35658:9;35654:18;35646:26;;35718:9;35712:4;35708:20;35704:1;35693:9;35689:17;35682:47;35746:131;35872:4;35746:131;:::i;:::-;35738:139;;35636:248;;;:::o;35890:419::-;36056:4;36094:2;36083:9;36079:18;36071:26;;36143:9;36137:4;36133:20;36129:1;36118:9;36114:17;36107:47;36171:131;36297:4;36171:131;:::i;:::-;36163:139;;36061:248;;;:::o;36315:419::-;36481:4;36519:2;36508:9;36504:18;36496:26;;36568:9;36562:4;36558:20;36554:1;36543:9;36539:17;36532:47;36596:131;36722:4;36596:131;:::i;:::-;36588:139;;36486:248;;;:::o;36740:419::-;36906:4;36944:2;36933:9;36929:18;36921:26;;36993:9;36987:4;36983:20;36979:1;36968:9;36964:17;36957:47;37021:131;37147:4;37021:131;:::i;:::-;37013:139;;36911:248;;;:::o;37165:419::-;37331:4;37369:2;37358:9;37354:18;37346:26;;37418:9;37412:4;37408:20;37404:1;37393:9;37389:17;37382:47;37446:131;37572:4;37446:131;:::i;:::-;37438:139;;37336:248;;;:::o;37590:419::-;37756:4;37794:2;37783:9;37779:18;37771:26;;37843:9;37837:4;37833:20;37829:1;37818:9;37814:17;37807:47;37871:131;37997:4;37871:131;:::i;:::-;37863:139;;37761:248;;;:::o;38015:419::-;38181:4;38219:2;38208:9;38204:18;38196:26;;38268:9;38262:4;38258:20;38254:1;38243:9;38239:17;38232:47;38296:131;38422:4;38296:131;:::i;:::-;38288:139;;38186:248;;;:::o;38440:419::-;38606:4;38644:2;38633:9;38629:18;38621:26;;38693:9;38687:4;38683:20;38679:1;38668:9;38664:17;38657:47;38721:131;38847:4;38721:131;:::i;:::-;38713:139;;38611:248;;;:::o;38865:419::-;39031:4;39069:2;39058:9;39054:18;39046:26;;39118:9;39112:4;39108:20;39104:1;39093:9;39089:17;39082:47;39146:131;39272:4;39146:131;:::i;:::-;39138:139;;39036:248;;;:::o;39290:222::-;39383:4;39421:2;39410:9;39406:18;39398:26;;39434:71;39502:1;39491:9;39487:17;39478:6;39434:71;:::i;:::-;39388:124;;;;:::o;39518:332::-;39639:4;39677:2;39666:9;39662:18;39654:26;;39690:71;39758:1;39747:9;39743:17;39734:6;39690:71;:::i;:::-;39771:72;39839:2;39828:9;39824:18;39815:6;39771:72;:::i;:::-;39644:206;;;;;:::o;39856:129::-;39890:6;39917:20;;:::i;:::-;39907:30;;39946:33;39974:4;39966:6;39946:33;:::i;:::-;39897:88;;;:::o;39991:75::-;40024:6;40057:2;40051:9;40041:19;;40031:35;:::o;40072:307::-;40133:4;40223:18;40215:6;40212:30;40209:2;;;40245:18;;:::i;:::-;40209:2;40283:29;40305:6;40283:29;:::i;:::-;40275:37;;40367:4;40361;40357:15;40349:23;;40138:241;;;:::o;40385:308::-;40447:4;40537:18;40529:6;40526:30;40523:2;;;40559:18;;:::i;:::-;40523:2;40597:29;40619:6;40597:29;:::i;:::-;40589:37;;40681:4;40675;40671:15;40663:23;;40452:241;;;:::o;40699:132::-;40766:4;40789:3;40781:11;;40819:4;40814:3;40810:14;40802:22;;40771:60;;;:::o;40837:141::-;40886:4;40909:3;40901:11;;40932:3;40929:1;40922:14;40966:4;40963:1;40953:18;40945:26;;40891:87;;;:::o;40984:114::-;41051:6;41085:5;41079:12;41069:22;;41058:40;;;:::o;41104:98::-;41155:6;41189:5;41183:12;41173:22;;41162:40;;;:::o;41208:99::-;41260:6;41294:5;41288:12;41278:22;;41267:40;;;:::o;41313:113::-;41383:4;41415;41410:3;41406:14;41398:22;;41388:38;;;:::o;41432:184::-;41531:11;41565:6;41560:3;41553:19;41605:4;41600:3;41596:14;41581:29;;41543:73;;;;:::o;41622:168::-;41705:11;41739:6;41734:3;41727:19;41779:4;41774:3;41770:14;41755:29;;41717:73;;;;:::o;41796:147::-;41897:11;41934:3;41919:18;;41909:34;;;;:::o;41949:169::-;42033:11;42067:6;42062:3;42055:19;42107:4;42102:3;42098:14;42083:29;;42045:73;;;;:::o;42124:148::-;42226:11;42263:3;42248:18;;42238:34;;;;:::o;42278:305::-;42318:3;42337:20;42355:1;42337:20;:::i;:::-;42332:25;;42371:20;42389:1;42371:20;:::i;:::-;42366:25;;42525:1;42457:66;42453:74;42450:1;42447:81;42444:2;;;42531:18;;:::i;:::-;42444:2;42575:1;42572;42568:9;42561:16;;42322:261;;;;:::o;42589:185::-;42629:1;42646:20;42664:1;42646:20;:::i;:::-;42641:25;;42680:20;42698:1;42680:20;:::i;:::-;42675:25;;42719:1;42709:2;;42724:18;;:::i;:::-;42709:2;42766:1;42763;42759:9;42754:14;;42631:143;;;;:::o;42780:348::-;42820:7;42843:20;42861:1;42843:20;:::i;:::-;42838:25;;42877:20;42895:1;42877:20;:::i;:::-;42872:25;;43065:1;42997:66;42993:74;42990:1;42987:81;42982:1;42975:9;42968:17;42964:105;42961:2;;;43072:18;;:::i;:::-;42961:2;43120:1;43117;43113:9;43102:20;;42828:300;;;;:::o;43134:191::-;43174:4;43194:20;43212:1;43194:20;:::i;:::-;43189:25;;43228:20;43246:1;43228:20;:::i;:::-;43223:25;;43267:1;43264;43261:8;43258:2;;;43272:18;;:::i;:::-;43258:2;43317:1;43314;43310:9;43302:17;;43179:146;;;;:::o;43331:96::-;43368:7;43397:24;43415:5;43397:24;:::i;:::-;43386:35;;43376:51;;;:::o;43433:104::-;43478:7;43507:24;43525:5;43507:24;:::i;:::-;43496:35;;43486:51;;;:::o;43543:90::-;43577:7;43620:5;43613:13;43606:21;43595:32;;43585:48;;;:::o;43639:149::-;43675:7;43715:66;43708:5;43704:78;43693:89;;43683:105;;;:::o;43794:114::-;43831:7;43871:30;43864:5;43860:42;43849:53;;43839:69;;;:::o;43914:126::-;43951:7;43991:42;43984:5;43980:54;43969:65;;43959:81;;;:::o;44046:77::-;44083:7;44112:5;44101:16;;44091:32;;;:::o;44129:93::-;44165:7;44205:10;44198:5;44194:22;44183:33;;44173:49;;;:::o;44228:154::-;44312:6;44307:3;44302;44289:30;44374:1;44365:6;44360:3;44356:16;44349:27;44279:103;;;:::o;44388:307::-;44456:1;44466:113;44480:6;44477:1;44474:13;44466:113;;;44565:1;44560:3;44556:11;44550:18;44546:1;44541:3;44537:11;44530:39;44502:2;44499:1;44495:10;44490:15;;44466:113;;;44597:6;44594:1;44591:13;44588:2;;;44677:1;44668:6;44663:3;44659:16;44652:27;44588:2;44437:258;;;;:::o;44701:320::-;44745:6;44782:1;44776:4;44772:12;44762:22;;44829:1;44823:4;44819:12;44850:18;44840:2;;44906:4;44898:6;44894:17;44884:27;;44840:2;44968;44960:6;44957:14;44937:18;44934:38;44931:2;;;44987:18;;:::i;:::-;44931:2;44752:269;;;;:::o;45027:281::-;45110:27;45132:4;45110:27;:::i;:::-;45102:6;45098:40;45240:6;45228:10;45225:22;45204:18;45192:10;45189:34;45186:62;45183:2;;;45251:18;;:::i;:::-;45183:2;45291:10;45287:2;45280:22;45070:238;;;:::o;45314:233::-;45353:3;45376:24;45394:5;45376:24;:::i;:::-;45367:33;;45422:66;45415:5;45412:77;45409:2;;;45492:18;;:::i;:::-;45409:2;45539:1;45532:5;45528:13;45521:20;;45357:190;;;:::o;45553:100::-;45592:7;45621:26;45641:5;45621:26;:::i;:::-;45610:37;;45600:53;;;:::o;45659:94::-;45698:7;45727:20;45741:5;45727:20;:::i;:::-;45716:31;;45706:47;;;:::o;45759:79::-;45798:7;45827:5;45816:16;;45806:32;;;:::o;45844:176::-;45876:1;45893:20;45911:1;45893:20;:::i;:::-;45888:25;;45927:20;45945:1;45927:20;:::i;:::-;45922:25;;45966:1;45956:2;;45971:18;;:::i;:::-;45956:2;46012:1;46009;46005:9;46000:14;;45878:142;;;;:::o;46026:180::-;46074:77;46071:1;46064:88;46171:4;46168:1;46161:15;46195:4;46192:1;46185:15;46212:180;46260:77;46257:1;46250:88;46357:4;46354:1;46347:15;46381:4;46378:1;46371:15;46398:180;46446:77;46443:1;46436:88;46543:4;46540:1;46533:15;46567:4;46564:1;46557:15;46584:180;46632:77;46629:1;46622:88;46729:4;46726:1;46719:15;46753:4;46750:1;46743:15;46770:102;46811:6;46862:2;46858:7;46853:2;46846:5;46842:14;46838:28;46828:38;;46818:54;;;:::o;46878:94::-;46911:8;46959:5;46955:2;46951:14;46930:35;;46920:52;;;:::o;46978:230::-;47118:34;47114:1;47106:6;47102:14;47095:58;47187:13;47182:2;47174:6;47170:15;47163:38;47084:124;:::o;47214:170::-;47354:22;47350:1;47342:6;47338:14;47331:46;47320:64;:::o;47390:164::-;47530:16;47526:1;47518:6;47514:14;47507:40;47496:58;:::o;47560:230::-;47700:34;47696:1;47688:6;47684:14;47677:58;47769:13;47764:2;47756:6;47752:15;47745:38;47666:124;:::o;47796:237::-;47936:34;47932:1;47924:6;47920:14;47913:58;48005:20;48000:2;47992:6;47988:15;47981:45;47902:131;:::o;48039:225::-;48179:34;48175:1;48167:6;48163:14;48156:58;48248:8;48243:2;48235:6;48231:15;48224:33;48145:119;:::o;48270:178::-;48410:30;48406:1;48398:6;48394:14;48387:54;48376:72;:::o;48454:164::-;48594:16;48590:1;48582:6;48578:14;48571:40;48560:58;:::o;48624:223::-;48764:34;48760:1;48752:6;48748:14;48741:58;48833:6;48828:2;48820:6;48816:15;48809:31;48730:117;:::o;48853:175::-;48993:27;48989:1;48981:6;48977:14;48970:51;48959:69;:::o;49034:245::-;49174:34;49170:1;49162:6;49158:14;49151:58;49243:28;49238:2;49230:6;49226:15;49219:53;49140:139;:::o;49285:159::-;49425:11;49421:1;49413:6;49409:14;49402:35;49391:53;:::o;49450:179::-;49590:31;49586:1;49578:6;49574:14;49567:55;49556:73;:::o;49635:231::-;49775:34;49771:1;49763:6;49759:14;49752:58;49844:14;49839:2;49831:6;49827:15;49820:39;49741:125;:::o;49872:166::-;50012:18;50008:1;50000:6;49996:14;49989:42;49978:60;:::o;50044:243::-;50184:34;50180:1;50172:6;50168:14;50161:58;50253:26;50248:2;50240:6;50236:15;50229:51;50150:137;:::o;50293:229::-;50433:34;50429:1;50421:6;50417:14;50410:58;50502:12;50497:2;50489:6;50485:15;50478:37;50399:123;:::o;50528:228::-;50668:34;50664:1;50656:6;50652:14;50645:58;50737:11;50732:2;50724:6;50720:15;50713:36;50634:122;:::o;50762:182::-;50902:34;50898:1;50890:6;50886:14;50879:58;50868:76;:::o;50950:231::-;51090:34;51086:1;51078:6;51074:14;51067:58;51159:14;51154:2;51146:6;51142:15;51135:39;51056:125;:::o;51187:182::-;51327:34;51323:1;51315:6;51311:14;51304:58;51293:76;:::o;51375:228::-;51515:34;51511:1;51503:6;51499:14;51492:58;51584:11;51579:2;51571:6;51567:15;51560:36;51481:122;:::o;51609:167::-;51749:19;51745:1;51737:6;51733:14;51726:43;51715:61;:::o;51782:177::-;51922:29;51918:1;51910:6;51906:14;51899:53;51888:71;:::o;51965:220::-;52105:34;52101:1;52093:6;52089:14;52082:58;52174:3;52169:2;52161:6;52157:15;52150:28;52071:114;:::o;52191:174::-;52331:26;52327:1;52319:6;52315:14;52308:50;52297:68;:::o;52371:114::-;52477:8;:::o;52491:236::-;52631:34;52627:1;52619:6;52615:14;52608:58;52700:19;52695:2;52687:6;52683:15;52676:44;52597:130;:::o;52733:231::-;52873:34;52869:1;52861:6;52857:14;52850:58;52942:14;52937:2;52929:6;52925:15;52918:39;52839:125;:::o;52970:181::-;53110:33;53106:1;53098:6;53094:14;53087:57;53076:75;:::o;53157:235::-;53297:34;53293:1;53285:6;53281:14;53274:58;53366:18;53361:2;53353:6;53349:15;53342:43;53263:129;:::o;53398:122::-;53471:24;53489:5;53471:24;:::i;:::-;53464:5;53461:35;53451:2;;53510:1;53507;53500:12;53451:2;53441:79;:::o;53526:116::-;53596:21;53611:5;53596:21;:::i;:::-;53589:5;53586:32;53576:2;;53632:1;53629;53622:12;53576:2;53566:76;:::o;53648:120::-;53720:23;53737:5;53720:23;:::i;:::-;53713:5;53710:34;53700:2;;53758:1;53755;53748:12;53700:2;53690:78;:::o;53774:122::-;53847:24;53865:5;53847:24;:::i;:::-;53840:5;53837:35;53827:2;;53886:1;53883;53876:12;53827:2;53817:79;:::o;53902:122::-;53975:24;53993:5;53975:24;:::i;:::-;53968:5;53965:35;53955:2;;54014:1;54011;54004:12;53955:2;53945:79;:::o;54030:120::-;54102:23;54119:5;54102:23;:::i;:::-;54095:5;54092:34;54082:2;;54140:1;54137;54130:12;54082:2;54072:78;:::o

Swarm Source

ipfs://f9458170a6432b69cbea145dd57c4645abc95558315f6ba3645b747d55f363ce
Loading