ETH Price: $3,464.45 (+0.26%)
Gas: 10 Gwei

Token

RandomEDGE Free (RE)
 

Overview

Max Total Supply

1,434 RE

Holders

523

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
2 RE
0x0d77c6329df0afe4dab3f73e52e765d0c41586b0
Loading...
Loading
Loading...
Loading
Loading...
Loading

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

Contract Source Code Verified (Exact Match)

Contract Name:
RandomEDGE

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 25 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Multiple files format)

File 12 of 16: lotto_mainnet_free.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.4;

import "ERC721Enumerable.sol";
import "Ownable.sol";
import "VRFConsumerBase.sol";

interface IERC20 {
    function balanceOf(address account) external view returns (uint256);
    function transfer(address recipient, uint256 amount) external returns (bool);
}

abstract contract ReentrancyGuard {
    uint256 private constant _NOT_ENTERED = 1;
    uint256 private constant _ENTERED = 2;

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

    modifier nonReentrant() {
        require(_status != _ENTERED, "ReentrancyGuard: reentrant call");
        _status = _ENTERED;
        _;
        _status = _NOT_ENTERED;
    }
}

contract RandomEDGE is ERC721Enumerable, Ownable, VRFConsumerBase, ReentrancyGuard {
    using Strings for uint256;

    // Constants
    // ------------------------------------------------------------------------
    uint256 public constant MAX_SUPPLY = 5000;
    uint256 public constant PRICE = 0; // 0.05 ether
    uint256 internal constant WINNER_CUT = 100;
    string internal constant IPFS_UNKNOWN = "Qmbzf9grQq4rN1ZmZvrrjyWg3wC8Hx3BqUv16kpWsPpVLM"; // ***
    string internal constant IPFS_WINNER = "QmXyasrdptv9zzGU1iK6uNSth4RpRAxn4r8ga9GK4R68nY"; // ***
    string internal constant IPFS_LOSER = "QmZEDgZ8ujyu6gfvU1gHsTfZN2MnKUe57j5qXQ2ePBWKjA"; // ***
    string internal constant TOKEN_NAME = "RandomEDGE Free";
    string internal constant TOKEN_SYMBOL = "RE";

    // State
    // ------------------------------------------------------------------------
    bool public isFinished;
    bool public isRngRequested;
    address public winnerAddress;
    uint256 public contributed;
    uint256 public startTime;
    
    // Chainlink
    // ------------------------------------------------------------------------
    bytes32 internal constant KEY_HASH = 0xAA77729D3466CA35AE8D28B3BBAC7CC36A5031EFDC430821C02BC31A238AF445; // MAINNET
    uint256 internal constant VRF_FEE = 2 * 10 ** 18; // MAINNET
    address public constant VRF_COORDINATOR = 0xf0d54349aDdcf704F77AE15b96510dEA15cb7952; // MAINNET
    address public constant LINK_TOKEN = 0x514910771AF9Ca656af840dff83E8264EcF986CA; // MAINNET
    bytes32 public requestId;
    uint256 public randomResult;

    // Events
    // ------------------------------------------------------------------------
    event BaseTokenURIChanged(string baseTokenURI);
    event Received(address, uint256);

    // Constructor
    // ------------------------------------------------------------------------
    constructor() VRFConsumerBase(VRF_COORDINATOR, LINK_TOKEN) ERC721(TOKEN_NAME, TOKEN_SYMBOL) {
        startTime = block.timestamp + 7 days;
    }

    // Randomness/state advancing functions
    // ------------------------------------------------------------------------
    function requestResult() external onlyOwner {
        require(totalSupply() > 0, "NO_TICKETS");
        require(!isRngRequested, "ALREADY_REQUESTED");
        require(LINK.balanceOf(address(this)) >= VRF_FEE, "NEED_LINK");
        requestId = requestRandomness(KEY_HASH, VRF_FEE);
        isRngRequested = true;
    }

    function fulfillRandomness(bytes32 _requestId, uint256 randomness) internal override {
        require(requestId == _requestId, "INVALID_REQUEST");
        randomResult = (randomness % totalSupply()) + 1; // 1 to totalSupply() inclusive
    }
    
    function finalize() external onlyOwner {
        winnerAddress = ownerOf(randomResult);
        require(winnerAddress != address(0), "NO_WINNER");
        require(!isFinished, "PAID_OUT");
        isFinished = true;
        winnerAddress.call{value: winnerCut()}("");
    }
    
    function winnerCut() public view returns (uint256) {
        return contributed * WINNER_CUT / 100;
    }
    
    function isStarted() public view returns (bool) {
        return startTime < block.timestamp;
    }
    
    function setStartTime(uint256 _startTime) external onlyOwner {
        require(_startTime < startTime, "REDUCE_ONLY");
        startTime = _startTime;
    }

    // Mint functions
    // ------------------------------------------------------------------------
    function mint(uint256 quantity) external payable nonReentrant {
        require(isStarted(), "NOT_YET_STARTED");
        require(totalSupply() < MAX_SUPPLY, "SOLD_OUT");
        require(!isRngRequested, "LATE_CUTOFF");
        require(quantity > 0, "ZERO_QUANTITY");
        require(totalSupply() + quantity <= MAX_SUPPLY, "EXCEEDS_MAX_SUPPLY");
        require(msg.value >= PRICE * quantity, "INVALID_ETH_AMOUNT");

        for (uint256 i = 0; i < quantity; i++) {
            _safeMint(msg.sender, totalSupply() + 1);
        }
        contributed = contributed + msg.value;
    }

    // URI Functions
    // ------------------------------------------------------------------------
    function tokenURI(uint256 tokenId) public view override(ERC721) returns (string memory) {
        require(_exists(tokenId), "Cannot query non-existent token");
        string memory outStr = string(abi.encodePacked("data:application/json;utf8,", '{"name":"', TOKEN_NAME, ' #', tokenId.toString(), '","image": "ipfs://'));
        string memory attributes = string(abi.encodePacked('", "attributes":[{"trait_type": "Winner","value":"'));
        string memory endJson = '"}]}';
        if (randomResult != 0) {
            if (randomResult == tokenId) {
                outStr = string(abi.encodePacked(outStr, IPFS_WINNER, attributes, "Yes", endJson));
            } else {
                outStr = string(abi.encodePacked(outStr, IPFS_LOSER, attributes, "No", endJson));
            }
        } else {
            outStr = string(abi.encodePacked(outStr, IPFS_UNKNOWN, attributes, "???", endJson));
        }
        return outStr;
    }

    // Receive & Withdrawal functions
    // ------------------------------------------------------------------------
    receive() external payable {
        if (!isFinished) {
            contributed = contributed + msg.value;
        }
        emit Received(msg.sender, msg.value);
    }
    
    function withdrawErc20(IERC20 token) external onlyOwner {
        require(token.transfer(msg.sender, token.balanceOf(address(this))), "Transfer failed");
    }

    function emergencyWithdraw() external onlyOwner {
        owner().call{value: address(this).balance}("");
    }
}

File 1 of 16: Address.sol
// SPDX-License-Identifier: MIT

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 2 of 16: Context.sol
// SPDX-License-Identifier: MIT

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 3 of 16: ERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "IERC165.sol";

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

File 4 of 16: ERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "IERC721.sol";
import "IERC721Receiver.sol";
import "IERC721Metadata.sol";
import "Address.sol";
import "Context.sol";
import "Strings.sol";
import "ERC165.sol";

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        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 5 of 16: ERC721Enumerable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "ERC721.sol";
import "IERC721Enumerable.sol";

/**
 * @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 6 of 16: IERC165.sol
// SPDX-License-Identifier: MIT

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 7 of 16: IERC721.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "IERC165.sol";

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

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

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

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

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

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

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

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

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

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

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

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

File 8 of 16: IERC721Enumerable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "IERC721.sol";

/**
 * @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 9 of 16: IERC721Metadata.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "IERC721.sol";

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

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

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

File 10 of 16: IERC721Receiver.sol
// SPDX-License-Identifier: MIT

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 11 of 16: LinkTokenInterface.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

interface LinkTokenInterface {

  function allowance(
    address owner,
    address spender
  )
    external
    view
    returns (
      uint256 remaining
    );

  function approve(
    address spender,
    uint256 value
  )
    external
    returns (
      bool success
    );

  function balanceOf(
    address owner
  )
    external
    view
    returns (
      uint256 balance
    );

  function decimals()
    external
    view
    returns (
      uint8 decimalPlaces
    );

  function decreaseApproval(
    address spender,
    uint256 addedValue
  )
    external
    returns (
      bool success
    );

  function increaseApproval(
    address spender,
    uint256 subtractedValue
  ) external;

  function name()
    external
    view
    returns (
      string memory tokenName
    );

  function symbol()
    external
    view
    returns (
      string memory tokenSymbol
    );

  function totalSupply()
    external
    view
    returns (
      uint256 totalTokensIssued
    );

  function transfer(
    address to,
    uint256 value
  )
    external
    returns (
      bool success
    );

  function transferAndCall(
    address to,
    uint256 value,
    bytes calldata data
  )
    external
    returns (
      bool success
    );

  function transferFrom(
    address from,
    address to,
    uint256 value
  )
    external
    returns (
      bool success
    );

}

File 13 of 16: Ownable.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "Context.sol";

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

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _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 14 of 16: Strings.sol
// SPDX-License-Identifier: MIT

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 15 of 16: VRFConsumerBase.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

import "LinkTokenInterface.sol";

import "VRFRequestIDBase.sol";

/** ****************************************************************************
 * @notice Interface for contracts using VRF randomness
 * *****************************************************************************
 * @dev PURPOSE
 *
 * @dev Reggie the Random Oracle (not his real job) wants to provide randomness
 * @dev to Vera the verifier in such a way that Vera can be sure he's not
 * @dev making his output up to suit himself. Reggie provides Vera a public key
 * @dev to which he knows the secret key. Each time Vera provides a seed to
 * @dev Reggie, he gives back a value which is computed completely
 * @dev deterministically from the seed and the secret key.
 *
 * @dev Reggie provides a proof by which Vera can verify that the output was
 * @dev correctly computed once Reggie tells it to her, but without that proof,
 * @dev the output is indistinguishable to her from a uniform random sample
 * @dev from the output space.
 *
 * @dev The purpose of this contract is to make it easy for unrelated contracts
 * @dev to talk to Vera the verifier about the work Reggie is doing, to provide
 * @dev simple access to a verifiable source of randomness.
 * *****************************************************************************
 * @dev USAGE
 *
 * @dev Calling contracts must inherit from VRFConsumerBase, and can
 * @dev initialize VRFConsumerBase's attributes in their constructor as
 * @dev shown:
 *
 * @dev   contract VRFConsumer {
 * @dev     constuctor(<other arguments>, address _vrfCoordinator, address _link)
 * @dev       VRFConsumerBase(_vrfCoordinator, _link) public {
 * @dev         <initialization with other arguments goes here>
 * @dev       }
 * @dev   }
 *
 * @dev The oracle will have given you an ID for the VRF keypair they have
 * @dev committed to (let's call it keyHash), and have told you the minimum LINK
 * @dev price for VRF service. Make sure your contract has sufficient LINK, and
 * @dev call requestRandomness(keyHash, fee, seed), where seed is the input you
 * @dev want to generate randomness from.
 *
 * @dev Once the VRFCoordinator has received and validated the oracle's response
 * @dev to your request, it will call your contract's fulfillRandomness method.
 *
 * @dev The randomness argument to fulfillRandomness is the actual random value
 * @dev generated from your seed.
 *
 * @dev The requestId argument is generated from the keyHash and the seed by
 * @dev makeRequestId(keyHash, seed). If your contract could have concurrent
 * @dev requests open, you can use the requestId to track which seed is
 * @dev associated with which randomness. See VRFRequestIDBase.sol for more
 * @dev details. (See "SECURITY CONSIDERATIONS" for principles to keep in mind,
 * @dev if your contract could have multiple requests in flight simultaneously.)
 *
 * @dev Colliding `requestId`s are cryptographically impossible as long as seeds
 * @dev differ. (Which is critical to making unpredictable randomness! See the
 * @dev next section.)
 *
 * *****************************************************************************
 * @dev SECURITY CONSIDERATIONS
 *
 * @dev A method with the ability to call your fulfillRandomness method directly
 * @dev could spoof a VRF response with any random value, so it's critical that
 * @dev it cannot be directly called by anything other than this base contract
 * @dev (specifically, by the VRFConsumerBase.rawFulfillRandomness method).
 *
 * @dev For your users to trust that your contract's random behavior is free
 * @dev from malicious interference, it's best if you can write it so that all
 * @dev behaviors implied by a VRF response are executed *during* your
 * @dev fulfillRandomness method. If your contract must store the response (or
 * @dev anything derived from it) and use it later, you must ensure that any
 * @dev user-significant behavior which depends on that stored value cannot be
 * @dev manipulated by a subsequent VRF request.
 *
 * @dev Similarly, both miners and the VRF oracle itself have some influence
 * @dev over the order in which VRF responses appear on the blockchain, so if
 * @dev your contract could have multiple VRF requests in flight simultaneously,
 * @dev you must ensure that the order in which the VRF responses arrive cannot
 * @dev be used to manipulate your contract's user-significant behavior.
 *
 * @dev Since the ultimate input to the VRF is mixed with the block hash of the
 * @dev block in which the request is made, user-provided seeds have no impact
 * @dev on its economic security properties. They are only included for API
 * @dev compatability with previous versions of this contract.
 *
 * @dev Since the block hash of the block which contains the requestRandomness
 * @dev call is mixed into the input to the VRF *last*, a sufficiently powerful
 * @dev miner could, in principle, fork the blockchain to evict the block
 * @dev containing the request, forcing the request to be included in a
 * @dev different block with a different hash, and therefore a different input
 * @dev to the VRF. However, such an attack would incur a substantial economic
 * @dev cost. This cost scales with the number of blocks the VRF oracle waits
 * @dev until it calls responds to a request.
 */
abstract contract VRFConsumerBase is VRFRequestIDBase {

  /**
   * @notice fulfillRandomness handles the VRF response. Your contract must
   * @notice implement it. See "SECURITY CONSIDERATIONS" above for important
   * @notice principles to keep in mind when implementing your fulfillRandomness
   * @notice method.
   *
   * @dev VRFConsumerBase expects its subcontracts to have a method with this
   * @dev signature, and will call it once it has verified the proof
   * @dev associated with the randomness. (It is triggered via a call to
   * @dev rawFulfillRandomness, below.)
   *
   * @param requestId The Id initially returned by requestRandomness
   * @param randomness the VRF output
   */
  function fulfillRandomness(
    bytes32 requestId,
    uint256 randomness
  )
    internal
    virtual;

  /**
   * @dev In order to keep backwards compatibility we have kept the user
   * seed field around. We remove the use of it because given that the blockhash
   * enters later, it overrides whatever randomness the used seed provides.
   * Given that it adds no security, and can easily lead to misunderstandings,
   * we have removed it from usage and can now provide a simpler API.
   */
  uint256 constant private USER_SEED_PLACEHOLDER = 0;

  /**
   * @notice requestRandomness initiates a request for VRF output given _seed
   *
   * @dev The fulfillRandomness method receives the output, once it's provided
   * @dev by the Oracle, and verified by the vrfCoordinator.
   *
   * @dev The _keyHash must already be registered with the VRFCoordinator, and
   * @dev the _fee must exceed the fee specified during registration of the
   * @dev _keyHash.
   *
   * @dev The _seed parameter is vestigial, and is kept only for API
   * @dev compatibility with older versions. It can't *hurt* to mix in some of
   * @dev your own randomness, here, but it's not necessary because the VRF
   * @dev oracle will mix the hash of the block containing your request into the
   * @dev VRF seed it ultimately uses.
   *
   * @param _keyHash ID of public key against which randomness is generated
   * @param _fee The amount of LINK to send with the request
   *
   * @return requestId unique ID for this request
   *
   * @dev The returned requestId can be used to distinguish responses to
   * @dev concurrent requests. It is passed as the first argument to
   * @dev fulfillRandomness.
   */
  function requestRandomness(
    bytes32 _keyHash,
    uint256 _fee
  )
    internal
    returns (
      bytes32 requestId
    )
  {
    LINK.transferAndCall(vrfCoordinator, _fee, abi.encode(_keyHash, USER_SEED_PLACEHOLDER));
    // This is the seed passed to VRFCoordinator. The oracle will mix this with
    // the hash of the block containing this request to obtain the seed/input
    // which is finally passed to the VRF cryptographic machinery.
    uint256 vRFSeed  = makeVRFInputSeed(_keyHash, USER_SEED_PLACEHOLDER, address(this), nonces[_keyHash]);
    // nonces[_keyHash] must stay in sync with
    // VRFCoordinator.nonces[_keyHash][this], which was incremented by the above
    // successful LINK.transferAndCall (in VRFCoordinator.randomnessRequest).
    // This provides protection against the user repeating their input seed,
    // which would result in a predictable/duplicate output, if multiple such
    // requests appeared in the same block.
    nonces[_keyHash] = nonces[_keyHash] + 1;
    return makeRequestId(_keyHash, vRFSeed);
  }

  LinkTokenInterface immutable internal LINK;
  address immutable private vrfCoordinator;

  // Nonces for each VRF key from which randomness has been requested.
  //
  // Must stay in sync with VRFCoordinator[_keyHash][this]
  mapping(bytes32 /* keyHash */ => uint256 /* nonce */) private nonces;

  /**
   * @param _vrfCoordinator address of VRFCoordinator contract
   * @param _link address of LINK token contract
   *
   * @dev https://docs.chain.link/docs/link-token-contracts
   */
  constructor(
    address _vrfCoordinator,
    address _link
  ) {
    vrfCoordinator = _vrfCoordinator;
    LINK = LinkTokenInterface(_link);
  }

  // rawFulfillRandomness is called by VRFCoordinator when it receives a valid VRF
  // proof. rawFulfillRandomness then calls fulfillRandomness, after validating
  // the origin of the call
  function rawFulfillRandomness(
    bytes32 requestId,
    uint256 randomness
  )
    external
  {
    require(msg.sender == vrfCoordinator, "Only VRFCoordinator can fulfill");
    fulfillRandomness(requestId, randomness);
  }
}

File 16 of 16: VRFRequestIDBase.sol
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.0;

contract VRFRequestIDBase {

  /**
   * @notice returns the seed which is actually input to the VRF coordinator
   *
   * @dev To prevent repetition of VRF output due to repetition of the
   * @dev user-supplied seed, that seed is combined in a hash with the
   * @dev user-specific nonce, and the address of the consuming contract. The
   * @dev risk of repetition is mostly mitigated by inclusion of a blockhash in
   * @dev the final seed, but the nonce does protect against repetition in
   * @dev requests which are included in a single block.
   *
   * @param _userSeed VRF seed input provided by user
   * @param _requester Address of the requesting contract
   * @param _nonce User-specific nonce at the time of the request
   */
  function makeVRFInputSeed(
    bytes32 _keyHash,
    uint256 _userSeed,
    address _requester,
    uint256 _nonce
  )
    internal
    pure
    returns (
      uint256
    )
  {
    return uint256(keccak256(abi.encode(_keyHash, _userSeed, _requester, _nonce)));
  }

  /**
   * @notice Returns the id for this request
   * @param _keyHash The serviceAgreement ID to be used for this request
   * @param _vRFInputSeed The seed to be passed directly to the VRF
   * @return The id for this request
   *
   * @dev Note that _vRFInputSeed is not the seed passed by the consuming
   * @dev contract, but the one generated by makeVRFInputSeed
   */
  function makeRequestId(
    bytes32 _keyHash,
    uint256 _vRFInputSeed
  )
    internal
    pure
    returns (
      bytes32
    )
  {
    return keccak256(abi.encodePacked(_keyHash, _vRFInputSeed));
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"string","name":"baseTokenURI","type":"string"}],"name":"BaseTokenURIChanged","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":"","type":"address"},{"indexed":false,"internalType":"uint256","name":"","type":"uint256"}],"name":"Received","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"LINK_TOKEN","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"VRF_COORDINATOR","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"contributed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"emergencyWithdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"finalize","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isFinished","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isRngRequested","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"isStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"quantity","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","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":"randomResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"},{"internalType":"uint256","name":"randomness","type":"uint256"}],"name":"rawFulfillRandomness","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"requestId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"requestResult","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":"uint256","name":"_startTime","type":"uint256"}],"name":"setStartTime","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startTime","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"winnerAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"winnerCut","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"contract IERC20","name":"token","type":"address"}],"name":"withdrawErc20","outputs":[],"stateMutability":"nonpayable","type":"function"},{"stateMutability":"payable","type":"receive"}]

60c06040523480156200001157600080fd5b50604080518082018252600f81526e52616e646f6d45444745204672656560881b602080830191825283518085019094526002845261524560f01b90840152815173f0d54349addcf704f77ae15b96510dea15cb79529373514910771af9ca656af840dff83e8264ecf986ca939290916200008f916000916200014e565b508051620000a59060019060208401906200014e565b505050620000c2620000bc620000f860201b60201c565b620000fc565b6001600160601b0319606092831b811660a052911b166080526001600c55620000ef4262093a80620001f4565b600f5562000258565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b8280546200015c906200021b565b90600052602060002090601f016020900481019282620001805760008555620001cb565b82601f106200019b57805160ff1916838001178555620001cb565b82800160010185558215620001cb579182015b82811115620001cb578251825591602001919060010190620001ae565b50620001d9929150620001dd565b5090565b5b80821115620001d95760008155600101620001de565b600082198211156200021657634e487b7160e01b600052601160045260246000fd5b500190565b600181811c908216806200023057607f821691505b602082108114156200025257634e487b7160e01b600052602260045260246000fd5b50919050565b60805160601c60a05160601c612bc66200029260003960008181610f6c0152611b61015260008181610d8b0152611b320152612bc66000f3fe6080604052600436106101d35760003560e01c80636d7180d3116100fe5780636d7180d31461048857806370a082311461049d578063715018a6146104bd57806378e97925146104d25780637b352962146104e85780638d859f3e146105025780638da5cb5b1461051757806394985ddd1461052c57806395d89b411461054c578063a0712d6814610561578063a22cb46514610574578063a7150e6a14610594578063b88d4fde146105a9578063c7e42b1b146105c9578063c87b56dd146105e9578063db2e21bc14610609578063e985e9c51461061e578063ed7a4e0b1461063e578063eedac3a614610664578063f2fde38b1461068c57600080fd5b80626d6cae1461023457806301ffc9a71461025d57806305f6a9241461028d57806306fdde03146102c2578063081812fc146102e4578063095ea7b314610304578063111070e414610326578063112f19071461034557806318160ddd1461035b57806323b872dd146103705780632f745c591461039057806332cb6b0c146103b05780633e0a322d146103c657806342619f66146103e657806342842e0e146103fc5780634bb278f31461041c5780634f6ccce714610431578063544736e6146104515780636352211e1461046857600080fd5b3661022f57600d5460ff166101f45734600e546101f09190612967565b600e555b7f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f885258743334604051610225929190612833565b60405180910390a1005b600080fd5b34801561024057600080fd5b5061024a60105481565b6040519081526020015b60405180910390f35b34801561026957600080fd5b5061027d610278366004612590565b6106ac565b6040519015158152602001610254565b34801561029957600080fd5b506102b573f0d54349addcf704f77ae15b96510dea15cb795281565b60405161025491906127e2565b3480156102ce57600080fd5b506102d76106d7565b604051610254919061287c565b3480156102f057600080fd5b506102b56102ff3660046125ca565b610769565b34801561031057600080fd5b5061032461031f366004612525565b6107f6565b005b34801561033257600080fd5b50600d5461027d90610100900460ff1681565b34801561035157600080fd5b5061024a600e5481565b34801561036757600080fd5b5060085461024a565b34801561037c57600080fd5b5061032461038b3660046123d7565b610907565b34801561039c57600080fd5b5061024a6103ab366004612525565b610938565b3480156103bc57600080fd5b5061024a61138881565b3480156103d257600080fd5b506103246103e13660046125ca565b6109ce565b3480156103f257600080fd5b5061024a60115481565b34801561040857600080fd5b506103246104173660046123d7565b610a41565b34801561042857600080fd5b50610324610a5c565b34801561043d57600080fd5b5061024a61044c3660046125ca565b610ba0565b34801561045d57600080fd5b50600f54421161027d565b34801561047457600080fd5b506102b56104833660046125ca565b610c33565b34801561049457600080fd5b50610324610caa565b3480156104a957600080fd5b5061024a6104b836600461237a565b610e90565b3480156104c957600080fd5b50610324610f17565b3480156104de57600080fd5b5061024a600f5481565b3480156104f457600080fd5b50600d5461027d9060ff1681565b34801561050e57600080fd5b5061024a600081565b34801561052357600080fd5b506102b5610f52565b34801561053857600080fd5b5061032461054736600461256e565b610f61565b34801561055857600080fd5b506102d7610fe7565b61032461056f3660046125ca565b610ff6565b34801561058057600080fd5b5061032461058f3660046124f7565b611258565b3480156105a057600080fd5b5061024a611319565b3480156105b557600080fd5b506103246105c4366004612418565b61133a565b3480156105d557600080fd5b506103246105e436600461237a565b611372565b3480156105f557600080fd5b506102d76106043660046125ca565b6114d7565b34801561061557600080fd5b506103246116ca565b34801561062a57600080fd5b5061027d61063936600461239e565b611713565b34801561064a57600080fd5b50600d546102b5906201000090046001600160a01b031681565b34801561067057600080fd5b506102b573514910771af9ca656af840dff83e8264ecf986ca81565b34801561069857600080fd5b506103246106a736600461237a565b611741565b60006001600160e01b0319821663780e9d6360e01b14806106d157506106d1826117de565b92915050565b6060600080546106e6906129f5565b80601f0160208091040260200160405190810160405280929190818152602001828054610712906129f5565b801561075f5780601f106107345761010080835404028352916020019161075f565b820191906000526020600020905b81548152906001019060200180831161074257829003601f168201915b5050505050905090565b60006107748261182e565b6107da5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061080182610c33565b9050806001600160a01b0316836001600160a01b0316141561086f5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084016107d1565b336001600160a01b038216148061088b575061088b8133611713565b6108f85760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776044820152771b995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b60421b60648201526084016107d1565b610902838361184b565b505050565b61091133826118b9565b61092d5760405162461bcd60e51b81526004016107d190612916565b610902838383611983565b600061094383610e90565b82106109a55760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b60648201526084016107d1565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b336109d7610f52565b6001600160a01b0316146109fd5760405162461bcd60e51b81526004016107d1906128e1565b600f548110610a3c5760405162461bcd60e51b815260206004820152600b60248201526a5245445543455f4f4e4c5960a81b60448201526064016107d1565b600f55565b6109028383836040518060200160405280600081525061133a565b33610a65610f52565b6001600160a01b031614610a8b5760405162461bcd60e51b81526004016107d1906128e1565b610a96601154610c33565b600d805462010000600160b01b031916620100006001600160a01b0393841681029190911791829055900416610afa5760405162461bcd60e51b81526020600482015260096024820152682727afaba4a72722a960b91b60448201526064016107d1565b600d5460ff1615610b385760405162461bcd60e51b81526020600482015260086024820152671410525117d3d55560c21b60448201526064016107d1565b600d805460ff1916600117908190556001600160a01b036201000090910416610b5f611319565b6040515b60006040518083038185875af1925050503d8060008114610902576040519150601f19603f3d011682016040523d82523d6000602084013e505050565b6000610bab60085490565b8210610c0e5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b60648201526084016107d1565b60088281548110610c2157610c21612aa1565b90600052602060002001549050919050565b6000818152600260205260408120546001600160a01b0316806106d15760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b60648201526084016107d1565b33610cb3610f52565b6001600160a01b031614610cd95760405162461bcd60e51b81526004016107d1906128e1565b6000610ce460085490565b11610d1e5760405162461bcd60e51b815260206004820152600a6024820152694e4f5f5449434b45545360b01b60448201526064016107d1565b600d54610100900460ff1615610d6a5760405162461bcd60e51b81526020600482015260116024820152701053149150511657d49154555154d51151607a1b60448201526064016107d1565b6040516370a0823160e01b8152671bc16d674ec80000906001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016906370a0823190610dc09030906004016127e2565b60206040518083038186803b158015610dd857600080fd5b505afa158015610dec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e1091906125e3565b1015610e4a5760405162461bcd60e51b81526020600482015260096024820152684e4545445f4c494e4b60b81b60448201526064016107d1565b610e7c7faa77729d3466ca35ae8d28b3bbac7cc36a5031efdc430821c02bc31a238af445671bc16d674ec80000611b2e565b601055600d805461ff001916610100179055565b60006001600160a01b038216610efb5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b60648201526084016107d1565b506001600160a01b031660009081526003602052604090205490565b33610f20610f52565b6001600160a01b031614610f465760405162461bcd60e51b81526004016107d1906128e1565b610f506000611cb9565b565b600a546001600160a01b031690565b336001600160a01b037f00000000000000000000000000000000000000000000000000000000000000001614610fd95760405162461bcd60e51b815260206004820152601f60248201527f4f6e6c7920565246436f6f7264696e61746f722063616e2066756c66696c6c0060448201526064016107d1565b610fe38282611d0b565b5050565b6060600180546106e6906129f5565b6002600c5414156110495760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016107d1565b6002600c55600f5442116110915760405162461bcd60e51b815260206004820152600f60248201526e1393d517d6515517d4d51054951151608a1b60448201526064016107d1565b61138861109d60085490565b106110d55760405162461bcd60e51b815260206004820152600860248201526714d3d31117d3d55560c21b60448201526064016107d1565b600d54610100900460ff161561111b5760405162461bcd60e51b815260206004820152600b60248201526a2620aa22afa1aaaa27a32360a91b60448201526064016107d1565b6000811161115b5760405162461bcd60e51b815260206004820152600d60248201526c5a45524f5f5155414e5449545960981b60448201526064016107d1565b6113888161116860085490565b6111729190612967565b11156111b55760405162461bcd60e51b8152602060048201526012602482015271455843454544535f4d41585f535550504c5960701b60448201526064016107d1565b6111c0816000612993565b3410156112045760405162461bcd60e51b81526020600482015260126024820152711253959053125117d1551217d05353d5539560721b60448201526064016107d1565b60005b8181101561123e5761122c3361121c60085490565b611227906001612967565b611d6d565b8061123681612a30565b915050611207565b5034600e5461124d9190612967565b600e55506001600c55565b6001600160a01b0382163314156112ad5760405162461bcd60e51b815260206004820152601960248201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b60448201526064016107d1565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6000606480600e5461132b9190612993565b611335919061297f565b905090565b61134433836118b9565b6113605760405162461bcd60e51b81526004016107d190612916565b61136c84848484611d87565b50505050565b3361137b610f52565b6001600160a01b0316146113a15760405162461bcd60e51b81526004016107d1906128e1565b6040516370a0823160e01b81526001600160a01b0382169063a9059cbb90339083906370a08231906113d79030906004016127e2565b60206040518083038186803b1580156113ef57600080fd5b505afa158015611403573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061142791906125e3565b6040518363ffffffff1660e01b8152600401611444929190612833565b602060405180830381600087803b15801561145e57600080fd5b505af1158015611472573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114969190612551565b6114d45760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b60448201526064016107d1565b50565b60606114e28261182e565b61152e5760405162461bcd60e51b815260206004820152601f60248201527f43616e6e6f74207175657279206e6f6e2d6578697374656e7420746f6b656e0060448201526064016107d1565b60006040518060400160405280600f81526020016e52616e646f6d45444745204672656560881b81525061156184611dba565b60405160200161157292919061274b565b604051602081830303815290604052905060006040516020016115d3907f222c202261747472696275746573223a5b7b2274726169745f74797065223a20815271112bb4b73732b91116113b30b63ab2911d1160711b602082015260320190565b60408051601f198184030181528282019091526004825263227d5d7d60e01b6020830152601154909250156116805784601154141561165157826040518060600160405280602e8152602001612b63602e9139838360405160200161163b949392919061268d565b60405160208183030381529060405292506116c1565b826040518060600160405280602e8152602001612b35602e9139838360405160200161163b9493929190612628565b826040518060600160405280602e8152602001612b07602e913983836040516020016116af94939291906126f3565b60405160208183030381529060405292505b50909392505050565b336116d3610f52565b6001600160a01b0316146116f95760405162461bcd60e51b81526004016107d1906128e1565b611701610f52565b6001600160a01b031647604051610b63565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b3361174a610f52565b6001600160a01b0316146117705760405162461bcd60e51b81526004016107d1906128e1565b6001600160a01b0381166117d55760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016107d1565b6114d481611cb9565b60006001600160e01b031982166380ac58cd60e01b148061180f57506001600160e01b03198216635b5e139f60e01b145b806106d157506301ffc9a760e01b6001600160e01b03198316146106d1565b6000908152600260205260409020546001600160a01b0316151590565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061188082610c33565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006118c48261182e565b6119255760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016107d1565b600061193083610c33565b9050806001600160a01b0316846001600160a01b0316148061196b5750836001600160a01b031661196084610769565b6001600160a01b0316145b8061197b575061197b8185611713565b949350505050565b826001600160a01b031661199682610c33565b6001600160a01b0316146119fe5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b60648201526084016107d1565b6001600160a01b038216611a605760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016107d1565b611a6b838383611eb7565b611a7660008261184b565b6001600160a01b0383166000908152600360205260408120805460019290611a9f9084906129b2565b90915550506001600160a01b0382166000908152600360205260408120805460019290611acd908490612967565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634000aea07f000000000000000000000000000000000000000000000000000000000000000084866000604051602001611b9e929190918252602082015260400190565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401611bcb9392919061284c565b602060405180830381600087803b158015611be557600080fd5b505af1158015611bf9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c1d9190612551565b506000838152600b6020818152604080842054815180840189905280830186905230606082015260808082018390528351808303909101815260a090910190925281519183019190912093879052919052611c79906001612967565b6000858152600b602052604090205561197b8482604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b8160105414611d4e5760405162461bcd60e51b815260206004820152600f60248201526e1253959053125117d49154555154d5608a1b60448201526064016107d1565b600854611d5b9082612a4b565b611d66906001612967565b6011555050565b610fe3828260405180602001604052806000815250611f6f565b611d92848484611983565b611d9e84848484611fa2565b61136c5760405162461bcd60e51b81526004016107d19061288f565b606081611dde5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611e085780611df281612a30565b9150611e019050600a8361297f565b9150611de2565b6000816001600160401b03811115611e2257611e22612ab7565b6040519080825280601f01601f191660200182016040528015611e4c576020820181803683370190505b5090505b841561197b57611e616001836129b2565b9150611e6e600a86612a4b565b611e79906030612967565b60f81b818381518110611e8e57611e8e612aa1565b60200101906001600160f81b031916908160001a905350611eb0600a8661297f565b9450611e50565b6001600160a01b038316611f1257611f0d81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b611f35565b816001600160a01b0316836001600160a01b031614611f3557611f3583826120ac565b6001600160a01b038216611f4c5761090281612149565b826001600160a01b0316826001600160a01b0316146109025761090282826121f8565b611f79838361223c565b611f866000848484611fa2565b6109025760405162461bcd60e51b81526004016107d19061288f565b60006001600160a01b0384163b156120a457604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611fe69033908990889088906004016127f6565b602060405180830381600087803b15801561200057600080fd5b505af1925050508015612030575060408051601f3d908101601f1916820190925261202d918101906125ad565b60015b61208a573d80801561205e576040519150601f19603f3d011682016040523d82523d6000602084013e612063565b606091505b5080516120825760405162461bcd60e51b81526004016107d19061288f565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061197b565b50600161197b565b600060016120b984610e90565b6120c391906129b2565b600083815260076020526040902054909150808214612116576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061215b906001906129b2565b6000838152600960205260408120546008805493945090928490811061218357612183612aa1565b9060005260206000200154905080600883815481106121a4576121a4612aa1565b60009182526020808320909101929092558281526009909152604080822084905585825281205560088054806121dc576121dc612a8b565b6001900381819060005260206000200160009055905550505050565b600061220383610e90565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160a01b0382166122925760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016107d1565b61229b8161182e565b156122e75760405162461bcd60e51b815260206004820152601c60248201527b115490cdcc8c4e881d1bdad95b88185b1c9958591e481b5a5b9d195960221b60448201526064016107d1565b6122f360008383611eb7565b6001600160a01b038216600090815260036020526040812080546001929061231c908490612967565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006020828403121561238c57600080fd5b813561239781612acd565b9392505050565b600080604083850312156123b157600080fd5b82356123bc81612acd565b915060208301356123cc81612acd565b809150509250929050565b6000806000606084860312156123ec57600080fd5b83356123f781612acd565b9250602084013561240781612acd565b929592945050506040919091013590565b6000806000806080858703121561242e57600080fd5b843561243981612acd565b9350602085013561244981612acd565b92506040850135915060608501356001600160401b038082111561246c57600080fd5b818701915087601f83011261248057600080fd5b81358181111561249257612492612ab7565b604051601f8201601f19908116603f011681019083821181831017156124ba576124ba612ab7565b816040528281528a60208487010111156124d357600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6000806040838503121561250a57600080fd5b823561251581612acd565b915060208301356123cc81612ae2565b6000806040838503121561253857600080fd5b823561254381612acd565b946020939093013593505050565b60006020828403121561256357600080fd5b815161239781612ae2565b6000806040838503121561258157600080fd5b50508035926020909101359150565b6000602082840312156125a257600080fd5b813561239781612af0565b6000602082840312156125bf57600080fd5b815161239781612af0565b6000602082840312156125dc57600080fd5b5035919050565b6000602082840312156125f557600080fd5b5051919050565b600081518084526126148160208601602086016129c9565b601f01601f19169290920160200192915050565b6000855161263a818460208a016129c9565b85519083019061264e818360208a016129c9565b85519101906126618183602089016129c9565b614e6f60f01b9101908152835161267f8160028401602088016129c9565b016002019695505050505050565b6000855161269f818460208a016129c9565b8551908301906126b3818360208a016129c9565b85519101906126c68183602089016129c9565b6259657360e81b910190815283516126e58160038401602088016129c9565b016003019695505050505050565b60008551612705818460208a016129c9565b855190830190612719818360208a016129c9565b855191019061272c8183602089016129c9565b623f3f3f60e81b910190815283516126e58160038401602088016129c9565b7a19185d184e985c1c1b1a58d85d1a5bdb8bda9cdbdb8edd5d198e0b602a1b8152683d913730b6b2911d1160b91b601b82015282516000906127948160248501602088016129c9565b61202360f01b60249184019182015283516127b68160268401602088016129c9565b72222c22696d616765223a2022697066733a2f2f60681b60269290910191820152603901949350505050565b6001600160a01b0391909116815260200190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612829908301846125fc565b9695505050505050565b6001600160a01b03929092168252602082015260400190565b60018060a01b038416815282602082015260606040820152600061287360608301846125fc565b95945050505050565b60208152600061239760208301846125fc565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6000821982111561297a5761297a612a5f565b500190565b60008261298e5761298e612a75565b500490565b60008160001904831182151516156129ad576129ad612a5f565b500290565b6000828210156129c4576129c4612a5f565b500390565b60005b838110156129e45781810151838201526020016129cc565b8381111561136c5750506000910152565b600181811c90821680612a0957607f821691505b60208210811415612a2a57634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415612a4457612a44612a5f565b5060010190565b600082612a5a57612a5a612a75565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146114d457600080fd5b80151581146114d457600080fd5b6001600160e01b0319811681146114d457600080fdfe516d627a66396772517134724e315a6d5a7672726a795767337743384878334271557631366b7057735070564c4d516d5a4544675a38756a797536676676553167487354665a4e324d6e4b556535376a3571585132655042574b6a41516d587961737264707476397a7a475531694b36754e5374683452705241786e347238676139474b345236386e59a264697066735822122052abc131d7a0111009ce5a6a0a62fd035512f0c14fc9a1d143e49de2e80b235864736f6c63430008070033

Deployed Bytecode

0x6080604052600436106101d35760003560e01c80636d7180d3116100fe5780636d7180d31461048857806370a082311461049d578063715018a6146104bd57806378e97925146104d25780637b352962146104e85780638d859f3e146105025780638da5cb5b1461051757806394985ddd1461052c57806395d89b411461054c578063a0712d6814610561578063a22cb46514610574578063a7150e6a14610594578063b88d4fde146105a9578063c7e42b1b146105c9578063c87b56dd146105e9578063db2e21bc14610609578063e985e9c51461061e578063ed7a4e0b1461063e578063eedac3a614610664578063f2fde38b1461068c57600080fd5b80626d6cae1461023457806301ffc9a71461025d57806305f6a9241461028d57806306fdde03146102c2578063081812fc146102e4578063095ea7b314610304578063111070e414610326578063112f19071461034557806318160ddd1461035b57806323b872dd146103705780632f745c591461039057806332cb6b0c146103b05780633e0a322d146103c657806342619f66146103e657806342842e0e146103fc5780634bb278f31461041c5780634f6ccce714610431578063544736e6146104515780636352211e1461046857600080fd5b3661022f57600d5460ff166101f45734600e546101f09190612967565b600e555b7f88a5966d370b9919b20f3e2c13ff65706f196a4e32cc2c12bf57088f885258743334604051610225929190612833565b60405180910390a1005b600080fd5b34801561024057600080fd5b5061024a60105481565b6040519081526020015b60405180910390f35b34801561026957600080fd5b5061027d610278366004612590565b6106ac565b6040519015158152602001610254565b34801561029957600080fd5b506102b573f0d54349addcf704f77ae15b96510dea15cb795281565b60405161025491906127e2565b3480156102ce57600080fd5b506102d76106d7565b604051610254919061287c565b3480156102f057600080fd5b506102b56102ff3660046125ca565b610769565b34801561031057600080fd5b5061032461031f366004612525565b6107f6565b005b34801561033257600080fd5b50600d5461027d90610100900460ff1681565b34801561035157600080fd5b5061024a600e5481565b34801561036757600080fd5b5060085461024a565b34801561037c57600080fd5b5061032461038b3660046123d7565b610907565b34801561039c57600080fd5b5061024a6103ab366004612525565b610938565b3480156103bc57600080fd5b5061024a61138881565b3480156103d257600080fd5b506103246103e13660046125ca565b6109ce565b3480156103f257600080fd5b5061024a60115481565b34801561040857600080fd5b506103246104173660046123d7565b610a41565b34801561042857600080fd5b50610324610a5c565b34801561043d57600080fd5b5061024a61044c3660046125ca565b610ba0565b34801561045d57600080fd5b50600f54421161027d565b34801561047457600080fd5b506102b56104833660046125ca565b610c33565b34801561049457600080fd5b50610324610caa565b3480156104a957600080fd5b5061024a6104b836600461237a565b610e90565b3480156104c957600080fd5b50610324610f17565b3480156104de57600080fd5b5061024a600f5481565b3480156104f457600080fd5b50600d5461027d9060ff1681565b34801561050e57600080fd5b5061024a600081565b34801561052357600080fd5b506102b5610f52565b34801561053857600080fd5b5061032461054736600461256e565b610f61565b34801561055857600080fd5b506102d7610fe7565b61032461056f3660046125ca565b610ff6565b34801561058057600080fd5b5061032461058f3660046124f7565b611258565b3480156105a057600080fd5b5061024a611319565b3480156105b557600080fd5b506103246105c4366004612418565b61133a565b3480156105d557600080fd5b506103246105e436600461237a565b611372565b3480156105f557600080fd5b506102d76106043660046125ca565b6114d7565b34801561061557600080fd5b506103246116ca565b34801561062a57600080fd5b5061027d61063936600461239e565b611713565b34801561064a57600080fd5b50600d546102b5906201000090046001600160a01b031681565b34801561067057600080fd5b506102b573514910771af9ca656af840dff83e8264ecf986ca81565b34801561069857600080fd5b506103246106a736600461237a565b611741565b60006001600160e01b0319821663780e9d6360e01b14806106d157506106d1826117de565b92915050565b6060600080546106e6906129f5565b80601f0160208091040260200160405190810160405280929190818152602001828054610712906129f5565b801561075f5780601f106107345761010080835404028352916020019161075f565b820191906000526020600020905b81548152906001019060200180831161074257829003601f168201915b5050505050905090565b60006107748261182e565b6107da5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b600061080182610c33565b9050806001600160a01b0316836001600160a01b0316141561086f5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084016107d1565b336001600160a01b038216148061088b575061088b8133611713565b6108f85760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f776044820152771b995c881b9bdc88185c1c1c9bdd995908199bdc88185b1b60421b60648201526084016107d1565b610902838361184b565b505050565b61091133826118b9565b61092d5760405162461bcd60e51b81526004016107d190612916565b610902838383611983565b600061094383610e90565b82106109a55760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b60648201526084016107d1565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b336109d7610f52565b6001600160a01b0316146109fd5760405162461bcd60e51b81526004016107d1906128e1565b600f548110610a3c5760405162461bcd60e51b815260206004820152600b60248201526a5245445543455f4f4e4c5960a81b60448201526064016107d1565b600f55565b6109028383836040518060200160405280600081525061133a565b33610a65610f52565b6001600160a01b031614610a8b5760405162461bcd60e51b81526004016107d1906128e1565b610a96601154610c33565b600d805462010000600160b01b031916620100006001600160a01b0393841681029190911791829055900416610afa5760405162461bcd60e51b81526020600482015260096024820152682727afaba4a72722a960b91b60448201526064016107d1565b600d5460ff1615610b385760405162461bcd60e51b81526020600482015260086024820152671410525117d3d55560c21b60448201526064016107d1565b600d805460ff1916600117908190556001600160a01b036201000090910416610b5f611319565b6040515b60006040518083038185875af1925050503d8060008114610902576040519150601f19603f3d011682016040523d82523d6000602084013e505050565b6000610bab60085490565b8210610c0e5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b60648201526084016107d1565b60088281548110610c2157610c21612aa1565b90600052602060002001549050919050565b6000818152600260205260408120546001600160a01b0316806106d15760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b60648201526084016107d1565b33610cb3610f52565b6001600160a01b031614610cd95760405162461bcd60e51b81526004016107d1906128e1565b6000610ce460085490565b11610d1e5760405162461bcd60e51b815260206004820152600a6024820152694e4f5f5449434b45545360b01b60448201526064016107d1565b600d54610100900460ff1615610d6a5760405162461bcd60e51b81526020600482015260116024820152701053149150511657d49154555154d51151607a1b60448201526064016107d1565b6040516370a0823160e01b8152671bc16d674ec80000906001600160a01b037f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca16906370a0823190610dc09030906004016127e2565b60206040518083038186803b158015610dd857600080fd5b505afa158015610dec573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610e1091906125e3565b1015610e4a5760405162461bcd60e51b81526020600482015260096024820152684e4545445f4c494e4b60b81b60448201526064016107d1565b610e7c7faa77729d3466ca35ae8d28b3bbac7cc36a5031efdc430821c02bc31a238af445671bc16d674ec80000611b2e565b601055600d805461ff001916610100179055565b60006001600160a01b038216610efb5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b60648201526084016107d1565b506001600160a01b031660009081526003602052604090205490565b33610f20610f52565b6001600160a01b031614610f465760405162461bcd60e51b81526004016107d1906128e1565b610f506000611cb9565b565b600a546001600160a01b031690565b336001600160a01b037f000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb79521614610fd95760405162461bcd60e51b815260206004820152601f60248201527f4f6e6c7920565246436f6f7264696e61746f722063616e2066756c66696c6c0060448201526064016107d1565b610fe38282611d0b565b5050565b6060600180546106e6906129f5565b6002600c5414156110495760405162461bcd60e51b815260206004820152601f60248201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c0060448201526064016107d1565b6002600c55600f5442116110915760405162461bcd60e51b815260206004820152600f60248201526e1393d517d6515517d4d51054951151608a1b60448201526064016107d1565b61138861109d60085490565b106110d55760405162461bcd60e51b815260206004820152600860248201526714d3d31117d3d55560c21b60448201526064016107d1565b600d54610100900460ff161561111b5760405162461bcd60e51b815260206004820152600b60248201526a2620aa22afa1aaaa27a32360a91b60448201526064016107d1565b6000811161115b5760405162461bcd60e51b815260206004820152600d60248201526c5a45524f5f5155414e5449545960981b60448201526064016107d1565b6113888161116860085490565b6111729190612967565b11156111b55760405162461bcd60e51b8152602060048201526012602482015271455843454544535f4d41585f535550504c5960701b60448201526064016107d1565b6111c0816000612993565b3410156112045760405162461bcd60e51b81526020600482015260126024820152711253959053125117d1551217d05353d5539560721b60448201526064016107d1565b60005b8181101561123e5761122c3361121c60085490565b611227906001612967565b611d6d565b8061123681612a30565b915050611207565b5034600e5461124d9190612967565b600e55506001600c55565b6001600160a01b0382163314156112ad5760405162461bcd60e51b815260206004820152601960248201527822a9219b99189d1030b8383937bb32903a379031b0b63632b960391b60448201526064016107d1565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b6000606480600e5461132b9190612993565b611335919061297f565b905090565b61134433836118b9565b6113605760405162461bcd60e51b81526004016107d190612916565b61136c84848484611d87565b50505050565b3361137b610f52565b6001600160a01b0316146113a15760405162461bcd60e51b81526004016107d1906128e1565b6040516370a0823160e01b81526001600160a01b0382169063a9059cbb90339083906370a08231906113d79030906004016127e2565b60206040518083038186803b1580156113ef57600080fd5b505afa158015611403573d6000803e3d6000fd5b505050506040513d601f19601f8201168201806040525081019061142791906125e3565b6040518363ffffffff1660e01b8152600401611444929190612833565b602060405180830381600087803b15801561145e57600080fd5b505af1158015611472573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906114969190612551565b6114d45760405162461bcd60e51b815260206004820152600f60248201526e151c985b9cd9995c8819985a5b1959608a1b60448201526064016107d1565b50565b60606114e28261182e565b61152e5760405162461bcd60e51b815260206004820152601f60248201527f43616e6e6f74207175657279206e6f6e2d6578697374656e7420746f6b656e0060448201526064016107d1565b60006040518060400160405280600f81526020016e52616e646f6d45444745204672656560881b81525061156184611dba565b60405160200161157292919061274b565b604051602081830303815290604052905060006040516020016115d3907f222c202261747472696275746573223a5b7b2274726169745f74797065223a20815271112bb4b73732b91116113b30b63ab2911d1160711b602082015260320190565b60408051601f198184030181528282019091526004825263227d5d7d60e01b6020830152601154909250156116805784601154141561165157826040518060600160405280602e8152602001612b63602e9139838360405160200161163b949392919061268d565b60405160208183030381529060405292506116c1565b826040518060600160405280602e8152602001612b35602e9139838360405160200161163b9493929190612628565b826040518060600160405280602e8152602001612b07602e913983836040516020016116af94939291906126f3565b60405160208183030381529060405292505b50909392505050565b336116d3610f52565b6001600160a01b0316146116f95760405162461bcd60e51b81526004016107d1906128e1565b611701610f52565b6001600160a01b031647604051610b63565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b3361174a610f52565b6001600160a01b0316146117705760405162461bcd60e51b81526004016107d1906128e1565b6001600160a01b0381166117d55760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016107d1565b6114d481611cb9565b60006001600160e01b031982166380ac58cd60e01b148061180f57506001600160e01b03198216635b5e139f60e01b145b806106d157506301ffc9a760e01b6001600160e01b03198316146106d1565b6000908152600260205260409020546001600160a01b0316151590565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061188082610c33565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b60006118c48261182e565b6119255760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084016107d1565b600061193083610c33565b9050806001600160a01b0316846001600160a01b0316148061196b5750836001600160a01b031661196084610769565b6001600160a01b0316145b8061197b575061197b8185611713565b949350505050565b826001600160a01b031661199682610c33565b6001600160a01b0316146119fe5760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b60648201526084016107d1565b6001600160a01b038216611a605760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016107d1565b611a6b838383611eb7565b611a7660008261184b565b6001600160a01b0383166000908152600360205260408120805460019290611a9f9084906129b2565b90915550506001600160a01b0382166000908152600360205260408120805460019290611acd908490612967565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b60007f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca6001600160a01b0316634000aea07f000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb795284866000604051602001611b9e929190918252602082015260400190565b6040516020818303038152906040526040518463ffffffff1660e01b8152600401611bcb9392919061284c565b602060405180830381600087803b158015611be557600080fd5b505af1158015611bf9573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611c1d9190612551565b506000838152600b6020818152604080842054815180840189905280830186905230606082015260808082018390528351808303909101815260a090910190925281519183019190912093879052919052611c79906001612967565b6000858152600b602052604090205561197b8482604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b8160105414611d4e5760405162461bcd60e51b815260206004820152600f60248201526e1253959053125117d49154555154d5608a1b60448201526064016107d1565b600854611d5b9082612a4b565b611d66906001612967565b6011555050565b610fe3828260405180602001604052806000815250611f6f565b611d92848484611983565b611d9e84848484611fa2565b61136c5760405162461bcd60e51b81526004016107d19061288f565b606081611dde5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611e085780611df281612a30565b9150611e019050600a8361297f565b9150611de2565b6000816001600160401b03811115611e2257611e22612ab7565b6040519080825280601f01601f191660200182016040528015611e4c576020820181803683370190505b5090505b841561197b57611e616001836129b2565b9150611e6e600a86612a4b565b611e79906030612967565b60f81b818381518110611e8e57611e8e612aa1565b60200101906001600160f81b031916908160001a905350611eb0600a8661297f565b9450611e50565b6001600160a01b038316611f1257611f0d81600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b611f35565b816001600160a01b0316836001600160a01b031614611f3557611f3583826120ac565b6001600160a01b038216611f4c5761090281612149565b826001600160a01b0316826001600160a01b0316146109025761090282826121f8565b611f79838361223c565b611f866000848484611fa2565b6109025760405162461bcd60e51b81526004016107d19061288f565b60006001600160a01b0384163b156120a457604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290611fe69033908990889088906004016127f6565b602060405180830381600087803b15801561200057600080fd5b505af1925050508015612030575060408051601f3d908101601f1916820190925261202d918101906125ad565b60015b61208a573d80801561205e576040519150601f19603f3d011682016040523d82523d6000602084013e612063565b606091505b5080516120825760405162461bcd60e51b81526004016107d19061288f565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061197b565b50600161197b565b600060016120b984610e90565b6120c391906129b2565b600083815260076020526040902054909150808214612116576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061215b906001906129b2565b6000838152600960205260408120546008805493945090928490811061218357612183612aa1565b9060005260206000200154905080600883815481106121a4576121a4612aa1565b60009182526020808320909101929092558281526009909152604080822084905585825281205560088054806121dc576121dc612a8b565b6001900381819060005260206000200160009055905550505050565b600061220383610e90565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160a01b0382166122925760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016107d1565b61229b8161182e565b156122e75760405162461bcd60e51b815260206004820152601c60248201527b115490cdcc8c4e881d1bdad95b88185b1c9958591e481b5a5b9d195960221b60448201526064016107d1565b6122f360008383611eb7565b6001600160a01b038216600090815260036020526040812080546001929061231c908490612967565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b60006020828403121561238c57600080fd5b813561239781612acd565b9392505050565b600080604083850312156123b157600080fd5b82356123bc81612acd565b915060208301356123cc81612acd565b809150509250929050565b6000806000606084860312156123ec57600080fd5b83356123f781612acd565b9250602084013561240781612acd565b929592945050506040919091013590565b6000806000806080858703121561242e57600080fd5b843561243981612acd565b9350602085013561244981612acd565b92506040850135915060608501356001600160401b038082111561246c57600080fd5b818701915087601f83011261248057600080fd5b81358181111561249257612492612ab7565b604051601f8201601f19908116603f011681019083821181831017156124ba576124ba612ab7565b816040528281528a60208487010111156124d357600080fd5b82602086016020830137600060208483010152809550505050505092959194509250565b6000806040838503121561250a57600080fd5b823561251581612acd565b915060208301356123cc81612ae2565b6000806040838503121561253857600080fd5b823561254381612acd565b946020939093013593505050565b60006020828403121561256357600080fd5b815161239781612ae2565b6000806040838503121561258157600080fd5b50508035926020909101359150565b6000602082840312156125a257600080fd5b813561239781612af0565b6000602082840312156125bf57600080fd5b815161239781612af0565b6000602082840312156125dc57600080fd5b5035919050565b6000602082840312156125f557600080fd5b5051919050565b600081518084526126148160208601602086016129c9565b601f01601f19169290920160200192915050565b6000855161263a818460208a016129c9565b85519083019061264e818360208a016129c9565b85519101906126618183602089016129c9565b614e6f60f01b9101908152835161267f8160028401602088016129c9565b016002019695505050505050565b6000855161269f818460208a016129c9565b8551908301906126b3818360208a016129c9565b85519101906126c68183602089016129c9565b6259657360e81b910190815283516126e58160038401602088016129c9565b016003019695505050505050565b60008551612705818460208a016129c9565b855190830190612719818360208a016129c9565b855191019061272c8183602089016129c9565b623f3f3f60e81b910190815283516126e58160038401602088016129c9565b7a19185d184e985c1c1b1a58d85d1a5bdb8bda9cdbdb8edd5d198e0b602a1b8152683d913730b6b2911d1160b91b601b82015282516000906127948160248501602088016129c9565b61202360f01b60249184019182015283516127b68160268401602088016129c9565b72222c22696d616765223a2022697066733a2f2f60681b60269290910191820152603901949350505050565b6001600160a01b0391909116815260200190565b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612829908301846125fc565b9695505050505050565b6001600160a01b03929092168252602082015260400190565b60018060a01b038416815282602082015260606040820152600061287360608301846125fc565b95945050505050565b60208152600061239760208301846125fc565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6000821982111561297a5761297a612a5f565b500190565b60008261298e5761298e612a75565b500490565b60008160001904831182151516156129ad576129ad612a5f565b500290565b6000828210156129c4576129c4612a5f565b500390565b60005b838110156129e45781810151838201526020016129cc565b8381111561136c5750506000910152565b600181811c90821680612a0957607f821691505b60208210811415612a2a57634e487b7160e01b600052602260045260246000fd5b50919050565b6000600019821415612a4457612a44612a5f565b5060010190565b600082612a5a57612a5a612a75565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b6001600160a01b03811681146114d457600080fd5b80151581146114d457600080fd5b6001600160e01b0319811681146114d457600080fdfe516d627a66396772517134724e315a6d5a7672726a795767337743384878334271557631366b7057735070564c4d516d5a4544675a38756a797536676676553167487354665a4e324d6e4b556535376a3571585132655042574b6a41516d587961737264707476397a7a475531694b36754e5374683452705241786e347238676139474b345236386e59a264697066735822122052abc131d7a0111009ce5a6a0a62fd035512f0c14fc9a1d143e49de2e80b235864736f6c63430008070033

Deployed Bytecode Sourcemap

747:5816:15:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6136:10;;;;6131:81;;6191:9;6177:11;;:23;;;;:::i;:::-;6163:11;:37;6131:81;6227:31;6236:10;6248:9;6227:31;;;;;;;:::i;:::-;;;;;;;;747:5816;;;;;2286:24;;;;;;;;;;;;;;;;;;;11747:25:16;;;11735:2;11720:18;2286:24:15;;;;;;;;933:224:4;;;;;;;;;;-1:-1:-1;933:224:4;;;;;:::i;:::-;;:::i;:::-;;;11574:14:16;;11567:22;11549:41;;11537:2;11522:18;933:224:4;11409:187:16;2087:84:15;;;;;;;;;;;;2129:42;2087:84;;;;;;;;;:::i;2412:100:3:-;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;3971:221::-;;;;;;;;;;-1:-1:-1;3971:221:3;;;;;:::i;:::-;;:::i;3494:411::-;;;;;;;;;;-1:-1:-1;3494:411:3;;;;;:::i;:::-;;:::i;:::-;;1663:26:15;;;;;;;;;;-1:-1:-1;1663:26:15;;;;;;;;;;;1731;;;;;;;;;;;;;;;;1573:113:4;;;;;;;;;;-1:-1:-1;1661:10:4;:17;1573:113;;4861:339:3;;;;;;;;;;-1:-1:-1;4861:339:3;;;;;:::i;:::-;;:::i;1241:256:4:-;;;;;;;;;;-1:-1:-1;1241:256:4;;;;;:::i;:::-;;:::i;970:41:15:-;;;;;;;;;;;;1007:4;970:41;;4036:159;;;;;;;;;;-1:-1:-1;4036:159:15;;;;;:::i;:::-;;:::i;2317:27::-;;;;;;;;;;;;;;;;5271:185:3;;;;;;;;;;-1:-1:-1;5271:185:3;;;;;:::i;:::-;;:::i;3513:279:15:-;;;;;;;;;;;;;:::i;1763:233:4:-;;;;;;;;;;-1:-1:-1;1763:233:4;;;;;:::i;:::-;;:::i;3923:101:15:-;;;;;;;;;;-1:-1:-1;3989:9:15;;4001:15;-1:-1:-1;3923:101:15;;2106:239:3;;;;;;;;;;-1:-1:-1;2106:239:3;;;;;:::i;:::-;;:::i;2925:323:15:-;;;;;;;;;;;;;:::i;1836:208:3:-;;;;;;;;;;-1:-1:-1;1836:208:3;;;;;:::i;:::-;;:::i;1648:94:11:-;;;;;;;;;;;;;:::i;1764:24:15:-;;;;;;;;;;;;;;;;1634:22;;;;;;;;;;-1:-1:-1;1634:22:15;;;;;;;;1018:33;;;;;;;;;;;;1050:1;1018:33;;997:87:11;;;;;;;;;;;;;:::i;9830:233:13:-;;;;;;;;;;-1:-1:-1;9830:233:13;;;;;:::i;:::-;;:::i;2581:104:3:-;;;;;;;;;;;;;:::i;4307:594:15:-;;;;;;:::i;:::-;;:::i;4264:295:3:-;;;;;;;;;;-1:-1:-1;4264:295:3;;;;;:::i;:::-;;:::i;3804:107:15:-;;;;;;;;;;;;;:::i;5527:328:3:-;;;;;;;;;;-1:-1:-1;5527:328:3;;;;;:::i;:::-;;:::i;6278:161:15:-;;;;;;;;;;-1:-1:-1;6278:161:15;;;;;:::i;:::-;;:::i;5012:953::-;;;;;;;;;;-1:-1:-1;5012:953:15;;;;;:::i;:::-;;:::i;6447:113::-;;;;;;;;;;;;;:::i;4630:164:3:-;;;;;;;;;;-1:-1:-1;4630:164:3;;;;;:::i;:::-;;:::i;1696:28:15:-;;;;;;;;;;-1:-1:-1;1696:28:15;;;;;;;-1:-1:-1;;;;;1696:28:15;;;2189:79;;;;;;;;;;;;2226:42;2189:79;;1897:192:11;;;;;;;;;;-1:-1:-1;1897:192:11;;;;;:::i;:::-;;:::i;933:224:4:-;1035:4;-1:-1:-1;;;;;;1059:50:4;;-1:-1:-1;;;1059:50:4;;:90;;;1113:36;1137:11;1113:23;:36::i;:::-;1052:97;933:224;-1:-1:-1;;933:224:4:o;2412:100:3:-;2466:13;2499:5;2492:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2412:100;:::o;3971:221::-;4047:7;4075:16;4083:7;4075;:16::i;:::-;4067:73;;;;-1:-1:-1;;;4067:73:3;;20330:2:16;4067:73:3;;;20312:21:16;20369:2;20349:18;;;20342:30;20408:34;20388:18;;;20381:62;-1:-1:-1;;;20459:18:16;;;20452:42;20511:19;;4067:73:3;;;;;;;;;-1:-1:-1;4160:24:3;;;;:15;:24;;;;;;-1:-1:-1;;;;;4160:24:3;;3971:221::o;3494:411::-;3575:13;3591:23;3606:7;3591:14;:23::i;:::-;3575:39;;3639:5;-1:-1:-1;;;;;3633:11:3;:2;-1:-1:-1;;;;;3633:11:3;;;3625:57;;;;-1:-1:-1;;;3625:57:3;;22571:2:16;3625:57:3;;;22553:21:16;22610:2;22590:18;;;22583:30;22649:34;22629:18;;;22622:62;-1:-1:-1;;;22700:18:16;;;22693:31;22741:19;;3625:57:3;22369:397:16;3625:57:3;682:10:1;-1:-1:-1;;;;;3717:21:3;;;;:62;;-1:-1:-1;3742:37:3;3759:5;682:10:1;4630:164:3;:::i;3742:37::-;3695:168;;;;-1:-1:-1;;;3695:168:3;;17359:2:16;3695:168:3;;;17341:21:16;17398:2;17378:18;;;17371:30;17437:34;17417:18;;;17410:62;-1:-1:-1;;;17488:18:16;;;17481:54;17552:19;;3695:168:3;17157:420:16;3695:168:3;3876:21;3885:2;3889:7;3876:8;:21::i;:::-;3564:341;3494:411;;:::o;4861:339::-;5056:41;682:10:1;5089:7:3;5056:18;:41::i;:::-;5048:103;;;;-1:-1:-1;;;5048:103:3;;;;;;;:::i;:::-;5164:28;5174:4;5180:2;5184:7;5164:9;:28::i;1241:256:4:-;1338:7;1374:23;1391:5;1374:16;:23::i;:::-;1366:5;:31;1358:87;;;;-1:-1:-1;;;1358:87:4;;12884:2:16;1358:87:4;;;12866:21:16;12923:2;12903:18;;;12896:30;12962:34;12942:18;;;12935:62;-1:-1:-1;;;13013:18:16;;;13006:41;13064:19;;1358:87:4;12682:407:16;1358:87:4;-1:-1:-1;;;;;;1463:19:4;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;1241:256::o;4036:159:15:-;682:10:1;1217:7:11;:5;:7::i;:::-;-1:-1:-1;;;;;1217:23:11;;1209:68;;;;-1:-1:-1;;;1209:68:11;;;;;;;:::i;:::-;4129:9:15::1;;4116:10;:22;4108:46;;;::::0;-1:-1:-1;;;4108:46:15;;25194:2:16;4108:46:15::1;::::0;::::1;25176:21:16::0;25233:2;25213:18;;;25206:30;-1:-1:-1;;;25252:18:16;;;25245:41;25303:18;;4108:46:15::1;24992:335:16::0;4108:46:15::1;4165:9;:22:::0;4036:159::o;5271:185:3:-;5409:39;5426:4;5432:2;5436:7;5409:39;;;;;;;;;;;;:16;:39::i;3513:279:15:-;682:10:1;1217:7:11;:5;:7::i;:::-;-1:-1:-1;;;;;1217:23:11;;1209:68;;;;-1:-1:-1;;;1209:68:11;;;;;;;:::i;:::-;3579:21:15::1;3587:12;;3579:7;:21::i;:::-;3563:13;:37:::0;;-1:-1:-1;;;;;;3563:37:15::1;::::0;-1:-1:-1;;;;;3563:37:15;;::::1;::::0;::::1;::::0;;;::::1;::::0;;;;3619:13;::::1;;3611:49;;;::::0;-1:-1:-1;;;3611:49:15;;24857:2:16;3611:49:15::1;::::0;::::1;24839:21:16::0;24896:1;24876:18;;;24869:29;-1:-1:-1;;;24914:18:16;;;24907:39;24963:18;;3611:49:15::1;24655:332:16::0;3611:49:15::1;3680:10;::::0;::::1;;3679:11;3671:32;;;::::0;-1:-1:-1;;;3671:32:15;;15167:2:16;3671:32:15::1;::::0;::::1;15149:21:16::0;15206:1;15186:18;;;15179:29;-1:-1:-1;;;15224:18:16;;;15217:38;15272:18;;3671:32:15::1;14965:331:16::0;3671:32:15::1;3714:10;:17:::0;;-1:-1:-1;;3714:17:15::1;3727:4;3714:17;::::0;;;;-1:-1:-1;;;;;3742:13:15;;;::::1;;3768:11;:9;:11::i;:::-;3742:42;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3564:341:3::0;3494:411;;:::o;1763:233:4:-;1838:7;1874:30;1661:10;:17;;1573:113;1874:30;1866:5;:38;1858:95;;;;-1:-1:-1;;;1858:95:4;;23737:2:16;1858:95:4;;;23719:21:16;23776:2;23756:18;;;23749:30;23815:34;23795:18;;;23788:62;-1:-1:-1;;;23866:18:16;;;23859:42;23918:19;;1858:95:4;23535:408:16;1858:95:4;1971:10;1982:5;1971:17;;;;;;;;:::i;:::-;;;;;;;;;1964:24;;1763:233;;;:::o;2106:239:3:-;2178:7;2214:16;;;:7;:16;;;;;;-1:-1:-1;;;;;2214:16:3;2249:19;2241:73;;;;-1:-1:-1;;;2241:73:3;;18195:2:16;2241:73:3;;;18177:21:16;18234:2;18214:18;;;18207:30;18273:34;18253:18;;;18246:62;-1:-1:-1;;;18324:18:16;;;18317:39;18373:19;;2241:73:3;17993:405:16;2925:323:15;682:10:1;1217:7:11;:5;:7::i;:::-;-1:-1:-1;;;;;1217:23:11;;1209:68;;;;-1:-1:-1;;;1209:68:11;;;;;;;:::i;:::-;3004:1:15::1;2988:13;1661:10:4::0;:17;;1573:113;2988:13:15::1;:17;2980:40;;;::::0;-1:-1:-1;;;2980:40:15;;18605:2:16;2980:40:15::1;::::0;::::1;18587:21:16::0;18644:2;18624:18;;;18617:30;-1:-1:-1;;;18663:18:16;;;18656:40;18713:18;;2980:40:15::1;18403:334:16::0;2980:40:15::1;3040:14;::::0;::::1;::::0;::::1;;;3039:15;3031:45;;;::::0;-1:-1:-1;;;3031:45:15;;23391:2:16;3031:45:15::1;::::0;::::1;23373:21:16::0;23430:2;23410:18;;;23403:30;-1:-1:-1;;;23449:18:16;;;23442:47;23506:18;;3031:45:15::1;23189:341:16::0;3031:45:15::1;3095:29;::::0;-1:-1:-1;;;3095:29:15;;2057:12:::1;::::0;-1:-1:-1;;;;;3095:4:15::1;:14;::::0;::::1;::::0;:29:::1;::::0;3118:4:::1;::::0;3095:29:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:40;;3087:62;;;::::0;-1:-1:-1;;;3087:62:15;;21514:2:16;3087:62:15::1;::::0;::::1;21496:21:16::0;21553:1;21533:18;;;21526:29;-1:-1:-1;;;21571:18:16;;;21564:39;21620:18;;3087:62:15::1;21312:332:16::0;3087:62:15::1;3172:36;1937:66;2057:12;3172:17;:36::i;:::-;3160:9;:48:::0;3219:14:::1;:21:::0;;-1:-1:-1;;3219:21:15::1;;;::::0;;2925:323::o;1836:208:3:-;1908:7;-1:-1:-1;;;;;1936:19:3;;1928:74;;;;-1:-1:-1;;;1928:74:3;;17784:2:16;1928:74:3;;;17766:21:16;17823:2;17803:18;;;17796:30;17862:34;17842:18;;;17835:62;-1:-1:-1;;;17913:18:16;;;17906:40;17963:19;;1928:74:3;17582:406:16;1928:74:3;-1:-1:-1;;;;;;2020:16:3;;;;;:9;:16;;;;;;;1836:208::o;1648:94:11:-;682:10:1;1217:7:11;:5;:7::i;:::-;-1:-1:-1;;;;;1217:23:11;;1209:68;;;;-1:-1:-1;;;1209:68:11;;;;;;;:::i;:::-;1713:21:::1;1731:1;1713:9;:21::i;:::-;1648:94::o:0;997:87::-;1070:6;;-1:-1:-1;;;;;1070:6:11;;997:87::o;9830:233:13:-;9946:10;-1:-1:-1;;;;;9960:14:13;9946:28;;9938:72;;;;-1:-1:-1;;;9938:72:13;;21851:2:16;9938:72:13;;;21833:21:16;21890:2;21870:18;;;21863:30;21929:33;21909:18;;;21902:61;21980:18;;9938:72:13;21649:355:16;9938:72:13;10017:40;10035:9;10046:10;10017:17;:40::i;:::-;9830:233;;:::o;2581:104:3:-;2637:13;2670:7;2663:14;;;;;:::i;4307:594:15:-;455:1;603:7;;:19;;595:63;;;;-1:-1:-1;;;595:63:15;;24497:2:16;595:63:15;;;24479:21:16;24536:2;24516:18;;;24509:30;24575:33;24555:18;;;24548:61;24626:18;;595:63:15;24295:355:16;595:63:15;455:1;669:7;:18;3989:9;;4001:15;-1:-1:-1;4380:39:15::1;;;::::0;-1:-1:-1;;;4380:39:15;;14466:2:16;4380:39:15::1;::::0;::::1;14448:21:16::0;14505:2;14485:18;;;14478:30;-1:-1:-1;;;14524:18:16;;;14517:45;14579:18;;4380:39:15::1;14264:339:16::0;4380:39:15::1;1007:4;4438:13;1661:10:4::0;:17;;1573:113;4438:13:15::1;:26;4430:47;;;::::0;-1:-1:-1;;;4430:47:15;;19633:2:16;4430:47:15::1;::::0;::::1;19615:21:16::0;19672:1;19652:18;;;19645:29;-1:-1:-1;;;19690:18:16;;;19683:38;19738:18;;4430:47:15::1;19431:331:16::0;4430:47:15::1;4497:14;::::0;::::1;::::0;::::1;;;4496:15;4488:39;;;::::0;-1:-1:-1;;;4488:39:15;;17019:2:16;4488:39:15::1;::::0;::::1;17001:21:16::0;17058:2;17038:18;;;17031:30;-1:-1:-1;;;17077:18:16;;;17070:41;17128:18;;4488:39:15::1;16817:335:16::0;4488:39:15::1;4557:1;4546:8;:12;4538:38;;;::::0;-1:-1:-1;;;4538:38:15;;18944:2:16;4538:38:15::1;::::0;::::1;18926:21:16::0;18983:2;18963:18;;;18956:30;-1:-1:-1;;;19002:18:16;;;18995:43;19055:18;;4538:38:15::1;18742:337:16::0;4538:38:15::1;1007:4;4611:8;4595:13;1661:10:4::0;:17;;1573:113;4595:13:15::1;:24;;;;:::i;:::-;:38;;4587:69;;;::::0;-1:-1:-1;;;4587:69:15;;19286:2:16;4587:69:15::1;::::0;::::1;19268:21:16::0;19325:2;19305:18;;;19298:30;-1:-1:-1;;;19344:18:16;;;19337:48;19402:18;;4587:69:15::1;19084:342:16::0;4587:69:15::1;4688:16;4696:8:::0;1050:1:::1;4688:16;:::i;:::-;4675:9;:29;;4667:60;;;::::0;-1:-1:-1;;;4667:60:15;;24150:2:16;4667:60:15::1;::::0;::::1;24132:21:16::0;24189:2;24169:18;;;24162:30;-1:-1:-1;;;24208:18:16;;;24201:48;24266:18;;4667:60:15::1;23948:342:16::0;4667:60:15::1;4745:9;4740:106;4764:8;4760:1;:12;4740:106;;;4794:40;4804:10;4816:13;1661:10:4::0;:17;;1573:113;4816:13:15::1;:17;::::0;4832:1:::1;4816:17;:::i;:::-;4794:9;:40::i;:::-;4774:3:::0;::::1;::::0;::::1;:::i;:::-;;;;4740:106;;;;4884:9;4870:11;;:23;;;;:::i;:::-;4856:11;:37:::0;-1:-1:-1;411:1:15;710:7;:22;4307:594::o;4264:295:3:-;-1:-1:-1;;;;;4367:24:3;;682:10:1;4367:24:3;;4359:62;;;;-1:-1:-1;;;4359:62:3;;15908:2:16;4359:62:3;;;15890:21:16;15947:2;15927:18;;;15920:30;-1:-1:-1;;;15966:18:16;;;15959:55;16031:18;;4359:62:3;15706:349:16;4359:62:3;682:10:1;4434:32:3;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;4434:42:3;;;;;;;;;;;;:53;;-1:-1:-1;;4434:53:3;;;;;;;;;;4503:48;;11549:41:16;;;4434:42:3;;682:10:1;4503:48:3;;11522:18:16;4503:48:3;;;;;;;4264:295;;:::o;3804:107:15:-;3846:7;3900:3;1111;3873:11;;:24;;;;:::i;:::-;:30;;;;:::i;:::-;3866:37;;3804:107;:::o;5527:328:3:-;5702:41;682:10:1;5735:7:3;5702:18;:41::i;:::-;5694:103;;;;-1:-1:-1;;;5694:103:3;;;;;;;:::i;:::-;5808:39;5822:4;5828:2;5832:7;5841:5;5808:13;:39::i;:::-;5527:328;;;;:::o;6278:161:15:-;682:10:1;1217:7:11;:5;:7::i;:::-;-1:-1:-1;;;;;1217:23:11;;1209:68;;;;-1:-1:-1;;;1209:68:11;;;;;;;:::i;:::-;6380:30:15::1;::::0;-1:-1:-1;;;6380:30:15;;-1:-1:-1;;;;;6353:14:15;::::1;::::0;::::1;::::0;6368:10:::1;::::0;6353:14;;6380:15:::1;::::0;:30:::1;::::0;6404:4:::1;::::0;6380:30:::1;;;:::i;:::-;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6353:58;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;6345:86;;;::::0;-1:-1:-1;;;6345:86:15;;14122:2:16;6345:86:15::1;::::0;::::1;14104:21:16::0;14161:2;14141:18;;;14134:30;-1:-1:-1;;;14180:18:16;;;14173:45;14235:18;;6345:86:15::1;13920:339:16::0;6345:86:15::1;6278:161:::0;:::o;5012:953::-;5085:13;5119:16;5127:7;5119;:16::i;:::-;5111:60;;;;-1:-1:-1;;;5111:60:15;;22211:2:16;5111:60:15;;;22193:21:16;22250:2;22230:18;;;22223:30;22289:33;22269:18;;;22262:61;22340:18;;5111:60:15;22009:355:16;5111:60:15;5182:20;5273:10;;;;;;;;;;;;;-1:-1:-1;;;5273:10:15;;;5291:18;:7;:16;:18::i;:::-;5212:121;;;;;;;;;:::i;:::-;;;;;;;;;;;;;5182:152;;5345:24;5379:70;;;;;;8500:66:16;8488:79;;-1:-1:-1;;;8592:2:16;8583:12;;8576:70;8671:2;8662:12;;8286:394;5379:70:15;;;;-1:-1:-1;;5379:70:15;;;;;;5461:30;;;;;;;;;-1:-1:-1;;;5379:70:15;5461:30;;;5506:12;;5379:70;;-1:-1:-1;5506:17:15;5502:432;;5560:7;5544:12;;:23;5540:267;;;5621:6;5629:11;;;;;;;;;;;;;;;;;5642:10;5661:7;5604:65;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;5588:82;;5502:432;;5540:267;5744:6;5752:10;;;;;;;;;;;;;;;;;5764;5782:7;5727:63;;;;;;;;;;;:::i;5502:432::-;5872:6;5880:12;;;;;;;;;;;;;;;;;5894:10;5913:7;5855:66;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;5839:83;;5502:432;-1:-1:-1;5951:6:15;;5012:953;-1:-1:-1;;;5012:953:15:o;6447:113::-;682:10:1;1217:7:11;:5;:7::i;:::-;-1:-1:-1;;;;;1217:23:11;;1209:68;;;;-1:-1:-1;;;1209:68:11;;;;;;;:::i;:::-;6506:7:15::1;:5;:7::i;:::-;-1:-1:-1::0;;;;;6506:12:15::1;6526:21;6506:46;;;9829:205:16::0;4630:164:3;-1:-1:-1;;;;;4751:25:3;;;4727:4;4751:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;4630:164::o;1897:192:11:-;682:10:1;1217:7:11;:5;:7::i;:::-;-1:-1:-1;;;;;1217:23:11;;1209:68;;;;-1:-1:-1;;;1209:68:11;;;;;;;:::i;:::-;-1:-1:-1;;;;;1986:22:11;::::1;1978:73;;;::::0;-1:-1:-1;;;1978:73:11;;13715:2:16;1978:73:11::1;::::0;::::1;13697:21:16::0;13754:2;13734:18;;;13727:30;13793:34;13773:18;;;13766:62;-1:-1:-1;;;13844:18:16;;;13837:36;13890:19;;1978:73:11::1;13513:402:16::0;1978:73:11::1;2062:19;2072:8;2062:9;:19::i;1467:305:3:-:0;1569:4;-1:-1:-1;;;;;;1606:40:3;;-1:-1:-1;;;1606:40:3;;:105;;-1:-1:-1;;;;;;;1663:48:3;;-1:-1:-1;;;1663:48:3;1606:105;:158;;;-1:-1:-1;;;;;;;;;;894:40:2;;;1728:36:3;785:157:2;7365:127:3;7430:4;7454:16;;;:7;:16;;;;;;-1:-1:-1;;;;;7454:16:3;:30;;;7365:127::o;11347:174::-;11422:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;11422:29:3;-1:-1:-1;;;;;11422:29:3;;;;;;;;:24;;11476:23;11422:24;11476:14;:23::i;:::-;-1:-1:-1;;;;;11467:46:3;;;;;;;;;;;11347:174;;:::o;7659:348::-;7752:4;7777:16;7785:7;7777;:16::i;:::-;7769:73;;;;-1:-1:-1;;;7769:73:3;;16262:2:16;7769:73:3;;;16244:21:16;16301:2;16281:18;;;16274:30;16340:34;16320:18;;;16313:62;-1:-1:-1;;;16391:18:16;;;16384:42;16443:19;;7769:73:3;16060:408:16;7769:73:3;7853:13;7869:23;7884:7;7869:14;:23::i;:::-;7853:39;;7922:5;-1:-1:-1;;;;;7911:16:3;:7;-1:-1:-1;;;;;7911:16:3;;:51;;;;7955:7;-1:-1:-1;;;;;7931:31:3;:20;7943:7;7931:11;:20::i;:::-;-1:-1:-1;;;;;7931:31:3;;7911:51;:87;;;;7966:32;7983:5;7990:7;7966:16;:32::i;:::-;7903:96;7659:348;-1:-1:-1;;;;7659:348:3:o;10651:578::-;10810:4;-1:-1:-1;;;;;10783:31:3;:23;10798:7;10783:14;:23::i;:::-;-1:-1:-1;;;;;10783:31:3;;10775:85;;;;-1:-1:-1;;;10775:85:3;;21104:2:16;10775:85:3;;;21086:21:16;21143:2;21123:18;;;21116:30;21182:34;21162:18;;;21155:62;-1:-1:-1;;;21233:18:16;;;21226:39;21282:19;;10775:85:3;20902:405:16;10775:85:3;-1:-1:-1;;;;;10879:16:3;;10871:65;;;;-1:-1:-1;;;10871:65:3;;15503:2:16;10871:65:3;;;15485:21:16;15542:2;15522:18;;;15515:30;15581:34;15561:18;;;15554:62;-1:-1:-1;;;15632:18:16;;;15625:34;15676:19;;10871:65:3;15301:400:16;10871:65:3;10949:39;10970:4;10976:2;10980:7;10949:20;:39::i;:::-;11053:29;11070:1;11074:7;11053:8;:29::i;:::-;-1:-1:-1;;;;;11095:15:3;;;;;;:9;:15;;;;;:20;;11114:1;;11095:15;:20;;11114:1;;11095:20;:::i;:::-;;;;-1:-1:-1;;;;;;;11126:13:3;;;;;;:9;:13;;;;;:18;;11143:1;;11126:13;:18;;11143:1;;11126:18;:::i;:::-;;;;-1:-1:-1;;11155:16:3;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;11155:21:3;-1:-1:-1;;;;;11155:21:3;;;;;;;;;11194:27;;11155:16;;11194:27;;;;;;;10651:578;;;:::o;7894:1077:13:-;8004:17;8039:4;-1:-1:-1;;;;;8039:20:13;;8060:14;8076:4;8093:8;6724:1;8082:43;;;;;;;;11957:25:16;;;12013:2;11998:18;;11991:34;11945:2;11930:18;;11783:248;8082:43:13;;;;;;;;;;;;;8039:87;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;8361:15:13;8445:16;;;:6;:16;;;;;;;;;1036:51:14;;;;;12267:25:16;;;12308:18;;;12301:34;;;8438:4:13;12351:18:16;;;12344:60;12420:18;;;;12413:34;;;1036:51:14;;;;;;;;;;12239:19:16;;;;1036:51:14;;;1026:62;;;;;;;;;8899:16:13;;;;;;;:20;;8918:1;8899:20;:::i;:::-;8880:16;;;;:6;:16;;;;;:39;8933:32;8887:8;8957:7;1653:41:14;;;;;;;5165:19:16;;;;5200:12;;;5193:28;;;;1653:41:14;;;;;;;;;5237:12:16;;;;1653:41:14;;1643:52;;;;;;1486:215;2097:173:11;2172:6;;;-1:-1:-1;;;;;2189:17:11;;;-1:-1:-1;;;;;;2189:17:11;;;;;;;2222:40;;2172:6;;;2189:17;2172:6;;2222:40;;2153:16;;2222:40;2142:128;2097:173;:::o;3256:245:15:-;3373:10;3360:9;;:23;3352:51;;;;-1:-1:-1;;;3352:51:15;;16675:2:16;3352:51:15;;;16657:21:16;16714:2;16694:18;;;16687:30;-1:-1:-1;;;16733:18:16;;;16726:45;16788:18;;3352:51:15;16473:339:16;3352:51:15;1661:10:4;:17;3430:26:15;;:10;:26;:::i;:::-;3429:32;;3460:1;3429:32;:::i;:::-;3414:12;:47;-1:-1:-1;;3256:245:15:o;8349:110:3:-;8425:26;8435:2;8439:7;8425:26;;;;;;;;;;;;:9;:26::i;6737:315::-;6894:28;6904:4;6910:2;6914:7;6894:9;:28::i;:::-;6941:48;6964:4;6970:2;6974:7;6983:5;6941:22;:48::i;:::-;6933:111;;;;-1:-1:-1;;;6933:111:3;;;;;;;:::i;288:723:12:-;344:13;565:10;561:53;;-1:-1:-1;;592:10:12;;;;;;;;;;;;-1:-1:-1;;;592:10:12;;;;;288:723::o;561:53::-;639:5;624:12;680:78;687:9;;680:78;;713:8;;;;:::i;:::-;;-1:-1:-1;736:10:12;;-1:-1:-1;744:2:12;736:10;;:::i;:::-;;;680:78;;;768:19;800:6;-1:-1:-1;;;;;790:17:12;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;790:17:12;;768:39;;818:154;825:10;;818:154;;852:11;862:1;852:11;;:::i;:::-;;-1:-1:-1;921:10:12;929:2;921:5;:10;:::i;:::-;908:24;;:2;:24;:::i;:::-;895:39;;878:6;885;878:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;878:56:12;;;;;;;;-1:-1:-1;949:11:12;958:2;949:11;;:::i;:::-;;;818:154;;2609:589:4;-1:-1:-1;;;;;2815:18:4;;2811:187;;2850:40;2882:7;4025:10;:17;;3998:24;;;;:15;:24;;;;;:44;;;4053:24;;;;;;;;;;;;3921:164;2850:40;2811:187;;;2920:2;-1:-1:-1;;;;;2912:10:4;:4;-1:-1:-1;;;;;2912:10:4;;2908:90;;2939:47;2972:4;2978:7;2939:32;:47::i;:::-;-1:-1:-1;;;;;3012:16:4;;3008:183;;3045:45;3082:7;3045:36;:45::i;3008:183::-;3118:4;-1:-1:-1;;;;;3112:10:4;:2;-1:-1:-1;;;;;3112:10:4;;3108:83;;3139:40;3167:2;3171:7;3139:27;:40::i;8686:321:3:-;8816:18;8822:2;8826:7;8816:5;:18::i;:::-;8867:54;8898:1;8902:2;8906:7;8915:5;8867:22;:54::i;:::-;8845:154;;;;-1:-1:-1;;;8845:154:3;;;;;;;:::i;12086:799::-;12241:4;-1:-1:-1;;;;;12262:13:3;;1066:20:0;1114:8;12258:620:3;;12298:72;;-1:-1:-1;;;12298:72:3;;-1:-1:-1;;;;;12298:36:3;;;;;:72;;682:10:1;;12349:4:3;;12355:7;;12364:5;;12298:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;12298:72:3;;;;;;;;-1:-1:-1;;12298:72:3;;;;;;;;;;;;:::i;:::-;;;12294:529;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;12540:13:3;;12536:272;;12583:60;;-1:-1:-1;;;12583:60:3;;;;;;;:::i;12536:272::-;12758:6;12752:13;12743:6;12739:2;12735:15;12728:38;12294:529;-1:-1:-1;;;;;;12421:51:3;-1:-1:-1;;;12421:51:3;;-1:-1:-1;12414:58:3;;12258:620;-1:-1:-1;12862:4:3;12855:11;;4712:988:4;4978:22;5028:1;5003:22;5020:4;5003:16;:22::i;:::-;:26;;;;:::i;:::-;5040:18;5061:26;;;:17;:26;;;;;;4978:51;;-1:-1:-1;5194:28:4;;;5190:328;;-1:-1:-1;;;;;5261:18:4;;5239:19;5261:18;;;:12;:18;;;;;;;;:34;;;;;;;;;5312:30;;;;;;:44;;;5429:30;;:17;:30;;;;;:43;;;5190:328;-1:-1:-1;5614:26:4;;;;:17;:26;;;;;;;;5607:33;;;-1:-1:-1;;;;;5658:18:4;;;;;:12;:18;;;;;:34;;;;;;;5651:41;4712:988::o;5995:1079::-;6273:10;:17;6248:22;;6273:21;;6293:1;;6273:21;:::i;:::-;6305:18;6326:24;;;:15;:24;;;;;;6699:10;:26;;6248:46;;-1:-1:-1;6326:24:4;;6248:46;;6699:26;;;;;;:::i;:::-;;;;;;;;;6677:48;;6763:11;6738:10;6749;6738:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;6843:28;;;:15;:28;;;;;;;:41;;;7015:24;;;;;7008:31;7050:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;6066:1008;;;5995:1079;:::o;3499:221::-;3584:14;3601:20;3618:2;3601:16;:20::i;:::-;-1:-1:-1;;;;;3632:16:4;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;3677:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;3499:221:4:o;9343:382:3:-;-1:-1:-1;;;;;9423:16:3;;9415:61;;;;-1:-1:-1;;;9415:61:3;;19969:2:16;9415:61:3;;;19951:21:16;;;19988:18;;;19981:30;20047:34;20027:18;;;20020:62;20099:18;;9415:61:3;19767:356:16;9415:61:3;9496:16;9504:7;9496;:16::i;:::-;9495:17;9487:58;;;;-1:-1:-1;;;9487:58:3;;14810:2:16;9487:58:3;;;14792:21:16;14849:2;14829:18;;;14822:30;-1:-1:-1;;;14868:18:16;;;14861:58;14936:18;;9487:58:3;14608:352:16;9487:58:3;9558:45;9587:1;9591:2;9595:7;9558:20;:45::i;:::-;-1:-1:-1;;;;;9616:13:3;;;;;;:9;:13;;;;;:18;;9633:1;;9616:13;:18;;9633:1;;9616:18;:::i;:::-;;;;-1:-1:-1;;9645:16:3;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;9645:21:3;-1:-1:-1;;;;;9645:21:3;;;;;;;;9684:33;;9645:16;;;9684:33;;9645:16;;9684:33;9343:382;;:::o;14:247:16:-;73:6;126:2;114:9;105:7;101:23;97:32;94:52;;;142:1;139;132:12;94:52;181:9;168:23;200:31;225:5;200:31;:::i;:::-;250:5;14:247;-1:-1:-1;;;14:247:16:o;266:388::-;334:6;342;395:2;383:9;374:7;370:23;366:32;363:52;;;411:1;408;401:12;363:52;450:9;437:23;469:31;494:5;469:31;:::i;:::-;519:5;-1:-1:-1;576:2:16;561:18;;548:32;589:33;548:32;589:33;:::i;:::-;641:7;631:17;;;266:388;;;;;:::o;659:456::-;736:6;744;752;805:2;793:9;784:7;780:23;776:32;773:52;;;821:1;818;811:12;773:52;860:9;847:23;879:31;904:5;879:31;:::i;:::-;929:5;-1:-1:-1;986:2:16;971:18;;958:32;999:33;958:32;999:33;:::i;:::-;659:456;;1051:7;;-1:-1:-1;;;1105:2:16;1090:18;;;;1077:32;;659:456::o;1120:1266::-;1215:6;1223;1231;1239;1292:3;1280:9;1271:7;1267:23;1263:33;1260:53;;;1309:1;1306;1299:12;1260:53;1348:9;1335:23;1367:31;1392:5;1367:31;:::i;:::-;1417:5;-1:-1:-1;1474:2:16;1459:18;;1446:32;1487:33;1446:32;1487:33;:::i;:::-;1539:7;-1:-1:-1;1593:2:16;1578:18;;1565:32;;-1:-1:-1;1648:2:16;1633:18;;1620:32;-1:-1:-1;;;;;1701:14:16;;;1698:34;;;1728:1;1725;1718:12;1698:34;1766:6;1755:9;1751:22;1741:32;;1811:7;1804:4;1800:2;1796:13;1792:27;1782:55;;1833:1;1830;1823:12;1782:55;1869:2;1856:16;1891:2;1887;1884:10;1881:36;;;1897:18;;:::i;:::-;1972:2;1966:9;1940:2;2026:13;;-1:-1:-1;;2022:22:16;;;2046:2;2018:31;2014:40;2002:53;;;2070:18;;;2090:22;;;2067:46;2064:72;;;2116:18;;:::i;:::-;2156:10;2152:2;2145:22;2191:2;2183:6;2176:18;2231:7;2226:2;2221;2217;2213:11;2209:20;2206:33;2203:53;;;2252:1;2249;2242:12;2203:53;2308:2;2303;2299;2295:11;2290:2;2282:6;2278:15;2265:46;2353:1;2348:2;2343;2335:6;2331:15;2327:24;2320:35;2374:6;2364:16;;;;;;;1120:1266;;;;;;;:::o;2391:382::-;2456:6;2464;2517:2;2505:9;2496:7;2492:23;2488:32;2485:52;;;2533:1;2530;2523:12;2485:52;2572:9;2559:23;2591:31;2616:5;2591:31;:::i;:::-;2641:5;-1:-1:-1;2698:2:16;2683:18;;2670:32;2711:30;2670:32;2711:30;:::i;2778:315::-;2846:6;2854;2907:2;2895:9;2886:7;2882:23;2878:32;2875:52;;;2923:1;2920;2913:12;2875:52;2962:9;2949:23;2981:31;3006:5;2981:31;:::i;:::-;3031:5;3083:2;3068:18;;;;3055:32;;-1:-1:-1;;;2778:315:16:o;3098:245::-;3165:6;3218:2;3206:9;3197:7;3193:23;3189:32;3186:52;;;3234:1;3231;3224:12;3186:52;3266:9;3260:16;3285:28;3307:5;3285:28;:::i;3348:248::-;3416:6;3424;3477:2;3465:9;3456:7;3452:23;3448:32;3445:52;;;3493:1;3490;3483:12;3445:52;-1:-1:-1;;3516:23:16;;;3586:2;3571:18;;;3558:32;;-1:-1:-1;3348:248:16:o;3601:245::-;3659:6;3712:2;3700:9;3691:7;3687:23;3683:32;3680:52;;;3728:1;3725;3718:12;3680:52;3767:9;3754:23;3786:30;3810:5;3786:30;:::i;3851:249::-;3920:6;3973:2;3961:9;3952:7;3948:23;3944:32;3941:52;;;3989:1;3986;3979:12;3941:52;4021:9;4015:16;4040:30;4064:5;4040:30;:::i;4372:180::-;4431:6;4484:2;4472:9;4463:7;4459:23;4455:32;4452:52;;;4500:1;4497;4490:12;4452:52;-1:-1:-1;4523:23:16;;4372:180;-1:-1:-1;4372:180:16:o;4557:184::-;4627:6;4680:2;4668:9;4659:7;4655:23;4651:32;4648:52;;;4696:1;4693;4686:12;4648:52;-1:-1:-1;4719:16:16;;4557:184;-1:-1:-1;4557:184:16:o;4746:257::-;4787:3;4825:5;4819:12;4852:6;4847:3;4840:19;4868:63;4924:6;4917:4;4912:3;4908:14;4901:4;4894:5;4890:16;4868:63;:::i;:::-;4985:2;4964:15;-1:-1:-1;;4960:29:16;4951:39;;;;4992:4;4947:50;;4746:257;-1:-1:-1;;4746:257:16:o;5260:1003::-;5636:3;5674:6;5668:13;5690:53;5736:6;5731:3;5724:4;5716:6;5712:17;5690:53;:::i;:::-;5806:13;;5765:16;;;;5828:57;5806:13;5765:16;5862:4;5850:17;;5828:57;:::i;:::-;5952:13;;5907:20;;;5974:57;5952:13;5907:20;6008:4;5996:17;;5974:57;:::i;:::-;-1:-1:-1;;;6053:20:16;;6082:19;;;6126:13;;6148:65;6126:13;6200:1;6189:13;;6182:4;6170:17;;6148:65;:::i;:::-;6233:20;6255:1;6229:28;;5260:1003;-1:-1:-1;;;;;;5260:1003:16:o;6268:1004::-;6644:3;6682:6;6676:13;6698:53;6744:6;6739:3;6732:4;6724:6;6720:17;6698:53;:::i;:::-;6814:13;;6773:16;;;;6836:57;6814:13;6773:16;6870:4;6858:17;;6836:57;:::i;:::-;6960:13;;6915:20;;;6982:57;6960:13;6915:20;7016:4;7004:17;;6982:57;:::i;:::-;-1:-1:-1;;;7061:20:16;;7090;;;7135:13;;7157:65;7135:13;7209:1;7198:13;;7191:4;7179:17;;7157:65;:::i;:::-;7242:20;7264:1;7238:28;;6268:1004;-1:-1:-1;;;;;;6268:1004:16:o;7277:::-;7653:3;7691:6;7685:13;7707:53;7753:6;7748:3;7741:4;7733:6;7729:17;7707:53;:::i;:::-;7823:13;;7782:16;;;;7845:57;7823:13;7782:16;7879:4;7867:17;;7845:57;:::i;:::-;7969:13;;7924:20;;;7991:57;7969:13;7924:20;8025:4;8013:17;;7991:57;:::i;:::-;-1:-1:-1;;;8070:20:16;;8099;;;8144:13;;8166:65;8144:13;8218:1;8207:13;;8200:4;8188:17;;8166:65;:::i;8685:1139::-;-1:-1:-1;;;9286:42:16;;-1:-1:-1;;;9353:2:16;9344:12;;9337:52;9412:13;;-1:-1:-1;;9434:62:16;9412:13;9484:2;9475:12;;9468:4;9456:17;;9434:62;:::i;:::-;-1:-1:-1;;;9555:2:16;9515:16;;;9547:11;;;9540:25;9590:13;;9612:63;9590:13;9661:2;9653:11;;9646:4;9634:17;;9612:63;:::i;:::-;-1:-1:-1;;;9735:2:16;9694:17;;;;9727:11;;;9720:71;9815:2;9807:11;;8685:1139;-1:-1:-1;;;;8685:1139:16:o;10039:203::-;-1:-1:-1;;;;;10203:32:16;;;;10185:51;;10173:2;10158:18;;10039:203::o;10247:488::-;-1:-1:-1;;;;;10516:15:16;;;10498:34;;10568:15;;10563:2;10548:18;;10541:43;10615:2;10600:18;;10593:34;;;10663:3;10658:2;10643:18;;10636:31;;;10441:4;;10684:45;;10709:19;;10701:6;10684:45;:::i;:::-;10676:53;10247:488;-1:-1:-1;;;;;;10247:488:16:o;10740:274::-;-1:-1:-1;;;;;10932:32:16;;;;10914:51;;10996:2;10981:18;;10974:34;10902:2;10887:18;;10740:274::o;11019:385::-;11251:1;11247;11242:3;11238:11;11234:19;11226:6;11222:32;11211:9;11204:51;11291:6;11286:2;11275:9;11271:18;11264:34;11334:2;11329;11318:9;11314:18;11307:30;11185:4;11354:44;11394:2;11383:9;11379:18;11371:6;11354:44;:::i;:::-;11346:52;11019:385;-1:-1:-1;;;;;11019:385:16:o;12458:219::-;12607:2;12596:9;12589:21;12570:4;12627:44;12667:2;12656:9;12652:18;12644:6;12627:44;:::i;13094:414::-;13296:2;13278:21;;;13335:2;13315:18;;;13308:30;13374:34;13369:2;13354:18;;13347:62;-1:-1:-1;;;13440:2:16;13425:18;;13418:48;13498:3;13483:19;;13094:414::o;20541:356::-;20743:2;20725:21;;;20762:18;;;20755:30;20821:34;20816:2;20801:18;;20794:62;20888:2;20873:18;;20541:356::o;22771:413::-;22973:2;22955:21;;;23012:2;22992:18;;;22985:30;23051:34;23046:2;23031:18;;23024:62;-1:-1:-1;;;23117:2:16;23102:18;;23095:47;23174:3;23159:19;;22771:413::o;25514:128::-;25554:3;25585:1;25581:6;25578:1;25575:13;25572:39;;;25591:18;;:::i;:::-;-1:-1:-1;25627:9:16;;25514:128::o;25647:120::-;25687:1;25713;25703:35;;25718:18;;:::i;:::-;-1:-1:-1;25752:9:16;;25647:120::o;25772:168::-;25812:7;25878:1;25874;25870:6;25866:14;25863:1;25860:21;25855:1;25848:9;25841:17;25837:45;25834:71;;;25885:18;;:::i;:::-;-1:-1:-1;25925:9:16;;25772:168::o;25945:125::-;25985:4;26013:1;26010;26007:8;26004:34;;;26018:18;;:::i;:::-;-1:-1:-1;26055:9:16;;25945:125::o;26075:258::-;26147:1;26157:113;26171:6;26168:1;26165:13;26157:113;;;26247:11;;;26241:18;26228:11;;;26221:39;26193:2;26186:10;26157:113;;;26288:6;26285:1;26282:13;26279:48;;;-1:-1:-1;;26323:1:16;26305:16;;26298:27;26075:258::o;26338:380::-;26417:1;26413:12;;;;26460;;;26481:61;;26535:4;26527:6;26523:17;26513:27;;26481:61;26588:2;26580:6;26577:14;26557:18;26554:38;26551:161;;;26634:10;26629:3;26625:20;26622:1;26615:31;26669:4;26666:1;26659:15;26697:4;26694:1;26687:15;26551:161;;26338:380;;;:::o;26723:135::-;26762:3;-1:-1:-1;;26783:17:16;;26780:43;;;26803:18;;:::i;:::-;-1:-1:-1;26850:1:16;26839:13;;26723:135::o;26863:112::-;26895:1;26921;26911:35;;26926:18;;:::i;:::-;-1:-1:-1;26960:9:16;;26863:112::o;26980:127::-;27041:10;27036:3;27032:20;27029:1;27022:31;27072:4;27069:1;27062:15;27096:4;27093:1;27086:15;27112:127;27173:10;27168:3;27164:20;27161:1;27154:31;27204:4;27201:1;27194:15;27228:4;27225:1;27218:15;27244:127;27305:10;27300:3;27296:20;27293:1;27286:31;27336:4;27333:1;27326:15;27360:4;27357:1;27350:15;27376:127;27437:10;27432:3;27428:20;27425:1;27418:31;27468:4;27465:1;27458:15;27492:4;27489:1;27482:15;27508:127;27569:10;27564:3;27560:20;27557:1;27550:31;27600:4;27597:1;27590:15;27624:4;27621:1;27614:15;27640:131;-1:-1:-1;;;;;27715:31:16;;27705:42;;27695:70;;27761:1;27758;27751:12;27776:118;27862:5;27855:13;27848:21;27841:5;27838:32;27828:60;;27884:1;27881;27874:12;27899:131;-1:-1:-1;;;;;;27973:32:16;;27963:43;;27953:71;;28020:1;28017;28010:12

Swarm Source

ipfs://52abc131d7a0111009ce5a6a0a62fd035512f0c14fc9a1d143e49de2e80b2358
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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