ETH Price: $3,306.44 (+1.74%)
Gas: 3 Gwei

Token

Console NFT Vaults (Cnsl-NFT-V)
 

Overview

Max Total Supply

500 Cnsl-NFT-V

Holders

390

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
twistd.eth
Balance
1 Cnsl-NFT-V
0x797d72F2D3b05A5a9DBCCec5a30A3ead7173f480
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:
ConsoleNFT_Vault

Compiler Version
v0.8.7+commit.e28d00a7

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, GNU GPLv3 license

Contract Source Code (Solidity)

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

// SPDX-License-Identifier: GPL-3.0

/*
      ::::::::   ::::::::  ::::    :::  ::::::::   ::::::::  :::        ::::::::::          ::::    ::: :::::::::: ::::::::::: 
    :+:    :+: :+:    :+: :+:+:   :+: :+:    :+: :+:    :+: :+:        :+:                 :+:+:   :+: :+:            :+:      
   +:+        +:+    +:+ :+:+:+  +:+ +:+        +:+    +:+ +:+        +:+                 :+:+:+  +:+ +:+            +:+       
  +#+        +#+    +:+ +#+ +:+ +#+ +#++:++#++ +#+    +:+ +#+        +#++:++#            +#+ +:+ +#+ :#::+::#       +#+        
 +#+        +#+    +#+ +#+  +#+#+#        +#+ +#+    +#+ +#+        +#+                 +#+  +#+#+# +#+            +#+         
#+#    #+# #+#    #+# #+#   #+#+# #+#    #+# #+#    #+# #+#        #+#                 #+#   #+#+# #+#            #+#          
########   ########  ###    ####  ########   ########  ########## ##########          ###    #### ###            ###           
*/

pragma solidity ^0.8.0;

/**
 * @dev These functions deal with verification of Merkle Trees proofs.
 *
 * The proofs can be generated using the JavaScript library
 * https://github.com/miguelmota/merkletreejs[merkletreejs].
 * Note: the hashing algorithm should be keccak256 and pair sorting should be enabled.
 *
 * See `test/utils/cryptography/MerkleProof.test.js` for some examples.
 */
library MerkleProof {
    /**
     * @dev Returns true if a `leaf` can be proved to be a part of a Merkle tree
     * defined by `root`. For this, a `proof` must be provided, containing
     * sibling hashes on the branch from the leaf to the root of the tree. Each
     * pair of leaves and each pair of pre-images are assumed to be sorted.
     */
    function verify(
        bytes32[] memory proof,
        bytes32 root,
        bytes32 leaf
    ) internal pure returns (bool) {
        return processProof(proof, leaf) == root;
    }

    /**
     * @dev Returns the rebuilt hash obtained by traversing a Merklee tree up
     * from `leaf` using `proof`. A `proof` is valid if and only if the rebuilt
     * hash matches the root of the tree. When processing the proof, the pairs
     * of leafs & pre-images are assumed to be sorted.
     *
     * _Available since v4.4._
     */
    function processProof(bytes32[] memory proof, bytes32 leaf) internal pure returns (bytes32) {
        bytes32 computedHash = leaf;
        for (uint256 i = 0; i < proof.length; i++) {
            bytes32 proofElement = proof[i];
            if (computedHash <= proofElement) {
                // Hash(current computed hash + current element of the proof)
                computedHash = keccak256(abi.encodePacked(computedHash, proofElement));
            } else {
                // Hash(current element of the proof + current computed hash)
                computedHash = keccak256(abi.encodePacked(proofElement, computedHash));
            }
        }
        return computedHash;
    }
}

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));
  }
}

// File: https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/interfaces/LinkTokenInterface.sol

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: https://github.com/smartcontractkit/chainlink/blob/develop/contracts/src/v0.8/VRFConsumerBase.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 private constant 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 internal immutable LINK;
  address private immutable vrfCoordinator;

  // Nonces for each VRF key from which randomness has been requested.
  //
  // Must stay in sync with VRFCoordinator[_keyHash][this]
  mapping(bytes32 => uint256) /* keyHash */ /* 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);
  }
}

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


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



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


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


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


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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

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

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

        _;

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



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


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


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

    function _verifyCallResult(
        bool success,
        bytes memory returndata,
        string memory errorMessage
    ) private 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);
            }
        }
    }
}




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


/**
 * @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), "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(to).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 {}
}



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


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

abstract contract SourceData {
	function getRarity(uint256 token_id) public view virtual returns(uint8);
	function getNumberOfItems(uint256 token_id) public view virtual returns(uint8);
	function getCreditsMultiplier(uint256 token_id) public view virtual returns(uint256);
	function getCreditsAmount(uint256 token_id) public view virtual returns(uint256);
	function getFirstItemRarity(uint256 token_id) public view virtual returns(uint256);
	function getSecondItemRarity(uint256 token_id) public view virtual returns(uint256);
	function getFirstItemClass(uint256 token_id) public view virtual returns(uint256);
}

contract ConsoleNFT_Vault is ERC721Enumerable, ReentrancyGuard, Ownable, VRFConsumerBase {
	
	address dataContract;

    // Mapping for wallet addresses that have previously minted
    mapping(address => uint256) private _whitelistMinters;

	string internal baseTokenURI;
	string internal baseTokenURI_extension;
	
	uint public constant maxTokens = 500;
    uint public total = 0;
	uint mintCost = 0.05 ether;
	
	bool whitelistActive;
	bool sysAdminMinted;
	bool error404Minted;
	bool code200Minted;
	bool giveawaysMinted;
	
	address error404Address;
	address code200Address;
	address giveawaysAddress;
	
	bytes32 _rootHash;
	
	string[] private rarity = [
        "Legendary",
        "Epic",
        "Rare",
        "Uncommon",
        "Common"
    ];
	
	string[] private numberOfItemsInside = [
        "6",
        "5",
        "4",
        "3",
        "2"
    ];
	
	string[] private creditsMultiplier = [
        "Ultra",
        "Very high",
        "High",
        "Medium",
        "Low"
    ];
	
	string[] private creditsAmount = [
        "Ultra",
        "Very high",
        "High",
        "Medium",
        "Low"
    ];
	
	string[] private firstItemRarity = [
        "Legendary",
        "Epic",
        "Rare",
        "Uncommon",
        "Common"
    ];
	
	string[] private secondItemRarity = [
        "Legendary",
        "Epic",
        "Rare",
        "Uncommon",
        "Common"
    ];
	
	string[] private firstItemClass = [
        "Computer",
        "Weapon",
        "Keylogger",
        "Rainbow tables",
        "Packet sniffer",
        "Smartphone",
        "De-auth device",
        "NFC device",
        "RFID blocker",
        "Drone",
        "Screen crab",
        "Programmable chip",
        "Lockpick",
        "Land",
        "Armor",
        "Clothing",
        "CD device",
        "USB device",
        "Floppy disc",
        "- None -"
    ];

	
	function getRarity(uint256 tokenId) public view returns (string memory) {
        require(_exists(tokenId), "Nonexistent token");
		
        string memory output;
		
		SourceData source_data = SourceData(dataContract);
		
        output = rarity[source_data.getRarity(tokenId)];
		
        return output;
    }
	
	function getNumberOfItemsInside(uint256 tokenId) public view returns (string memory) {
        require(_exists(tokenId), "Nonexistent token");
		
        string memory output;
		
		SourceData source_data = SourceData(dataContract);
		
        output = numberOfItemsInside[source_data.getNumberOfItems(tokenId)];
		
        return output;
    }
	
	function getCreditsMultiplier(uint256 tokenId) public view returns (string memory) {
        require(_exists(tokenId), "Nonexistent token");
		
        string memory output;
		
		SourceData source_data = SourceData(dataContract);
		
        output = creditsMultiplier[source_data.getCreditsMultiplier(tokenId)];
		
        return output;
    }
	
	function getCreditsAmount(uint256 tokenId) public view returns (string memory) {
        require(_exists(tokenId), "Nonexistent token");
		
        string memory output;
		
		SourceData source_data = SourceData(dataContract);
		
        output = creditsAmount[source_data.getCreditsAmount(tokenId)];
		
        return output;
    }
	
	function getFirstItemRarity(uint256 tokenId) public view returns (string memory) {
        require(_exists(tokenId), "Nonexistent token");
		
        string memory output;
		
		SourceData source_data = SourceData(dataContract);
		
        output = firstItemRarity[source_data.getFirstItemRarity(tokenId)];
		
        return output;
    }
	
	function getSecondItemRarity(uint256 tokenId) public view returns (string memory) {
        require(_exists(tokenId), "Nonexistent token");
		
        string memory output;
		
		SourceData source_data = SourceData(dataContract);
		
        output = secondItemRarity[source_data.getSecondItemRarity(tokenId)];
		
        return output;
    }
	
	function getFirstItemClass(uint256 tokenId) public view returns (string memory) {
        require(_exists(tokenId), "Nonexistent token");
		
        string memory output;
		
		SourceData source_data = SourceData(dataContract);
		
        output = firstItemClass[source_data.getFirstItemClass(tokenId)];
		
        return output;
    }
		
	// Setters
	function setSourceData(address _dataContract) external onlyOwner {
        dataContract = _dataContract;
    }
	
	function setBaseTokenURI(string memory _uri) external onlyOwner {
        baseTokenURI = _uri;
    }
	
	function setBaseTokenURI_extension(string memory _ext) external onlyOwner {
        baseTokenURI_extension = _ext;
    }
	
	function tokenURI(uint tokenId_) public view override returns (string memory) {
        require(_exists(tokenId_), "Query for non-existent token!");
        return string(abi.encodePacked(baseTokenURI, Strings.toString(tokenId_), baseTokenURI_extension));
    }
	
	function setError404Address(address _setAddress) external onlyOwner {
        error404Address = _setAddress;
    }
	
	function setCode200Address(address _setAddress) external onlyOwner {
        code200Address = _setAddress;
    }
	
	function setGiveawaysAddress(address _setAddress) external onlyOwner {
        giveawaysAddress = _setAddress;
    }
	
	function setRootHash(bytes32 rootHash) external onlyOwner {
        _rootHash = rootHash;
    }
	
	function setWhitelistState() external onlyOwner
    {
        whitelistActive = !whitelistActive;
    }
	
	// Claim
	function sysAdminClaim() public onlyOwner nonReentrant {
		require(sysAdminMinted == false, "Already minted!");
		
		sysAdminMinted = true;
		uint tokenId = getVRFRandomIndex();
        total++;
        _safeMint(owner(), tokenId);
    }
	
	function error404Claim() public nonReentrant {
		require(msg.sender == error404Address, "Not Error 404");
		require(error404Minted == false, "Already minted!");
		
		error404Minted = true;
		uint tokenId = getVRFRandomIndex();
        total++;
        _safeMint(msg.sender, tokenId);
    }
	
	function code200Claim() public nonReentrant {
		require(msg.sender == code200Address, "Not Code 200");
		require(code200Minted == false, "Already minted!");
		
		code200Minted = true;
		uint tokenId = getVRFRandomIndex();
        total++;
        _safeMint(msg.sender, tokenId);
    }
	
	function giveawaysClaim() public nonReentrant {
		// only 2, we can hardcode
		require(msg.sender == giveawaysAddress, "Not Giveaways wallet");
		require(giveawaysMinted == false, "Already minted!");
		
		giveawaysMinted = true;
		
		uint tokenId = getVRFRandomIndex();
        total++;
		_safeMint(msg.sender, tokenId);
		
		uint tokenId_second = getVRFRandomIndex();
        total++;
        _safeMint(msg.sender, tokenId_second);
    }
	
	function whitelistClaim(bytes32[] memory proof) public nonReentrant payable {
        require(whitelistActive, "The whitelist is not active yet");
        require(total < maxTokens, "All tokens have been already minted");
		require(msg.value >= mintCost, "Incorrect mint cost value");
		
		// Merkle tree validation
		bytes32 leaf = keccak256(abi.encodePacked(msg.sender));
		require(MerkleProof.verify(proof, _rootHash, leaf), "Invalid proof");
		
        require(_whitelistMinters[_msgSender()] < 1, "You've already minted");
		
		uint tokenId = getVRFRandomIndex();
        total++;

        _safeMint(_msgSender(), tokenId);

        //Set the _whitelistMinters value to tokenId for this address as it has minted
        _whitelistMinters[_msgSender()] = tokenId;
    }
	
    constructor() ERC721("Console NFT Vaults", "Cnsl-NFT-V") VRFConsumerBase(
        0xf0d54349aDdcf704F77AE15b96510dEA15cb7952,
        0x514910771AF9Ca656af840dff83E8264EcF986CA
    )
	Ownable() {
		keyHash = 0xAA77729D3466CA35AE8D28B3BBAC7CC36A5031EFDC430821C02BC31A238AF445;
        fee = 2 * (10**18);
		
		_rootHash = 0x944df87eb207e113ec142134130993ec225e847b9341eff16eb0c99ed8eb620a;
		
		error404Address = 0x24Db9e45f6aC29175030A083B985C184A02c2d64;
		code200Address = 0x1C0d3B190B18b4452BD4d0928D7f425eA9A0B3F9;
		giveawaysAddress = 0x7e95c71bDF0E0526eA534Fb5191ceD999190c117;
    }
	

	////////////////////////// VRF /////////////////////////////
	
    bytes32 internal keyHash;
    uint internal fee;
    uint internal randomResult;
    
    // VRF Functions
    function getRandomNumber() public onlyOwner returns (bytes32 requestId) {
        require(LINK.balanceOf(address(this)) >= fee, "Not enough LINK!");
        return requestRandomness(keyHash, fee);
    }
    function fulfillRandomness(bytes32 requestId, uint randomness) internal override {
        randomResult = randomness;
    }
    function getRandomResult() public view onlyOwner returns (uint) {
        return randomResult;
    }

    // >>> Now, the VRF is stored in [uint internal randomResult]
    ////////////////////////// VRF /////////////////////////////

    /////////////////////// Token ID Generator ////////////////////////
    // ** Thanks LarvaLabs for this big brain method. **             //
    // This function was orginally written by 0xInuarashi            //
    // and modified by SysAdmin to exclude Token ID,                 //
    // now including the usage of generated input from VRF.          //
    ///////////////////////////////////////////////////////////////////

    uint[maxTokens] internal indices;
    uint32 internal nonce;

    function getVRFRandomIndex() internal returns (uint) {
        require(randomResult != 0, "VRF Random Result has not been set!");
        uint _tokensRemaining = maxTokens - total; // require that this calculation is possible from all caller functions
        uint _maxIndex = _tokensRemaining == 0 ? 0 : _tokensRemaining - 1; // shorthand if for safety
        uint _rand = uint(keccak256(abi.encodePacked(randomResult, nonce, msg.sender, block.difficulty, block.timestamp))) % _tokensRemaining;
    
        uint _output = 0;

        _output = indices[_rand] != 0 ? indices[_rand] :_rand;
        indices[_rand] = indices[_maxIndex] == 0 ? _maxIndex : indices[_maxIndex];

        uint32 _nonceAdd = uint32(uint256(keccak256(abi.encodePacked(randomResult, nonce, msg.sender, block.difficulty, block.timestamp)))) % 10;
        nonce += _nonceAdd; 

        return _output;
    }

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

        if (value == 0) {
            return "0";
        }
        uint256 temp = value;
        uint256 digits;
        while (temp != 0) {
            digits++;
            temp /= 10;
        }
        bytes memory buffer = new bytes(digits);
        while (value != 0) {
            digits -= 1;
            buffer[digits] = bytes1(uint8(48 + uint256(value % 10)));
            value /= 10;
        }
        return string(buffer);
    }
	
	// Withdraw Ether
    function withdrawEther() public onlyOwner {
        payable(msg.sender).transfer(address(this).balance); 
    }

}

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":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[{"internalType":"address","name":"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":"code200Claim","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"error404Claim","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":"uint256","name":"tokenId","type":"uint256"}],"name":"getCreditsAmount","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getCreditsMultiplier","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getFirstItemClass","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getFirstItemRarity","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getNumberOfItemsInside","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"getRandomNumber","outputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"getRandomResult","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getRarity","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getSecondItemRarity","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"giveawaysClaim","outputs":[],"stateMutability":"nonpayable","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":"maxTokens","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"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":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uri","type":"string"}],"name":"setBaseTokenURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_ext","type":"string"}],"name":"setBaseTokenURI_extension","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_setAddress","type":"address"}],"name":"setCode200Address","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_setAddress","type":"address"}],"name":"setError404Address","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_setAddress","type":"address"}],"name":"setGiveawaysAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32","name":"rootHash","type":"bytes32"}],"name":"setRootHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_dataContract","type":"address"}],"name":"setSourceData","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setWhitelistState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"sysAdminClaim","outputs":[],"stateMutability":"nonpayable","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":"total","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"proof","type":"bytes32[]"}],"name":"whitelistClaim","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"withdrawEther","outputs":[],"stateMutability":"nonpayable","type":"function"}]

600060115566b1a2bc2ec500006012556009610160908152684c6567656e6461727960b81b6101805260c090815260046101a0818152634570696360e01b6101c05260e0526101e0908152635261726560e01b61020052610100526008610220908152672ab731b7b6b6b7b760c11b61024052610120526102a060405260066102609081526521b7b6b6b7b760d11b6102805261014052620000a6906017906005620008f7565b506040805160e081018252600160a08201818152601b60f91b60c0840152825282518084018452818152603560f81b6020828101919091528084019190915283518085018552828152600d60fa1b818301528385015283518085018552828152603360f81b8183015260608401528351808501909452908352601960f91b90830152608081019190915262000140906018906005620008f7565b506040805160e081018252600560a0820181815264556c74726160d81b60c084015282528251808401845260098152680accae4f240d0d2ced60bb1b60208281019190915280840191909152835180850185526004815263090d2ced60e31b81830152838501528351808501855260068152654d656469756d60d01b818301526060840152835180850190945260038452624c6f7760e81b908401526080820192909252620001f39160199190620008f7565b506040805160e081018252600560a0820181815264556c74726160d81b60c084015282528251808401845260098152680accae4f240d0d2ced60bb1b60208281019190915280840191909152835180850185526004815263090d2ced60e31b81830152838501528351808501855260068152654d656469756d60d01b818301526060840152835180850190945260038452624c6f7760e81b908401526080820192909252620002a691601a9190620008f7565b506040805160e081018252600960a08201908152684c6567656e6461727960b81b60c08301528152815180830183526004808252634570696360e01b6020838101919091528084019290925283518085018552908152635261726560e01b81830152828401528251808401845260088152672ab731b7b6b6b7b760c11b8183015260608301528251808401909352600683526521b7b6b6b7b760d11b9083015260808101919091526200035e90601b906005620008f7565b506040805160e081018252600960a08201908152684c6567656e6461727960b81b60c08301528152815180830183526004808252634570696360e01b6020838101919091528084019290925283518085018552908152635261726560e01b81830152828401528251808401845260088152672ab731b7b6b6b7b760c11b8183015260608301528251808401909352600683526521b7b6b6b7b760d11b9083015260808101919091526200041690601c906005620008f7565b50604080516102c081018252600861028082018181526721b7b6b83aba32b960c11b6102a084015282528251808401845260068152652bb2b0b837b760d11b602082810191909152808401919091528351808501855260098082526825b2bcb637b3b3b2b960b91b828401528486019190915284518086018652600e8082526d5261696e626f77207461626c657360901b828501526060860191909152855180870187528181526d2830b1b5b2ba1039b734b33332b960911b81850152608086015285518087018752600a80825269536d61727470686f6e6560b01b8286015260a0870191909152865180880188529182526d44652d617574682064657669636560901b8285015260c086019190915285518087018752818152694e46432064657669636560b01b8185015260e086015285518087018752600c81526b292324a210313637b1b5b2b960a11b818501526101008601528551808701875260058082526444726f6e6560d81b8286015261012087019190915286518088018852600b8082526a29b1b932b2b71031b930b160a91b82870152610140880191909152875180890189526011815270050726f6772616d6d61626c65206368697607c1b8187015261016088015287518089018952868152674c6f636b7069636b60c01b8187015261018088015287518089018952600481526313185b9960e21b818701526101a0880152875180890189529182526420b936b7b960d91b828601526101c08701919091528651808801885285815267436c6f7468696e6760c01b818601526101e0870152865180880188529283526843442064657669636560b81b8385015261020086019290925285518087018752908152695553422064657669636560b01b81840152610220850152845180860186529081526a466c6f707079206469736360a81b818301526102408401528351808501909452908352672d204e6f6e65202d60c01b90830152610260810191909152620006fa90601d9060146200095b565b503480156200070857600080fd5b506040805180820182526012815271436f6e736f6c65204e4654205661756c747360701b60208083019182528351808501909452600a84526921b739b616a7232a16ab60b11b90840152815173f0d54349addcf704f77ae15b96510dea15cb79529373514910771af9ca656af840dff83e8264ecf986ca939290916200079191600091620009ad565b508051620007a7906001906020840190620009ad565b50506001600a5550620007ba33620008a5565b6001600160601b0319606092831b811660a052911b166080527faa77729d3466ca35ae8d28b3bbac7cc36a5031efdc430821c02bc31a238af445601e55671bc16d674ec80000601f557f944df87eb207e113ec142134130993ec225e847b9341eff16eb0c99ed8eb620a601655601380547824db9e45f6ac29175030a083b985c184a02c2d640000000000600160281b600160c81b0319909116179055601480546001600160a01b0319908116731c0d3b190b18b4452bd4d0928d7f425ea9a0b3f91790915560158054909116737e95c71bdf0e0526ea534fb5191ced999190c11717905562000aef565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b82805482825590600052602060002090810192821562000949579160200282015b8281111562000949578251805162000938918491602090910190620009ad565b509160200191906001019062000918565b506200095792915062000a38565b5090565b82805482825590600052602060002090810192821562000949579160200282015b828111156200094957825180516200099c918491602090910190620009ad565b50916020019190600101906200097c565b828054620009bb9062000ab2565b90600052602060002090601f016020900481019282620009df576000855562000a2a565b82601f10620009fa57805160ff191683800117855562000a2a565b8280016001018555821562000a2a579182015b8281111562000a2a57825182559160200191906001019062000a0d565b506200095792915062000a59565b808211156200095757600062000a4f828262000a70565b5060010162000a38565b5b8082111562000957576000815560010162000a5a565b50805462000a7e9062000ab2565b6000825580601f1062000a8f575050565b601f01602090049060005260206000209081019062000aaf919062000a59565b50565b600181811c9082168062000ac757607f821691505b6020821081141562000ae957634e487b7160e01b600052602260045260246000fd5b50919050565b60805160601c60a05160601c6134af62000b29600039600081816115da015261246a015260008181611a06015261243b01526134af6000f3fe6080604052600436106102725760003560e01c806368b01c1f1161014f578063aeceadbf116100c1578063e83157421161007a578063e83157421461070b578063e985e9c514610721578063f2fde38b1461076a578063f58152541461078a578063fc59d962146107aa578063fe05452d146107bf57600080fd5b8063aeceadbf1461066c578063b102b6bc14610681578063b88d4fde14610696578063c87b56dd146106b6578063cd03a76a146106d6578063dbdff2c1146106f657600080fd5b80637390c786116101135780637390c786146105c45780638da5cb5b146105d957806390bbe186146105f757806394985ddd1461061757806395d89b4114610637578063a22cb4651461064c57600080fd5b806368b01c1f14610545578063708aa3dc1461056557806370a082311461057a578063715018a61461059a5780637362377b146105af57600080fd5b806330176e13116101e85780634f6ccce7116101ac5780634f6ccce71461049d57806354703d0c146104bd5780635d41c19c146104d05780636352211e146104e55780636550df401461050557806366b3fbd21461052557600080fd5b806330176e13146103fd57806342842e0e1461041d578063434b3c121461043d578063451032a11461045d578063487586971461047d57600080fd5b806318160ddd1161023a57806318160ddd146103485780631c62d87a1461036757806323b872dd146103875780632d7eae66146103a75780632ddbd13a146103c75780632f745c59146103dd57600080fd5b806301ffc9a71461027757806306fdde03146102ac578063081812fc146102ce578063095ea7b3146103065780631089e56914610328575b600080fd5b34801561028357600080fd5b50610297610292366004612eb5565b6107df565b60405190151581526020015b60405180910390f35b3480156102b857600080fd5b506102c161080a565b6040516102a3919061311c565b3480156102da57600080fd5b506102ee6102e9366004612e7a565b61089c565b6040516001600160a01b0390911681526020016102a3565b34801561031257600080fd5b50610326610321366004612d86565b610929565b005b34801561033457600080fd5b506102c1610343366004612e7a565b610a3f565b34801561035457600080fd5b506008545b6040519081526020016102a3565b34801561037357600080fd5b506102c1610382366004612e7a565b610b98565b34801561039357600080fd5b506103266103a2366004612c97565b610c52565b3480156103b357600080fd5b506103266103c2366004612e7a565b610c83565b3480156103d357600080fd5b5061035960115481565b3480156103e957600080fd5b506103596103f8366004612d86565b610cb2565b34801561040957600080fd5b50610326610418366004612eef565b610d48565b34801561042957600080fd5b50610326610438366004612c97565b610d89565b34801561044957600080fd5b50610326610458366004612c42565b610da4565b34801561046957600080fd5b506102c1610478366004612e7a565b610df0565b34801561048957600080fd5b506102c1610498366004612e7a565b610e4e565b3480156104a957600080fd5b506103596104b8366004612e7a565b610eac565b6103266104cb366004612db0565b610f3f565b3480156104dc57600080fd5b5061032661118d565b3480156104f157600080fd5b506102ee610500366004612e7a565b61126e565b34801561051157600080fd5b506102c1610520366004612e7a565b6112e5565b34801561053157600080fd5b50610326610540366004612c42565b611343565b34801561055157600080fd5b506102c1610560366004612e7a565b61138f565b34801561057157600080fd5b506103266113ed565b34801561058657600080fd5b50610359610595366004612c42565b61142b565b3480156105a657600080fd5b506103266114b2565b3480156105bb57600080fd5b506103266114e8565b3480156105d057600080fd5b50610359611541565b3480156105e557600080fd5b50600b546001600160a01b03166102ee565b34801561060357600080fd5b50610326610612366004612c42565b611575565b34801561062357600080fd5b50610326610632366004612e93565b6115cf565b34801561064357600080fd5b506102c161164d565b34801561065857600080fd5b50610326610667366004612d4f565b61165c565b34801561067857600080fd5b50610326611721565b34801561068d57600080fd5b506103266117e0565b3480156106a257600080fd5b506103266106b1366004612cd3565b61189f565b3480156106c257600080fd5b506102c16106d1366004612e7a565b6118d7565b3480156106e257600080fd5b506102c16106f1366004612e7a565b611963565b34801561070257600080fd5b506103596119c1565b34801561071757600080fd5b506103596101f481565b34801561072d57600080fd5b5061029761073c366004612c64565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561077657600080fd5b50610326610785366004612c42565b611adc565b34801561079657600080fd5b506103266107a5366004612c42565b611b74565b3480156107b657600080fd5b50610326611bc0565b3480156107cb57600080fd5b506103266107da366004612eef565b611cd8565b60006001600160e01b0319821663780e9d6360e01b1480610804575061080482611d15565b92915050565b6060600080546108199061335a565b80601f01602080910402602001604051908101604052809291908181526020018280546108459061335a565b80156108925780601f1061086757610100808354040283529160200191610892565b820191906000526020600020905b81548152906001019060200180831161087557829003601f168201915b5050505050905090565b60006108a782611d65565b61090d5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006109348261126e565b9050806001600160a01b0316836001600160a01b031614156109a25760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610904565b336001600160a01b03821614806109be57506109be813361073c565b610a305760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610904565b610a3a8383611d82565b505050565b6060610a4a82611d65565b610a665760405162461bcd60e51b815260040161090490613181565b600d5460405163f998620d60e01b8152600481018490526060916001600160a01b031690601890829063f998620d906024015b60206040518083038186803b158015610ab157600080fd5b505afa158015610ac5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae99190612f51565b60ff1681548110610afc57610afc613429565b906000526020600020018054610b119061335a565b80601f0160208091040260200160405190810160405280929190818152602001828054610b3d9061335a565b8015610b8a5780601f10610b5f57610100808354040283529160200191610b8a565b820191906000526020600020905b815481529060010190602001808311610b6d57829003601f168201915b509398975050505050505050565b6060610ba382611d65565b610bbf5760405162461bcd60e51b815260040161090490613181565b600d54604051630e316c3d60e11b8152600481018490526060916001600160a01b0316906019908290631c62d87a906024015b60206040518083038186803b158015610c0a57600080fd5b505afa158015610c1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c429190612f38565b81548110610afc57610afc613429565b610c5c3382611df0565b610c785760405162461bcd60e51b8152600401610904906131e1565b610a3a838383611eda565b600b546001600160a01b03163314610cad5760405162461bcd60e51b8152600401610904906131ac565b601655565b6000610cbd8361142b565b8210610d1f5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610904565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b600b546001600160a01b03163314610d725760405162461bcd60e51b8152600401610904906131ac565b8051610d8590600f906020840190612b35565b5050565b610a3a8383836040518060200160405280600081525061189f565b600b546001600160a01b03163314610dce5760405162461bcd60e51b8152600401610904906131ac565b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b6060610dfb82611d65565b610e175760405162461bcd60e51b815260040161090490613181565b600d5460405163451032a160e01b8152600481018490526060916001600160a01b031690601b90829063451032a190602401610bf2565b6060610e5982611d65565b610e755760405162461bcd60e51b815260040161090490613181565b600d54604051634875869760e01b8152600481018490526060916001600160a01b0316906017908290634875869790602401610a99565b6000610eb760085490565b8210610f1a5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610904565b60088281548110610f2d57610f2d613429565b90600052602060002001549050919050565b6002600a541415610f625760405162461bcd60e51b815260040161090490613232565b6002600a5560135460ff16610fb95760405162461bcd60e51b815260206004820152601f60248201527f5468652077686974656c697374206973206e6f742061637469766520796574006044820152606401610904565b6101f4601154106110185760405162461bcd60e51b815260206004820152602360248201527f416c6c20746f6b656e732068617665206265656e20616c7265616479206d696e6044820152621d195960ea1b6064820152608401610904565b60125434101561106a5760405162461bcd60e51b815260206004820152601960248201527f496e636f7272656374206d696e7420636f73742076616c7565000000000000006044820152606401610904565b6040516bffffffffffffffffffffffff193360601b1660208201526000906034016040516020818303038152906040528051906020012090506110b08260165483612085565b6110ec5760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210383937b7b360991b6044820152606401610904565b336000908152600e60205260409020546001116111435760405162461bcd60e51b8152602060048201526015602482015274165bdd49dd9948185b1c9958591e481b5a5b9d1959605a1b6044820152606401610904565b600061114d61209b565b60118054919250600061115f83613395565b919050555061117461116e3390565b8261229a565b336000908152600e602052604090205550506001600a55565b6002600a5414156111b05760405162461bcd60e51b815260040161090490613232565b6002600a556014546001600160a01b031633146111fe5760405162461bcd60e51b815260206004820152600c60248201526b04e6f7420436f6465203230360a41b6044820152606401610904565b6013546301000000900460ff16156112285760405162461bcd60e51b815260040161090490613269565b6013805463ff00000019166301000000179055600061124561209b565b60118054919250600061125783613395565b9190505550611266338261229a565b506001600a55565b6000818152600260205260408120546001600160a01b0316806108045760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610904565b60606112f082611d65565b61130c5760405162461bcd60e51b815260040161090490613181565b600d54604051630195437d60e61b8152600481018490526060916001600160a01b031690601d908290636550df4090602401610bf2565b600b546001600160a01b0316331461136d5760405162461bcd60e51b8152600401610904906131ac565b601580546001600160a01b0319166001600160a01b0392909216919091179055565b606061139a82611d65565b6113b65760405162461bcd60e51b815260040161090490613181565b600d546040516368b01c1f60e01b8152600481018490526060916001600160a01b031690601c9082906368b01c1f90602401610bf2565b600b546001600160a01b031633146114175760405162461bcd60e51b8152600401610904906131ac565b6013805460ff19811660ff90911615179055565b60006001600160a01b0382166114965760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610904565b506001600160a01b031660009081526003602052604090205490565b600b546001600160a01b031633146114dc5760405162461bcd60e51b8152600401610904906131ac565b6114e660006122b4565b565b600b546001600160a01b031633146115125760405162461bcd60e51b8152600401610904906131ac565b60405133904780156108fc02916000818181858888f1935050505015801561153e573d6000803e3d6000fd5b50565b600b546000906001600160a01b0316331461156e5760405162461bcd60e51b8152600401610904906131ac565b5060205490565b600b546001600160a01b0316331461159f5760405162461bcd60e51b8152600401610904906131ac565b601380546001600160a01b03909216650100000000000265010000000000600160c81b0319909216919091179055565b336001600160a01b037f000000000000000000000000000000000000000000000000000000000000000016146116475760405162461bcd60e51b815260206004820152601f60248201527f4f6e6c7920565246436f6f7264696e61746f722063616e2066756c66696c6c006044820152606401610904565b60205550565b6060600180546108199061335a565b6001600160a01b0382163314156116b55760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610904565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600b546001600160a01b0316331461174b5760405162461bcd60e51b8152600401610904906131ac565b6002600a54141561176e5760405162461bcd60e51b815260040161090490613232565b6002600a55601354610100900460ff161561179b5760405162461bcd60e51b815260040161090490613269565b6013805461ff00191661010017905560006117b461209b565b6011805491925060006117c683613395565b919050555061126661116e600b546001600160a01b031690565b6002600a5414156118035760405162461bcd60e51b815260040161090490613232565b6002600a556013546501000000000090046001600160a01b0316331461185b5760405162461bcd60e51b815260206004820152600d60248201526c139bdd08115c9c9bdc880d0c0d609a1b6044820152606401610904565b60135462010000900460ff16156118845760405162461bcd60e51b815260040161090490613269565b6013805462ff0000191662010000179055600061124561209b565b6118a93383611df0565b6118c55760405162461bcd60e51b8152600401610904906131e1565b6118d184848484612306565b50505050565b60606118e282611d65565b61192e5760405162461bcd60e51b815260206004820152601d60248201527f517565727920666f72206e6f6e2d6578697374656e7420746f6b656e210000006044820152606401610904565b600f61193983612339565b601060405160200161194d9392919061303a565b6040516020818303038152906040529050919050565b606061196e82611d65565b61198a5760405162461bcd60e51b815260040161090490613181565b600d54604051636681d3b560e11b8152600481018490526060916001600160a01b031690601a90829063cd03a76a90602401610bf2565b600b546000906001600160a01b031633146119ee5760405162461bcd60e51b8152600401610904906131ac565b601f546040516370a0823160e01b81523060048201527f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316906370a082319060240160206040518083038186803b158015611a5057600080fd5b505afa158015611a64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a889190612f38565b1015611ac95760405162461bcd60e51b815260206004820152601060248201526f4e6f7420656e6f756768204c494e4b2160801b6044820152606401610904565b611ad7601e54601f54612437565b905090565b600b546001600160a01b03163314611b065760405162461bcd60e51b8152600401610904906131ac565b6001600160a01b038116611b6b5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610904565b61153e816122b4565b600b546001600160a01b03163314611b9e5760405162461bcd60e51b8152600401610904906131ac565b601480546001600160a01b0319166001600160a01b0392909216919091179055565b6002600a541415611be35760405162461bcd60e51b815260040161090490613232565b6002600a556015546001600160a01b03163314611c395760405162461bcd60e51b8152602060048201526014602482015273139bdd0811da5d99585dd85e5cc81dd85b1b195d60621b6044820152606401610904565b601354640100000000900460ff1615611c645760405162461bcd60e51b815260040161090490613269565b6013805464ff0000000019166401000000001790556000611c8361209b565b601180549192506000611c9583613395565b9190505550611ca4338261229a565b6000611cae61209b565b601180549192506000611cc083613395565b9190505550611ccf338261229a565b50506001600a55565b600b546001600160a01b03163314611d025760405162461bcd60e51b8152600401610904906131ac565b8051610d85906010906020840190612b35565b60006001600160e01b031982166380ac58cd60e01b1480611d4657506001600160e01b03198216635b5e139f60e01b145b8061080457506301ffc9a760e01b6001600160e01b0319831614610804565b6000908152600260205260409020546001600160a01b0316151590565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611db78261126e565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611dfb82611d65565b611e5c5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610904565b6000611e678361126e565b9050806001600160a01b0316846001600160a01b03161480611ea25750836001600160a01b0316611e978461089c565b6001600160a01b0316145b80611ed257506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316611eed8261126e565b6001600160a01b031614611f555760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610904565b6001600160a01b038216611fb75760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610904565b611fc28383836125c2565b611fcd600082611d82565b6001600160a01b0383166000908152600360205260408120805460019290611ff6908490613317565b90915550506001600160a01b03821660009081526003602052604081208054600192906120249084906132c3565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600082612092858461267a565b14949350505050565b6000602054600014156120fc5760405162461bcd60e51b815260206004820152602360248201527f5652462052616e646f6d20526573756c7420686173206e6f74206265656e207360448201526265742160e81b6064820152608401610904565b60006011546101f461210e9190613317565b90506000811561212857612123600183613317565b61212b565b60005b60208054610215546040519394506000938693612156939263ffffffff16913391449142910161306d565b6040516020818303038152906040528051906020012060001c61217991906133b0565b905060006021826101f4811061219157612191613429565b015461219d57816121b4565b6021826101f481106121b1576121b1613429565b01545b90506021836101f481106121ca576121ca613429565b0154156121ec576021836101f481106121e5576121e5613429565b01546121ee565b825b6021836101f4811061220257612202613429565b01556020805461021554604051600093600a9361223093909263ffffffff909116913391449142910161306d565b6040516020818303038152906040528051906020012060001c61225391906133c4565b6102158054919250829160009061227190849063ffffffff166132db565b92506101000a81548163ffffffff021916908363ffffffff160217905550819550505050505090565b610d85828260405180602001604052806000815250612726565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b612311848484611eda565b61231d84848484612759565b6118d15760405162461bcd60e51b81526004016109049061312f565b60608161235d5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612387578061237181613395565b91506123809050600a83613303565b9150612361565b60008167ffffffffffffffff8111156123a2576123a261343f565b6040519080825280601f01601f1916602001820160405280156123cc576020820181803683370190505b5090505b8415611ed2576123e1600183613317565b91506123ee600a866133b0565b6123f99060306132c3565b60f81b81838151811061240e5761240e613429565b60200101906001600160f81b031916908160001a905350612430600a86613303565b94506123d0565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634000aea07f0000000000000000000000000000000000000000000000000000000000000000848660006040516020016124a7929190918252602082015260400190565b6040516020818303038152906040526040518463ffffffff1660e01b81526004016124d4939291906130ec565b602060405180830381600087803b1580156124ee57600080fd5b505af1158015612502573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125269190612e5d565b506000838152600c6020818152604080842054815180840189905280830186905230606082015260808082018390528351808303909101815260a0909101909252815191830191909120938790529190526125829060016132c3565b6000858152600c6020526040902055611ed28482604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b6001600160a01b03831661261d5761261881600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612640565b816001600160a01b0316836001600160a01b031614612640576126408382612866565b6001600160a01b03821661265757610a3a81612903565b826001600160a01b0316826001600160a01b031614610a3a57610a3a82826129b2565b600081815b845181101561271e57600085828151811061269c5761269c613429565b602002602001015190508083116126de57604080516020810185905290810182905260600160405160208183030381529060405280519060200120925061270b565b60408051602081018390529081018490526060016040516020818303038152906040528051906020012092505b508061271681613395565b91505061267f565b509392505050565b61273083836129f6565b61273d6000848484612759565b610a3a5760405162461bcd60e51b81526004016109049061312f565b60006001600160a01b0384163b1561285b57604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061279d9033908990889088906004016130af565b602060405180830381600087803b1580156127b757600080fd5b505af19250505080156127e7575060408051601f3d908101601f191682019092526127e491810190612ed2565b60015b612841573d808015612815576040519150601f19603f3d011682016040523d82523d6000602084013e61281a565b606091505b5080516128395760405162461bcd60e51b81526004016109049061312f565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611ed2565b506001949350505050565b600060016128738461142b565b61287d9190613317565b6000838152600760205260409020549091508082146128d0576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061291590600190613317565b6000838152600960205260408120546008805493945090928490811061293d5761293d613429565b90600052602060002001549050806008838154811061295e5761295e613429565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061299657612996613413565b6001900381819060005260206000200160009055905550505050565b60006129bd8361142b565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160a01b038216612a4c5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610904565b612a5581611d65565b15612aa25760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610904565b612aae600083836125c2565b6001600160a01b0382166000908152600360205260408120805460019290612ad79084906132c3565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b828054612b419061335a565b90600052602060002090601f016020900481019282612b635760008555612ba9565b82601f10612b7c57805160ff1916838001178555612ba9565b82800160010185558215612ba9579182015b82811115612ba9578251825591602001919060010190612b8e565b50612bb5929150612bb9565b5090565b5b80821115612bb55760008155600101612bba565b600067ffffffffffffffff831115612be857612be861343f565b612bfb601f8401601f1916602001613292565b9050828152838383011115612c0f57600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b0381168114612c3d57600080fd5b919050565b600060208284031215612c5457600080fd5b612c5d82612c26565b9392505050565b60008060408385031215612c7757600080fd5b612c8083612c26565b9150612c8e60208401612c26565b90509250929050565b600080600060608486031215612cac57600080fd5b612cb584612c26565b9250612cc360208501612c26565b9150604084013590509250925092565b60008060008060808587031215612ce957600080fd5b612cf285612c26565b9350612d0060208601612c26565b925060408501359150606085013567ffffffffffffffff811115612d2357600080fd5b8501601f81018713612d3457600080fd5b612d4387823560208401612bce565b91505092959194509250565b60008060408385031215612d6257600080fd5b612d6b83612c26565b91506020830135612d7b81613455565b809150509250929050565b60008060408385031215612d9957600080fd5b612da283612c26565b946020939093013593505050565b60006020808385031215612dc357600080fd5b823567ffffffffffffffff80821115612ddb57600080fd5b818501915085601f830112612def57600080fd5b813581811115612e0157612e0161343f565b8060051b9150612e12848301613292565b8181528481019084860184860187018a1015612e2d57600080fd5b600095505b83861015612e50578035835260019590950194918601918601612e32565b5098975050505050505050565b600060208284031215612e6f57600080fd5b8151612c5d81613455565b600060208284031215612e8c57600080fd5b5035919050565b60008060408385031215612ea657600080fd5b50508035926020909101359150565b600060208284031215612ec757600080fd5b8135612c5d81613463565b600060208284031215612ee457600080fd5b8151612c5d81613463565b600060208284031215612f0157600080fd5b813567ffffffffffffffff811115612f1857600080fd5b8201601f81018413612f2957600080fd5b611ed284823560208401612bce565b600060208284031215612f4a57600080fd5b5051919050565b600060208284031215612f6357600080fd5b815160ff81168114612c5d57600080fd5b60008151808452612f8c81602086016020860161332e565b601f01601f19169290920160200192915050565b8054600090600181811c9080831680612fba57607f831692505b6020808410821415612fdc57634e487b7160e01b600052602260045260246000fd5b818015612ff057600181146130015761302e565b60ff1986168952848901965061302e565b60008881526020902060005b868110156130265781548b82015290850190830161300d565b505084890196505b50505050505092915050565b60006130468286612fa0565b845161305681836020890161332e565b61306281830186612fa0565b979650505050505050565b94855260e09390931b6001600160e01b031916602085015260609190911b6bffffffffffffffffffffffff191660248401526038830152605882015260780190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906130e290830184612f74565b9695505050505050565b60018060a01b03841681528260208201526060604082015260006131136060830184612f74565b95945050505050565b602081526000612c5d6020830184612f74565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252601190820152702737b732bc34b9ba32b73a103a37b5b2b760791b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252600f908201526e416c7265616479206d696e7465642160881b604082015260600190565b604051601f8201601f1916810167ffffffffffffffff811182821017156132bb576132bb61343f565b604052919050565b600082198211156132d6576132d66133e7565b500190565b600063ffffffff8083168185168083038211156132fa576132fa6133e7565b01949350505050565b600082613312576133126133fd565b500490565b600082821015613329576133296133e7565b500390565b60005b83811015613349578181015183820152602001613331565b838111156118d15750506000910152565b600181811c9082168061336e57607f821691505b6020821081141561338f57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156133a9576133a96133e7565b5060010190565b6000826133bf576133bf6133fd565b500690565b600063ffffffff808416806133db576133db6133fd565b92169190910692915050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b801515811461153e57600080fd5b6001600160e01b03198116811461153e57600080fdfea2646970667358221220622aee37c71a3534e9b98a0a595722189f668df9e79436d6f54f66939e71295264736f6c63430008070033

Deployed Bytecode

0x6080604052600436106102725760003560e01c806368b01c1f1161014f578063aeceadbf116100c1578063e83157421161007a578063e83157421461070b578063e985e9c514610721578063f2fde38b1461076a578063f58152541461078a578063fc59d962146107aa578063fe05452d146107bf57600080fd5b8063aeceadbf1461066c578063b102b6bc14610681578063b88d4fde14610696578063c87b56dd146106b6578063cd03a76a146106d6578063dbdff2c1146106f657600080fd5b80637390c786116101135780637390c786146105c45780638da5cb5b146105d957806390bbe186146105f757806394985ddd1461061757806395d89b4114610637578063a22cb4651461064c57600080fd5b806368b01c1f14610545578063708aa3dc1461056557806370a082311461057a578063715018a61461059a5780637362377b146105af57600080fd5b806330176e13116101e85780634f6ccce7116101ac5780634f6ccce71461049d57806354703d0c146104bd5780635d41c19c146104d05780636352211e146104e55780636550df401461050557806366b3fbd21461052557600080fd5b806330176e13146103fd57806342842e0e1461041d578063434b3c121461043d578063451032a11461045d578063487586971461047d57600080fd5b806318160ddd1161023a57806318160ddd146103485780631c62d87a1461036757806323b872dd146103875780632d7eae66146103a75780632ddbd13a146103c75780632f745c59146103dd57600080fd5b806301ffc9a71461027757806306fdde03146102ac578063081812fc146102ce578063095ea7b3146103065780631089e56914610328575b600080fd5b34801561028357600080fd5b50610297610292366004612eb5565b6107df565b60405190151581526020015b60405180910390f35b3480156102b857600080fd5b506102c161080a565b6040516102a3919061311c565b3480156102da57600080fd5b506102ee6102e9366004612e7a565b61089c565b6040516001600160a01b0390911681526020016102a3565b34801561031257600080fd5b50610326610321366004612d86565b610929565b005b34801561033457600080fd5b506102c1610343366004612e7a565b610a3f565b34801561035457600080fd5b506008545b6040519081526020016102a3565b34801561037357600080fd5b506102c1610382366004612e7a565b610b98565b34801561039357600080fd5b506103266103a2366004612c97565b610c52565b3480156103b357600080fd5b506103266103c2366004612e7a565b610c83565b3480156103d357600080fd5b5061035960115481565b3480156103e957600080fd5b506103596103f8366004612d86565b610cb2565b34801561040957600080fd5b50610326610418366004612eef565b610d48565b34801561042957600080fd5b50610326610438366004612c97565b610d89565b34801561044957600080fd5b50610326610458366004612c42565b610da4565b34801561046957600080fd5b506102c1610478366004612e7a565b610df0565b34801561048957600080fd5b506102c1610498366004612e7a565b610e4e565b3480156104a957600080fd5b506103596104b8366004612e7a565b610eac565b6103266104cb366004612db0565b610f3f565b3480156104dc57600080fd5b5061032661118d565b3480156104f157600080fd5b506102ee610500366004612e7a565b61126e565b34801561051157600080fd5b506102c1610520366004612e7a565b6112e5565b34801561053157600080fd5b50610326610540366004612c42565b611343565b34801561055157600080fd5b506102c1610560366004612e7a565b61138f565b34801561057157600080fd5b506103266113ed565b34801561058657600080fd5b50610359610595366004612c42565b61142b565b3480156105a657600080fd5b506103266114b2565b3480156105bb57600080fd5b506103266114e8565b3480156105d057600080fd5b50610359611541565b3480156105e557600080fd5b50600b546001600160a01b03166102ee565b34801561060357600080fd5b50610326610612366004612c42565b611575565b34801561062357600080fd5b50610326610632366004612e93565b6115cf565b34801561064357600080fd5b506102c161164d565b34801561065857600080fd5b50610326610667366004612d4f565b61165c565b34801561067857600080fd5b50610326611721565b34801561068d57600080fd5b506103266117e0565b3480156106a257600080fd5b506103266106b1366004612cd3565b61189f565b3480156106c257600080fd5b506102c16106d1366004612e7a565b6118d7565b3480156106e257600080fd5b506102c16106f1366004612e7a565b611963565b34801561070257600080fd5b506103596119c1565b34801561071757600080fd5b506103596101f481565b34801561072d57600080fd5b5061029761073c366004612c64565b6001600160a01b03918216600090815260056020908152604080832093909416825291909152205460ff1690565b34801561077657600080fd5b50610326610785366004612c42565b611adc565b34801561079657600080fd5b506103266107a5366004612c42565b611b74565b3480156107b657600080fd5b50610326611bc0565b3480156107cb57600080fd5b506103266107da366004612eef565b611cd8565b60006001600160e01b0319821663780e9d6360e01b1480610804575061080482611d15565b92915050565b6060600080546108199061335a565b80601f01602080910402602001604051908101604052809291908181526020018280546108459061335a565b80156108925780601f1061086757610100808354040283529160200191610892565b820191906000526020600020905b81548152906001019060200180831161087557829003601f168201915b5050505050905090565b60006108a782611d65565b61090d5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600460205260409020546001600160a01b031690565b60006109348261126e565b9050806001600160a01b0316836001600160a01b031614156109a25760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610904565b336001600160a01b03821614806109be57506109be813361073c565b610a305760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610904565b610a3a8383611d82565b505050565b6060610a4a82611d65565b610a665760405162461bcd60e51b815260040161090490613181565b600d5460405163f998620d60e01b8152600481018490526060916001600160a01b031690601890829063f998620d906024015b60206040518083038186803b158015610ab157600080fd5b505afa158015610ac5573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610ae99190612f51565b60ff1681548110610afc57610afc613429565b906000526020600020018054610b119061335a565b80601f0160208091040260200160405190810160405280929190818152602001828054610b3d9061335a565b8015610b8a5780601f10610b5f57610100808354040283529160200191610b8a565b820191906000526020600020905b815481529060010190602001808311610b6d57829003601f168201915b509398975050505050505050565b6060610ba382611d65565b610bbf5760405162461bcd60e51b815260040161090490613181565b600d54604051630e316c3d60e11b8152600481018490526060916001600160a01b0316906019908290631c62d87a906024015b60206040518083038186803b158015610c0a57600080fd5b505afa158015610c1e573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190610c429190612f38565b81548110610afc57610afc613429565b610c5c3382611df0565b610c785760405162461bcd60e51b8152600401610904906131e1565b610a3a838383611eda565b600b546001600160a01b03163314610cad5760405162461bcd60e51b8152600401610904906131ac565b601655565b6000610cbd8361142b565b8210610d1f5760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b6064820152608401610904565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b600b546001600160a01b03163314610d725760405162461bcd60e51b8152600401610904906131ac565b8051610d8590600f906020840190612b35565b5050565b610a3a8383836040518060200160405280600081525061189f565b600b546001600160a01b03163314610dce5760405162461bcd60e51b8152600401610904906131ac565b600d80546001600160a01b0319166001600160a01b0392909216919091179055565b6060610dfb82611d65565b610e175760405162461bcd60e51b815260040161090490613181565b600d5460405163451032a160e01b8152600481018490526060916001600160a01b031690601b90829063451032a190602401610bf2565b6060610e5982611d65565b610e755760405162461bcd60e51b815260040161090490613181565b600d54604051634875869760e01b8152600481018490526060916001600160a01b0316906017908290634875869790602401610a99565b6000610eb760085490565b8210610f1a5760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b6064820152608401610904565b60088281548110610f2d57610f2d613429565b90600052602060002001549050919050565b6002600a541415610f625760405162461bcd60e51b815260040161090490613232565b6002600a5560135460ff16610fb95760405162461bcd60e51b815260206004820152601f60248201527f5468652077686974656c697374206973206e6f742061637469766520796574006044820152606401610904565b6101f4601154106110185760405162461bcd60e51b815260206004820152602360248201527f416c6c20746f6b656e732068617665206265656e20616c7265616479206d696e6044820152621d195960ea1b6064820152608401610904565b60125434101561106a5760405162461bcd60e51b815260206004820152601960248201527f496e636f7272656374206d696e7420636f73742076616c7565000000000000006044820152606401610904565b6040516bffffffffffffffffffffffff193360601b1660208201526000906034016040516020818303038152906040528051906020012090506110b08260165483612085565b6110ec5760405162461bcd60e51b815260206004820152600d60248201526c24b73b30b634b210383937b7b360991b6044820152606401610904565b336000908152600e60205260409020546001116111435760405162461bcd60e51b8152602060048201526015602482015274165bdd49dd9948185b1c9958591e481b5a5b9d1959605a1b6044820152606401610904565b600061114d61209b565b60118054919250600061115f83613395565b919050555061117461116e3390565b8261229a565b336000908152600e602052604090205550506001600a55565b6002600a5414156111b05760405162461bcd60e51b815260040161090490613232565b6002600a556014546001600160a01b031633146111fe5760405162461bcd60e51b815260206004820152600c60248201526b04e6f7420436f6465203230360a41b6044820152606401610904565b6013546301000000900460ff16156112285760405162461bcd60e51b815260040161090490613269565b6013805463ff00000019166301000000179055600061124561209b565b60118054919250600061125783613395565b9190505550611266338261229a565b506001600a55565b6000818152600260205260408120546001600160a01b0316806108045760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610904565b60606112f082611d65565b61130c5760405162461bcd60e51b815260040161090490613181565b600d54604051630195437d60e61b8152600481018490526060916001600160a01b031690601d908290636550df4090602401610bf2565b600b546001600160a01b0316331461136d5760405162461bcd60e51b8152600401610904906131ac565b601580546001600160a01b0319166001600160a01b0392909216919091179055565b606061139a82611d65565b6113b65760405162461bcd60e51b815260040161090490613181565b600d546040516368b01c1f60e01b8152600481018490526060916001600160a01b031690601c9082906368b01c1f90602401610bf2565b600b546001600160a01b031633146114175760405162461bcd60e51b8152600401610904906131ac565b6013805460ff19811660ff90911615179055565b60006001600160a01b0382166114965760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610904565b506001600160a01b031660009081526003602052604090205490565b600b546001600160a01b031633146114dc5760405162461bcd60e51b8152600401610904906131ac565b6114e660006122b4565b565b600b546001600160a01b031633146115125760405162461bcd60e51b8152600401610904906131ac565b60405133904780156108fc02916000818181858888f1935050505015801561153e573d6000803e3d6000fd5b50565b600b546000906001600160a01b0316331461156e5760405162461bcd60e51b8152600401610904906131ac565b5060205490565b600b546001600160a01b0316331461159f5760405162461bcd60e51b8152600401610904906131ac565b601380546001600160a01b03909216650100000000000265010000000000600160c81b0319909216919091179055565b336001600160a01b037f000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb795216146116475760405162461bcd60e51b815260206004820152601f60248201527f4f6e6c7920565246436f6f7264696e61746f722063616e2066756c66696c6c006044820152606401610904565b60205550565b6060600180546108199061335a565b6001600160a01b0382163314156116b55760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610904565b3360008181526005602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b600b546001600160a01b0316331461174b5760405162461bcd60e51b8152600401610904906131ac565b6002600a54141561176e5760405162461bcd60e51b815260040161090490613232565b6002600a55601354610100900460ff161561179b5760405162461bcd60e51b815260040161090490613269565b6013805461ff00191661010017905560006117b461209b565b6011805491925060006117c683613395565b919050555061126661116e600b546001600160a01b031690565b6002600a5414156118035760405162461bcd60e51b815260040161090490613232565b6002600a556013546501000000000090046001600160a01b0316331461185b5760405162461bcd60e51b815260206004820152600d60248201526c139bdd08115c9c9bdc880d0c0d609a1b6044820152606401610904565b60135462010000900460ff16156118845760405162461bcd60e51b815260040161090490613269565b6013805462ff0000191662010000179055600061124561209b565b6118a93383611df0565b6118c55760405162461bcd60e51b8152600401610904906131e1565b6118d184848484612306565b50505050565b60606118e282611d65565b61192e5760405162461bcd60e51b815260206004820152601d60248201527f517565727920666f72206e6f6e2d6578697374656e7420746f6b656e210000006044820152606401610904565b600f61193983612339565b601060405160200161194d9392919061303a565b6040516020818303038152906040529050919050565b606061196e82611d65565b61198a5760405162461bcd60e51b815260040161090490613181565b600d54604051636681d3b560e11b8152600481018490526060916001600160a01b031690601a90829063cd03a76a90602401610bf2565b600b546000906001600160a01b031633146119ee5760405162461bcd60e51b8152600401610904906131ac565b601f546040516370a0823160e01b81523060048201527f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca6001600160a01b0316906370a082319060240160206040518083038186803b158015611a5057600080fd5b505afa158015611a64573d6000803e3d6000fd5b505050506040513d601f19601f82011682018060405250810190611a889190612f38565b1015611ac95760405162461bcd60e51b815260206004820152601060248201526f4e6f7420656e6f756768204c494e4b2160801b6044820152606401610904565b611ad7601e54601f54612437565b905090565b600b546001600160a01b03163314611b065760405162461bcd60e51b8152600401610904906131ac565b6001600160a01b038116611b6b5760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610904565b61153e816122b4565b600b546001600160a01b03163314611b9e5760405162461bcd60e51b8152600401610904906131ac565b601480546001600160a01b0319166001600160a01b0392909216919091179055565b6002600a541415611be35760405162461bcd60e51b815260040161090490613232565b6002600a556015546001600160a01b03163314611c395760405162461bcd60e51b8152602060048201526014602482015273139bdd0811da5d99585dd85e5cc81dd85b1b195d60621b6044820152606401610904565b601354640100000000900460ff1615611c645760405162461bcd60e51b815260040161090490613269565b6013805464ff0000000019166401000000001790556000611c8361209b565b601180549192506000611c9583613395565b9190505550611ca4338261229a565b6000611cae61209b565b601180549192506000611cc083613395565b9190505550611ccf338261229a565b50506001600a55565b600b546001600160a01b03163314611d025760405162461bcd60e51b8152600401610904906131ac565b8051610d85906010906020840190612b35565b60006001600160e01b031982166380ac58cd60e01b1480611d4657506001600160e01b03198216635b5e139f60e01b145b8061080457506301ffc9a760e01b6001600160e01b0319831614610804565b6000908152600260205260409020546001600160a01b0316151590565b600081815260046020526040902080546001600160a01b0319166001600160a01b0384169081179091558190611db78261126e565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611dfb82611d65565b611e5c5760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b6064820152608401610904565b6000611e678361126e565b9050806001600160a01b0316846001600160a01b03161480611ea25750836001600160a01b0316611e978461089c565b6001600160a01b0316145b80611ed257506001600160a01b0380821660009081526005602090815260408083209388168352929052205460ff165b949350505050565b826001600160a01b0316611eed8261126e565b6001600160a01b031614611f555760405162461bcd60e51b815260206004820152602960248201527f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960448201526839903737ba1037bbb760b91b6064820152608401610904565b6001600160a01b038216611fb75760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610904565b611fc28383836125c2565b611fcd600082611d82565b6001600160a01b0383166000908152600360205260408120805460019290611ff6908490613317565b90915550506001600160a01b03821660009081526003602052604081208054600192906120249084906132c3565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600082612092858461267a565b14949350505050565b6000602054600014156120fc5760405162461bcd60e51b815260206004820152602360248201527f5652462052616e646f6d20526573756c7420686173206e6f74206265656e207360448201526265742160e81b6064820152608401610904565b60006011546101f461210e9190613317565b90506000811561212857612123600183613317565b61212b565b60005b60208054610215546040519394506000938693612156939263ffffffff16913391449142910161306d565b6040516020818303038152906040528051906020012060001c61217991906133b0565b905060006021826101f4811061219157612191613429565b015461219d57816121b4565b6021826101f481106121b1576121b1613429565b01545b90506021836101f481106121ca576121ca613429565b0154156121ec576021836101f481106121e5576121e5613429565b01546121ee565b825b6021836101f4811061220257612202613429565b01556020805461021554604051600093600a9361223093909263ffffffff909116913391449142910161306d565b6040516020818303038152906040528051906020012060001c61225391906133c4565b6102158054919250829160009061227190849063ffffffff166132db565b92506101000a81548163ffffffff021916908363ffffffff160217905550819550505050505090565b610d85828260405180602001604052806000815250612726565b600b80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b612311848484611eda565b61231d84848484612759565b6118d15760405162461bcd60e51b81526004016109049061312f565b60608161235d5750506040805180820190915260018152600360fc1b602082015290565b8160005b8115612387578061237181613395565b91506123809050600a83613303565b9150612361565b60008167ffffffffffffffff8111156123a2576123a261343f565b6040519080825280601f01601f1916602001820160405280156123cc576020820181803683370190505b5090505b8415611ed2576123e1600183613317565b91506123ee600a866133b0565b6123f99060306132c3565b60f81b81838151811061240e5761240e613429565b60200101906001600160f81b031916908160001a905350612430600a86613303565b94506123d0565b60007f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca6001600160a01b0316634000aea07f000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb7952848660006040516020016124a7929190918252602082015260400190565b6040516020818303038152906040526040518463ffffffff1660e01b81526004016124d4939291906130ec565b602060405180830381600087803b1580156124ee57600080fd5b505af1158015612502573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906125269190612e5d565b506000838152600c6020818152604080842054815180840189905280830186905230606082015260808082018390528351808303909101815260a0909101909252815191830191909120938790529190526125829060016132c3565b6000858152600c6020526040902055611ed28482604080516020808201949094528082019290925280518083038201815260609092019052805191012090565b6001600160a01b03831661261d5761261881600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b612640565b816001600160a01b0316836001600160a01b031614612640576126408382612866565b6001600160a01b03821661265757610a3a81612903565b826001600160a01b0316826001600160a01b031614610a3a57610a3a82826129b2565b600081815b845181101561271e57600085828151811061269c5761269c613429565b602002602001015190508083116126de57604080516020810185905290810182905260600160405160208183030381529060405280519060200120925061270b565b60408051602081018390529081018490526060016040516020818303038152906040528051906020012092505b508061271681613395565b91505061267f565b509392505050565b61273083836129f6565b61273d6000848484612759565b610a3a5760405162461bcd60e51b81526004016109049061312f565b60006001600160a01b0384163b1561285b57604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061279d9033908990889088906004016130af565b602060405180830381600087803b1580156127b757600080fd5b505af19250505080156127e7575060408051601f3d908101601f191682019092526127e491810190612ed2565b60015b612841573d808015612815576040519150601f19603f3d011682016040523d82523d6000602084013e61281a565b606091505b5080516128395760405162461bcd60e51b81526004016109049061312f565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611ed2565b506001949350505050565b600060016128738461142b565b61287d9190613317565b6000838152600760205260409020549091508082146128d0576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061291590600190613317565b6000838152600960205260408120546008805493945090928490811061293d5761293d613429565b90600052602060002001549050806008838154811061295e5761295e613429565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061299657612996613413565b6001900381819060005260206000200160009055905550505050565b60006129bd8361142b565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b6001600160a01b038216612a4c5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610904565b612a5581611d65565b15612aa25760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610904565b612aae600083836125c2565b6001600160a01b0382166000908152600360205260408120805460019290612ad79084906132c3565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b828054612b419061335a565b90600052602060002090601f016020900481019282612b635760008555612ba9565b82601f10612b7c57805160ff1916838001178555612ba9565b82800160010185558215612ba9579182015b82811115612ba9578251825591602001919060010190612b8e565b50612bb5929150612bb9565b5090565b5b80821115612bb55760008155600101612bba565b600067ffffffffffffffff831115612be857612be861343f565b612bfb601f8401601f1916602001613292565b9050828152838383011115612c0f57600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b0381168114612c3d57600080fd5b919050565b600060208284031215612c5457600080fd5b612c5d82612c26565b9392505050565b60008060408385031215612c7757600080fd5b612c8083612c26565b9150612c8e60208401612c26565b90509250929050565b600080600060608486031215612cac57600080fd5b612cb584612c26565b9250612cc360208501612c26565b9150604084013590509250925092565b60008060008060808587031215612ce957600080fd5b612cf285612c26565b9350612d0060208601612c26565b925060408501359150606085013567ffffffffffffffff811115612d2357600080fd5b8501601f81018713612d3457600080fd5b612d4387823560208401612bce565b91505092959194509250565b60008060408385031215612d6257600080fd5b612d6b83612c26565b91506020830135612d7b81613455565b809150509250929050565b60008060408385031215612d9957600080fd5b612da283612c26565b946020939093013593505050565b60006020808385031215612dc357600080fd5b823567ffffffffffffffff80821115612ddb57600080fd5b818501915085601f830112612def57600080fd5b813581811115612e0157612e0161343f565b8060051b9150612e12848301613292565b8181528481019084860184860187018a1015612e2d57600080fd5b600095505b83861015612e50578035835260019590950194918601918601612e32565b5098975050505050505050565b600060208284031215612e6f57600080fd5b8151612c5d81613455565b600060208284031215612e8c57600080fd5b5035919050565b60008060408385031215612ea657600080fd5b50508035926020909101359150565b600060208284031215612ec757600080fd5b8135612c5d81613463565b600060208284031215612ee457600080fd5b8151612c5d81613463565b600060208284031215612f0157600080fd5b813567ffffffffffffffff811115612f1857600080fd5b8201601f81018413612f2957600080fd5b611ed284823560208401612bce565b600060208284031215612f4a57600080fd5b5051919050565b600060208284031215612f6357600080fd5b815160ff81168114612c5d57600080fd5b60008151808452612f8c81602086016020860161332e565b601f01601f19169290920160200192915050565b8054600090600181811c9080831680612fba57607f831692505b6020808410821415612fdc57634e487b7160e01b600052602260045260246000fd5b818015612ff057600181146130015761302e565b60ff1986168952848901965061302e565b60008881526020902060005b868110156130265781548b82015290850190830161300d565b505084890196505b50505050505092915050565b60006130468286612fa0565b845161305681836020890161332e565b61306281830186612fa0565b979650505050505050565b94855260e09390931b6001600160e01b031916602085015260609190911b6bffffffffffffffffffffffff191660248401526038830152605882015260780190565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906130e290830184612f74565b9695505050505050565b60018060a01b03841681528260208201526060604082015260006131136060830184612f74565b95945050505050565b602081526000612c5d6020830184612f74565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252601190820152702737b732bc34b9ba32b73a103a37b5b2b760791b604082015260600190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b60208082526031908201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6040820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b606082015260800190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b6020808252600f908201526e416c7265616479206d696e7465642160881b604082015260600190565b604051601f8201601f1916810167ffffffffffffffff811182821017156132bb576132bb61343f565b604052919050565b600082198211156132d6576132d66133e7565b500190565b600063ffffffff8083168185168083038211156132fa576132fa6133e7565b01949350505050565b600082613312576133126133fd565b500490565b600082821015613329576133296133e7565b500390565b60005b83811015613349578181015183820152602001613331565b838111156118d15750506000910152565b600181811c9082168061336e57607f821691505b6020821081141561338f57634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156133a9576133a96133e7565b5060010190565b6000826133bf576133bf6133fd565b500690565b600063ffffffff808416806133db576133db6133fd565b92169190910692915050565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052603160045260246000fd5b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b801515811461153e57600080fd5b6001600160e01b03198116811461153e57600080fdfea2646970667358221220622aee37c71a3534e9b98a0a595722189f668df9e79436d6f54f66939e71295264736f6c63430008070033

Deployed Bytecode Sourcemap

60672:11508:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;53900:224;;;;;;;;;;-1:-1:-1;53900:224:0;;;;;:::i;:::-;;:::i;:::-;;;10128:14:1;;10121:22;10103:41;;10091:2;10076:18;53900:224:0;;;;;;;;41052:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;42581:221::-;;;;;;;;;;-1:-1:-1;42581:221:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;9036:32:1;;;9018:51;;9006:2;8991:18;42581:221:0;8872:203:1;42104:411:0;;;;;;;;;;-1:-1:-1;42104:411:0;;;;;:::i;:::-;;:::i;:::-;;62987:353;;;;;;;;;;-1:-1:-1;62987:353:0;;;;;:::i;:::-;;:::i;54540:113::-;;;;;;;;;;-1:-1:-1;54628:10:0;:17;54540:113;;;10301:25:1;;;10289:2;10274:18;54540:113:0;10155:177:1;63346:353:0;;;;;;;;;;-1:-1:-1;63346:353:0;;;;;:::i;:::-;;:::i;43471:339::-;;;;;;;;;;-1:-1:-1;43471:339:0;;;;;:::i;:::-;;:::i;66115:97::-;;;;;;;;;;-1:-1:-1;66115:97:0;;;;;:::i;:::-;;:::i;61041:21::-;;;;;;;;;;;;;;;;54208:256;;;;;;;;;;-1:-1:-1;54208:256:0;;;;;:::i;:::-;;:::i;65243:102::-;;;;;;;;;;-1:-1:-1;65243:102:0;;;;;:::i;:::-;;:::i;43881:185::-;;;;;;;;;;-1:-1:-1;43881:185:0;;;;;:::i;:::-;;:::i;65125:112::-;;;;;;;;;;-1:-1:-1;65125:112:0;;;;;:::i;:::-;;:::i;64052:347::-;;;;;;;;;;-1:-1:-1;64052:347:0;;;;;:::i;:::-;;:::i;62661:320::-;;;;;;;;;;-1:-1:-1;62661:320:0;;;;;:::i;:::-;;:::i;54730:233::-;;;;;;;;;;-1:-1:-1;54730:233:0;;;;;:::i;:::-;;:::i;67650:791::-;;;;;;:::i;:::-;;:::i;66894:292::-;;;;;;;;;;;;;:::i;40746:239::-;;;;;;;;;;-1:-1:-1;40746:239:0;;;;;:::i;:::-;;:::i;64761:344::-;;;;;;;;;;-1:-1:-1;64761:344:0;;;;;:::i;:::-;;:::i;65991:118::-;;;;;;;;;;-1:-1:-1;65991:118:0;;;;;:::i;:::-;;:::i;64405:350::-;;;;;;;;;;-1:-1:-1;64405:350:0;;;;;:::i;:::-;;:::i;66218:106::-;;;;;;;;;;;;;:::i;40476:208::-;;;;;;;;;;-1:-1:-1;40476:208:0;;;;;:::i;:::-;;:::i;25498:94::-;;;;;;;;;;;;;:::i;72062:113::-;;;;;;;;;;;;;:::i;69587:102::-;;;;;;;;;;;;;:::i;24847:87::-;;;;;;;;;;-1:-1:-1;24920:6:0;;-1:-1:-1;;;;;24920:6:0;24847:87;;65749:116;;;;;;;;;;-1:-1:-1;65749:116:0;;;;;:::i;:::-;;:::i;15512:210::-;;;;;;;;;;-1:-1:-1;15512:210:0;;;;;:::i;:::-;;:::i;41221:104::-;;;;;;;;;;;;;:::i;42874:295::-;;;;;;;;;;-1:-1:-1;42874:295:0;;;;;:::i;:::-;;:::i;66341:244::-;;;;;;;;;;;;;:::i;66591:297::-;;;;;;;;;;;;;:::i;44137:328::-;;;;;;;;;;-1:-1:-1;44137:328:0;;;;;:::i;:::-;;:::i;65479:264::-;;;;;;;;;;-1:-1:-1;65479:264:0;;;;;:::i;:::-;;:::i;63705:341::-;;;;;;;;;;-1:-1:-1;63705:341:0;;;;;:::i;:::-;;:::i;69245:205::-;;;;;;;;;;;;;:::i;60998:36::-;;;;;;;;;;;;61031:3;60998:36;;43240:164;;;;;;;;;;-1:-1:-1;43240:164:0;;;;;:::i;:::-;-1:-1:-1;;;;;43361:25:0;;;43337:4;43361:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;43240:164;25747:192;;;;;;;;;;-1:-1:-1;25747:192:0;;;;;:::i;:::-;;:::i;65871:114::-;;;;;;;;;;-1:-1:-1;65871:114:0;;;;;:::i;:::-;;:::i;67192:452::-;;;;;;;;;;;;;:::i;65351:122::-;;;;;;;;;;-1:-1:-1;65351:122:0;;;;;:::i;:::-;;:::i;53900:224::-;54002:4;-1:-1:-1;;;;;;54026:50:0;;-1:-1:-1;;;54026:50:0;;:90;;;54080:36;54104:11;54080:23;:36::i;:::-;54019:97;53900:224;-1:-1:-1;;53900:224:0:o;41052:100::-;41106:13;41139:5;41132:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41052:100;:::o;42581:221::-;42657:7;42685:16;42693:7;42685;:16::i;:::-;42677:73;;;;-1:-1:-1;;;42677:73:0;;19416:2:1;42677:73:0;;;19398:21:1;19455:2;19435:18;;;19428:30;19494:34;19474:18;;;19467:62;-1:-1:-1;;;19545:18:1;;;19538:42;19597:19;;42677:73:0;;;;;;;;;-1:-1:-1;42770:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;42770:24:0;;42581:221::o;42104:411::-;42185:13;42201:23;42216:7;42201:14;:23::i;:::-;42185:39;;42249:5;-1:-1:-1;;;;;42243:11:0;:2;-1:-1:-1;;;;;42243:11:0;;;42235:57;;;;-1:-1:-1;;;42235:57:0;;20960:2:1;42235:57:0;;;20942:21:1;20999:2;20979:18;;;20972:30;21038:34;21018:18;;;21011:62;-1:-1:-1;;;21089:18:1;;;21082:31;21130:19;;42235:57:0;20758:397:1;42235:57:0;23801:10;-1:-1:-1;;;;;42327:21:0;;;;:62;;-1:-1:-1;42352:37:0;42369:5;23801:10;43240:164;:::i;42352:37::-;42305:168;;;;-1:-1:-1;;;42305:168:0;;16009:2:1;42305:168:0;;;15991:21:1;16048:2;16028:18;;;16021:30;16087:34;16067:18;;;16060:62;16158:26;16138:18;;;16131:54;16202:19;;42305:168:0;15807:420:1;42305:168:0;42486:21;42495:2;42499:7;42486:8;:21::i;:::-;42174:341;42104:411;;:::o;62987:353::-;63057:13;63091:16;63099:7;63091;:16::i;:::-;63083:46;;;;-1:-1:-1;;;63083:46:0;;;;;;;:::i;:::-;63209:12;;63266:37;;-1:-1:-1;;;63266:37:0;;;;;10301:25:1;;;63144:20:0;;-1:-1:-1;;;;;63209:12:0;;63246:19;;63209:12;;63266:28;;10274:18:1;;63266:37:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;63246:58;;;;;;;;;;:::i;:::-;;;;;;;;63237:67;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;63237:67:0;;62987:353;-1:-1:-1;;;;;;;;62987:353:0:o;63346:::-;63414:13;63448:16;63456:7;63448;:16::i;:::-;63440:46;;;;-1:-1:-1;;;63440:46:0;;;;;;;:::i;:::-;63566:12;;63621:41;;-1:-1:-1;;;63621:41:0;;;;;10301:25:1;;;63501:20:0;;-1:-1:-1;;;;;63566:12:0;;63603:17;;63566:12;;63621:32;;10274:18:1;;63621:41:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;63603:60;;;;;;;;:::i;43471:339::-;43666:41;23801:10;43699:7;43666:18;:41::i;:::-;43658:103;;;;-1:-1:-1;;;43658:103:0;;;;;;;:::i;:::-;43774:28;43784:4;43790:2;43794:7;43774:9;:28::i;66115:97::-;24920:6;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;66184:9:::1;:20:::0;66115:97::o;54208:256::-;54305:7;54341:23;54358:5;54341:16;:23::i;:::-;54333:5;:31;54325:87;;;;-1:-1:-1;;;54325:87:0;;12547:2:1;54325:87:0;;;12529:21:1;12586:2;12566:18;;;12559:30;12625:34;12605:18;;;12598:62;-1:-1:-1;;;12676:18:1;;;12669:41;12727:19;;54325:87:0;12345:407:1;54325:87:0;-1:-1:-1;;;;;;54430:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;54208:256::o;65243:102::-;24920:6;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;65318:19;;::::1;::::0;:12:::1;::::0;:19:::1;::::0;::::1;::::0;::::1;:::i;:::-;;65243:102:::0;:::o;43881:185::-;44019:39;44036:4;44042:2;44046:7;44019:39;;;;;;;;;;;;:16;:39::i;65125:112::-;24920:6;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;65201:12:::1;:28:::0;;-1:-1:-1;;;;;;65201:28:0::1;-1:-1:-1::0;;;;;65201:28:0;;;::::1;::::0;;;::::1;::::0;;65125:112::o;64052:347::-;64118:13;64152:16;64160:7;64152;:16::i;:::-;64144:46;;;;-1:-1:-1;;;64144:46:0;;;;;;;:::i;:::-;64270:12;;64323:39;;-1:-1:-1;;;64323:39:0;;;;;10301:25:1;;;64205:20:0;;-1:-1:-1;;;;;64270:12:0;;64307:15;;64270:12;;64323:30;;10274:18:1;;64323:39:0;10155:177:1;62661:320:0;62718:13;62752:16;62760:7;62752;:16::i;:::-;62744:46;;;;-1:-1:-1;;;62744:46:0;;;;;;;:::i;:::-;62870:12;;62914:30;;-1:-1:-1;;;62914:30:0;;;;;10301:25:1;;;62805:20:0;;-1:-1:-1;;;;;62870:12:0;;62907:6;;62870:12;;62914:21;;10274:18:1;;62914:30:0;10155:177:1;54730:233:0;54805:7;54841:30;54628:10;:17;;54540:113;54841:30;54833:5;:38;54825:95;;;;-1:-1:-1;;;54825:95:0;;22129:2:1;54825:95:0;;;22111:21:1;22168:2;22148:18;;;22141:30;22207:34;22187:18;;;22180:62;-1:-1:-1;;;22258:18:1;;;22251:42;22310:19;;54825:95:0;21927:408:1;54825:95:0;54938:10;54949:5;54938:17;;;;;;;;:::i;:::-;;;;;;;;;54931:24;;54730:233;;;:::o;67650:791::-;27780:1;28376:7;;:19;;28368:63;;;;-1:-1:-1;;;28368:63:0;;;;;;;:::i;:::-;27780:1;28509:7;:18;67745:15:::1;::::0;::::1;;67737:59;;;::::0;-1:-1:-1;;;67737:59:0;;11438:2:1;67737:59:0::1;::::0;::::1;11420:21:1::0;11477:2;11457:18;;;11450:30;11516:33;11496:18;;;11489:61;11567:18;;67737:59:0::1;11236:355:1::0;67737:59:0::1;61031:3;67815:5;;:17;67807:65;;;::::0;-1:-1:-1;;;67807:65:0;;17951:2:1;67807:65:0::1;::::0;::::1;17933:21:1::0;17990:2;17970:18;;;17963:30;18029:34;18009:18;;;18002:62;-1:-1:-1;;;18080:18:1;;;18073:33;18123:19;;67807:65:0::1;17749:399:1::0;67807:65:0::1;67898:8;;67885:9;:21;;67877:59;;;::::0;-1:-1:-1;;;67877:59:0;;15655:2:1;67877:59:0::1;::::0;::::1;15637:21:1::0;15694:2;15674:18;;;15667:30;15733:27;15713:18;;;15706:55;15778:18;;67877:59:0::1;15453:349:1::0;67877:59:0::1;67999:28;::::0;-1:-1:-1;;68016:10:0::1;7292:2:1::0;7288:15;7284:53;67999:28:0::1;::::0;::::1;7272:66:1::0;67974:12:0::1;::::0;7354::1;;67999:28:0::1;;;;;;;;;;;;67989:39;;;;;;67974:54;;68041:42;68060:5;68067:9;;68078:4;68041:18;:42::i;:::-;68033:68;;;::::0;-1:-1:-1;;;68033:68:0;;22542:2:1;68033:68:0::1;::::0;::::1;22524:21:1::0;22581:2;22561:18;;;22554:30;-1:-1:-1;;;22600:18:1;;;22593:43;22653:18;;68033:68:0::1;22340:337:1::0;68033:68:0::1;23801:10:::0;68124:31:::1;::::0;;;:17:::1;:31;::::0;;;;;68158:1:::1;-1:-1:-1::0;68116:69:0::1;;;::::0;-1:-1:-1;;;68116:69:0;;16780:2:1;68116:69:0::1;::::0;::::1;16762:21:1::0;16819:2;16799:18;;;16792:30;-1:-1:-1;;;16838:18:1;;;16831:51;16899:18;;68116:69:0::1;16578:345:1::0;68116:69:0::1;68194:12;68209:19;:17;:19::i;:::-;68239:5;:7:::0;;68194:34;;-1:-1:-1;68239:5:0::1;:7;::::0;::::1;:::i;:::-;;;;;;68259:32;68269:12;23801:10:::0;;23721:98;68269:12:::1;68283:7;68259:9;:32::i;:::-;23801:10:::0;68392:31:::1;::::0;;;:17:::1;:31;::::0;;;;:41;-1:-1:-1;;27736:1:0;28688:7;:22;67650:791::o;66894:292::-;27780:1;28376:7;;:19;;28368:63;;;;-1:-1:-1;;;28368:63:0;;;;;;;:::i;:::-;27780:1;28509:7;:18;66965:14:::1;::::0;-1:-1:-1;;;;;66965:14:0::1;66951:10;:28;66943:53;;;::::0;-1:-1:-1;;;66943:53:0;;14142:2:1;66943:53:0::1;::::0;::::1;14124:21:1::0;14181:2;14161:18;;;14154:30;-1:-1:-1;;;14200:18:1;;;14193:42;14252:18;;66943:53:0::1;13940:336:1::0;66943:53:0::1;67009:13;::::0;;;::::1;;;:22;67001:50;;;;-1:-1:-1::0;;;67001:50:0::1;;;;;;;:::i;:::-;67060:13;:20:::0;;-1:-1:-1;;67060:20:0::1;::::0;::::1;::::0;;;67100:19:::1;:17;:19::i;:::-;67130:5;:7:::0;;67085:34;;-1:-1:-1;67130:5:0::1;:7;::::0;::::1;:::i;:::-;;;;;;67148:30;67158:10;67170:7;67148:9;:30::i;:::-;-1:-1:-1::0;27736:1:0;28688:7;:22;66894:292::o;40746:239::-;40818:7;40854:16;;;:7;:16;;;;;;-1:-1:-1;;;;;40854:16:0;40889:19;40881:73;;;;-1:-1:-1;;;40881:73:0;;17541:2:1;40881:73:0;;;17523:21:1;17580:2;17560:18;;;17553:30;17619:34;17599:18;;;17592:62;-1:-1:-1;;;17670:18:1;;;17663:39;17719:19;;40881:73:0;17339:405:1;64761:344:0;64826:13;64860:16;64868:7;64860;:16::i;:::-;64852:46;;;;-1:-1:-1;;;64852:46:0;;;;;;;:::i;:::-;64978:12;;65030:38;;-1:-1:-1;;;65030:38:0;;;;;10301:25:1;;;64913:20:0;;-1:-1:-1;;;;;64978:12:0;;65015:14;;64978:12;;65030:29;;10274:18:1;;65030:38:0;10155:177:1;65991:118:0;24920:6;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;66071:16:::1;:30:::0;;-1:-1:-1;;;;;;66071:30:0::1;-1:-1:-1::0;;;;;66071:30:0;;;::::1;::::0;;;::::1;::::0;;65991:118::o;64405:350::-;64472:13;64506:16;64514:7;64506;:16::i;:::-;64498:46;;;;-1:-1:-1;;;64498:46:0;;;;;;;:::i;:::-;64624:12;;64678:40;;-1:-1:-1;;;64678:40:0;;;;;10301:25:1;;;64559:20:0;;-1:-1:-1;;;;;64624:12:0;;64661:16;;64624:12;;64678:31;;10274:18:1;;64678:40:0;10155:177:1;66218:106:0;24920:6;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;66301:15:::1;::::0;;-1:-1:-1;;66282:34:0;::::1;66301:15;::::0;;::::1;66300:16;66282:34;::::0;;66218:106::o;40476:208::-;40548:7;-1:-1:-1;;;;;40576:19:0;;40568:74;;;;-1:-1:-1;;;40568:74:0;;17130:2:1;40568:74:0;;;17112:21:1;17169:2;17149:18;;;17142:30;17208:34;17188:18;;;17181:62;-1:-1:-1;;;17259:18:1;;;17252:40;17309:19;;40568:74:0;16928:406:1;40568:74:0;-1:-1:-1;;;;;;40660:16:0;;;;;:9;:16;;;;;;;40476:208::o;25498:94::-;24920:6;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;25563:21:::1;25581:1;25563:9;:21::i;:::-;25498:94::o:0;72062:113::-;24920:6;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;72115:51:::1;::::0;72123:10:::1;::::0;72144:21:::1;72115:51:::0;::::1;;;::::0;::::1;::::0;;;72144:21;72123:10;72115:51;::::1;;;;;;;;;;;;;::::0;::::1;;;;;;72062:113::o:0;69587:102::-;24920:6;;69645:4;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;-1:-1:-1;69669:12:0::1;::::0;69587:102;:::o;65749:116::-;24920:6;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;65828:15:::1;:29:::0;;-1:-1:-1;;;;;65828:29:0;;::::1;::::0;::::1;-1:-1:-1::0;;;;;;65828:29:0;;::::1;::::0;;;::::1;::::0;;65749:116::o;15512:210::-;15605:10;-1:-1:-1;;;;;15619:14:0;15605:28;;15597:72;;;;-1:-1:-1;;;15597:72:0;;20600:2:1;15597:72:0;;;20582:21:1;20639:2;20619:18;;;20612:30;20678:33;20658:18;;;20651:61;20729:18;;15597:72:0;20398:355:1;15597:72:0;69548:12;:25;-1:-1:-1;65243:102:0:o;41221:104::-;41277:13;41310:7;41303:14;;;;;:::i;42874:295::-;-1:-1:-1;;;;;42977:24:0;;23801:10;42977:24;;42969:62;;;;-1:-1:-1;;;42969:62:0;;14888:2:1;42969:62:0;;;14870:21:1;14927:2;14907:18;;;14900:30;14966:27;14946:18;;;14939:55;15011:18;;42969:62:0;14686:349:1;42969:62:0;23801:10;43044:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;43044:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;43044:53:0;;;;;;;;;;43113:48;;10103:41:1;;;43044:42:0;;23801:10;43113:48;;10076:18:1;43113:48:0;;;;;;;42874:295;;:::o;66341:244::-;24920:6;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;27780:1:::1;28376:7;;:19;;28368:63;;;;-1:-1:-1::0;;;28368:63:0::1;;;;;;;:::i;:::-;27780:1;28509:7;:18:::0;66409:14:::2;::::0;::::2;::::0;::::2;;;:23;66401:51;;;;-1:-1:-1::0;;;66401:51:0::2;;;;;;;:::i;:::-;66461:14;:21:::0;;-1:-1:-1;;66461:21:0::2;;;::::0;;;66502:19:::2;:17;:19::i;:::-;66532:5;:7:::0;;66487:34;;-1:-1:-1;66532:5:0::2;:7;::::0;::::2;:::i;:::-;;;;;;66550:27;66560:7;24920:6:::0;;-1:-1:-1;;;;;24920:6:0;;24847:87;66591:297;27780:1;28376:7;;:19;;28368:63;;;;-1:-1:-1;;;28368:63:0;;;;;;;:::i;:::-;27780:1;28509:7;:18;66663:15:::1;::::0;;;::::1;-1:-1:-1::0;;;;;66663:15:0::1;66649:10;:29;66641:55;;;::::0;-1:-1:-1;;;66641:55:0;;18355:2:1;66641:55:0::1;::::0;::::1;18337:21:1::0;18394:2;18374:18;;;18367:30;-1:-1:-1;;;18413:18:1;;;18406:43;18466:18;;66641:55:0::1;18153:337:1::0;66641:55:0::1;66709:14;::::0;;;::::1;;;:23;66701:51;;;;-1:-1:-1::0;;;66701:51:0::1;;;;;;;:::i;:::-;66761:14;:21:::0;;-1:-1:-1;;66761:21:0::1;::::0;::::1;::::0;;;66802:19:::1;:17;:19::i;44137:328::-:0;44312:41;23801:10;44345:7;44312:18;:41::i;:::-;44304:103;;;;-1:-1:-1;;;44304:103:0;;;;;;;:::i;:::-;44418:39;44432:4;44438:2;44442:7;44451:5;44418:13;:39::i;:::-;44137:328;;;;:::o;65479:264::-;65542:13;65576:17;65584:8;65576:7;:17::i;:::-;65568:59;;;;-1:-1:-1;;;65568:59:0;;19058:2:1;65568:59:0;;;19040:21:1;19097:2;19077:18;;;19070:30;19136:31;19116:18;;;19109:59;19185:18;;65568:59:0;18856:353:1;65568:59:0;65669:12;65683:26;65700:8;65683:16;:26::i;:::-;65711:22;65652:82;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;65638:97;;65479:264;;;:::o;63705:341::-;63769:13;63803:16;63811:7;63803;:16::i;:::-;63795:46;;;;-1:-1:-1;;;63795:46:0;;;;;;;:::i;:::-;63921:12;;63972:37;;-1:-1:-1;;;63972:37:0;;;;;10301:25:1;;;63856:20:0;;-1:-1:-1;;;;;63921:12:0;;63958:13;;63921:12;;63972:28;;10274:18:1;;63972:37:0;10155:177:1;69245:205:0;24920:6;;69298:17;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;69369:3:::1;::::0;69336:29:::1;::::0;-1:-1:-1;;;69336:29:0;;69359:4:::1;69336:29;::::0;::::1;9018:51:1::0;69336:4:0::1;-1:-1:-1::0;;;;;69336:14:0::1;::::0;::::1;::::0;8991:18:1;;69336:29:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:36;;69328:65;;;::::0;-1:-1:-1;;;69328:65:0;;11798:2:1;69328:65:0::1;::::0;::::1;11780:21:1::0;11837:2;11817:18;;;11810:30;-1:-1:-1;;;11856:18:1;;;11849:46;11912:18;;69328:65:0::1;11596:340:1::0;69328:65:0::1;69411:31;69429:7;;69438:3;;69411:17;:31::i;:::-;69404:38;;69245:205:::0;:::o;25747:192::-;24920:6;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;25836:22:0;::::1;25828:73;;;::::0;-1:-1:-1;;;25828:73:0;;13378:2:1;25828:73:0::1;::::0;::::1;13360:21:1::0;13417:2;13397:18;;;13390:30;13456:34;13436:18;;;13429:62;-1:-1:-1;;;13507:18:1;;;13500:36;13553:19;;25828:73:0::1;13176:402:1::0;25828:73:0::1;25912:19;25922:8;25912:9;:19::i;65871:114::-:0;24920:6;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;65949:14:::1;:28:::0;;-1:-1:-1;;;;;;65949:28:0::1;-1:-1:-1::0;;;;;65949:28:0;;;::::1;::::0;;;::::1;::::0;;65871:114::o;67192:452::-;27780:1;28376:7;;:19;;28368:63;;;;-1:-1:-1;;;28368:63:0;;;;;;;:::i;:::-;27780:1;28509:7;:18;67295:16:::1;::::0;-1:-1:-1;;;;;67295:16:0::1;67281:10;:30;67273:63;;;::::0;-1:-1:-1;;;67273:63:0;;21362:2:1;67273:63:0::1;::::0;::::1;21344:21:1::0;21401:2;21381:18;;;21374:30;-1:-1:-1;;;21420:18:1;;;21413:50;21480:18;;67273:63:0::1;21160:344:1::0;67273:63:0::1;67349:15;::::0;;;::::1;;;:24;67341:52;;;;-1:-1:-1::0;;;67341:52:0::1;;;;;;;:::i;:::-;67402:15;:22:::0;;-1:-1:-1;;67402:22:0::1;::::0;::::1;::::0;;;67448:19:::1;:17;:19::i;:::-;67478:5;:7:::0;;67433:34;;-1:-1:-1;67478:5:0::1;:7;::::0;::::1;:::i;:::-;;;;;;67490:30;67500:10;67512:7;67490:9;:30::i;:::-;67529:19;67551;:17;:19::i;:::-;67581:5;:7:::0;;67529:41;;-1:-1:-1;67581:5:0::1;:7;::::0;::::1;:::i;:::-;;;;;;67599:37;67609:10;67621:14;67599:9;:37::i;:::-;-1:-1:-1::0;;27736:1:0;28688:7;:22;67192:452::o;65351:122::-;24920:6;;-1:-1:-1;;;;;24920:6:0;23801:10;25067:23;25059:68;;;;-1:-1:-1;;;25059:68:0;;;;;;;:::i;:::-;65436:29;;::::1;::::0;:22:::1;::::0;:29:::1;::::0;::::1;::::0;::::1;:::i;40107:305::-:0;40209:4;-1:-1:-1;;;;;;40246:40:0;;-1:-1:-1;;;40246:40:0;;:105;;-1:-1:-1;;;;;;;40303:48:0;;-1:-1:-1;;;40303:48:0;40246:105;:158;;;-1:-1:-1;;;;;;;;;;38823:40:0;;;40368:36;38714:157;45975:127;46040:4;46064:16;;;:7;:16;;;;;;-1:-1:-1;;;;;46064:16:0;:30;;;45975:127::o;49957:174::-;50032:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;50032:29:0;-1:-1:-1;;;;;50032:29:0;;;;;;;;:24;;50086:23;50032:24;50086:14;:23::i;:::-;-1:-1:-1;;;;;50077:46:0;;;;;;;;;;;49957:174;;:::o;46269:348::-;46362:4;46387:16;46395:7;46387;:16::i;:::-;46379:73;;;;-1:-1:-1;;;46379:73:0;;15242:2:1;46379:73:0;;;15224:21:1;15281:2;15261:18;;;15254:30;15320:34;15300:18;;;15293:62;-1:-1:-1;;;15371:18:1;;;15364:42;15423:19;;46379:73:0;15040:408:1;46379:73:0;46463:13;46479:23;46494:7;46479:14;:23::i;:::-;46463:39;;46532:5;-1:-1:-1;;;;;46521:16:0;:7;-1:-1:-1;;;;;46521:16:0;;:51;;;;46565:7;-1:-1:-1;;;;;46541:31:0;:20;46553:7;46541:11;:20::i;:::-;-1:-1:-1;;;;;46541:31:0;;46521:51;:87;;;-1:-1:-1;;;;;;43361:25:0;;;43337:4;43361:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;46576:32;46513:96;46269:348;-1:-1:-1;;;;46269:348:0:o;49261:578::-;49420:4;-1:-1:-1;;;;;49393:31:0;:23;49408:7;49393:14;:23::i;:::-;-1:-1:-1;;;;;49393:31:0;;49385:85;;;;-1:-1:-1;;;49385:85:0;;20190:2:1;49385:85:0;;;20172:21:1;20229:2;20209:18;;;20202:30;20268:34;20248:18;;;20241:62;-1:-1:-1;;;20319:18:1;;;20312:39;20368:19;;49385:85:0;19988:405:1;49385:85:0;-1:-1:-1;;;;;49489:16:0;;49481:65;;;;-1:-1:-1;;;49481:65:0;;14483:2:1;49481:65:0;;;14465:21:1;14522:2;14502:18;;;14495:30;14561:34;14541:18;;;14534:62;-1:-1:-1;;;14612:18:1;;;14605:34;14656:19;;49481:65:0;14281:400:1;49481:65:0;49559:39;49580:4;49586:2;49590:7;49559:20;:39::i;:::-;49663:29;49680:1;49684:7;49663:8;:29::i;:::-;-1:-1:-1;;;;;49705:15:0;;;;;;:9;:15;;;;;:20;;49724:1;;49705:15;:20;;49724:1;;49705:20;:::i;:::-;;;;-1:-1:-1;;;;;;;49736:13:0;;;;;;:9;:13;;;;;:18;;49753:1;;49736:13;:18;;49753:1;;49736:18;:::i;:::-;;;;-1:-1:-1;;49765:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;49765:21:0;-1:-1:-1;;;;;49765:21:0;;;;;;;;;49804:27;;49765:16;;49804:27;;;;;;;49261:578;;;:::o;1714:190::-;1839:4;1892;1863:25;1876:5;1883:4;1863:12;:25::i;:::-;:33;;1714:190;-1:-1:-1;;;;1714:190:0:o;70341:896::-;70388:4;70413:12;;70429:1;70413:17;;70405:65;;;;-1:-1:-1;;;70405:65:0;;12143:2:1;70405:65:0;;;12125:21:1;12182:2;12162:18;;;12155:30;12221:34;12201:18;;;12194:62;-1:-1:-1;;;12272:18:1;;;12265:33;12315:19;;70405:65:0;11941:399:1;70405:65:0;70481:21;70517:5;;61031:3;70505:17;;;;:::i;:::-;70481:41;-1:-1:-1;70604:14:0;70621:21;;:48;;70649:20;70668:1;70649:16;:20;:::i;:::-;70621:48;;;70645:1;70621:48;70752:12;;;70766:5;;70735:84;;70604:65;;-1:-1:-1;70707:10:0;;70824:16;;70735:84;;70752:12;70766:5;;;70773:10;;70785:16;;70803:15;;70735:84;;:::i;:::-;;;;;;;;;;;;;70725:95;;;;;;70720:101;;:120;;;;:::i;:::-;70707:133;;70857:12;70896:7;70904:5;70896:14;;;;;;;:::i;:::-;;;:43;;70934:5;70896:43;;;70918:7;70926:5;70918:14;;;;;;;:::i;:::-;;;70896:43;70886:53;;70967:7;70975:9;70967:18;;;;;;;:::i;:::-;;;:23;:56;;71005:7;71013:9;71005:18;;;;;;;:::i;:::-;;;70967:56;;;70993:9;70967:56;70950:7;70958:5;70950:14;;;;;;;:::i;:::-;;:73;71097:12;;;71111:5;;71080:84;;71036:16;;71170:2;;71080:84;;71097:12;;71111:5;;;;;71118:10;;71130:16;;71148:15;;71080:84;;:::i;:::-;;;;;;;;;;;;;71070:95;;;;;;71062:104;;71055:117;;;;:::i;:::-;71183:5;:18;;71036:136;;-1:-1:-1;71036:136:0;;71183:5;;:18;;71036:136;;71183:18;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;71222:7;71215:14;;;;;;;70341:896;:::o;46959:110::-;47035:26;47045:2;47049:7;47035:26;;;;;;;;;;;;:9;:26::i;25947:173::-;26022:6;;;-1:-1:-1;;;;;26039:17:0;;;-1:-1:-1;;;;;;26039:17:0;;;;;;;26072:40;;26022:6;;;26039:17;26022:6;;26072:40;;26003:16;;26072:40;25992:128;25947:173;:::o;45347:315::-;45504:28;45514:4;45520:2;45524:7;45504:9;:28::i;:::-;45551:48;45574:4;45580:2;45584:7;45593:5;45551:22;:48::i;:::-;45543:111;;;;-1:-1:-1;;;45543:111:0;;;;;;;:::i;21418:723::-;21474:13;21695:10;21691:53;;-1:-1:-1;;21722:10:0;;;;;;;;;;;;-1:-1:-1;;;21722:10:0;;;;;21418:723::o;21691:53::-;21769:5;21754:12;21810:78;21817:9;;21810:78;;21843:8;;;;:::i;:::-;;-1:-1:-1;21866:10:0;;-1:-1:-1;21874:2:0;21866:10;;:::i;:::-;;;21810:78;;;21898:19;21930:6;21920:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;21920:17:0;;21898:39;;21948:154;21955:10;;21948:154;;21982:11;21992:1;21982:11;;:::i;:::-;;-1:-1:-1;22051:10:0;22059:2;22051:5;:10;:::i;:::-;22038:24;;:2;:24;:::i;:::-;22025:39;;22008:6;22015;22008:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;22008:56:0;;;;;;;;-1:-1:-1;22079:11:0;22088:2;22079:11;;:::i;:::-;;;21948:154;;13629:1034;13706:17;13732:4;-1:-1:-1;;;;;13732:20:0;;13753:14;13769:4;13786:8;12459:1;13775:43;;;;;;;;10511:25:1;;;10567:2;10552:18;;10545:34;10499:2;10484:18;;10337:248;13775:43:0;;;;;;;;;;;;;13732:87;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;14054:15:0;14137:16;;;:6;:16;;;;;;;;;3916:51;;;;;10821:25:1;;;10862:18;;;10855:34;;;14130:4:0;10905:18:1;;;10898:60;10974:18;;;;10967:34;;;3916:51:0;;;;;;;;;;10793:19:1;;;;3916:51:0;;;3906:62;;;;;;;;;14591:16;;;;;;;:20;;14610:1;14591:20;:::i;:::-;14572:16;;;;:6;:16;;;;;:39;14625:32;14579:8;14649:7;4486:41;;;;;;;7534:19:1;;;;7569:12;;;7562:28;;;;4486:41:0;;;;;;;;;7606:12:1;;;;4486:41:0;;4476:52;;;;;;4366:168;55576:589;-1:-1:-1;;;;;55782:18:0;;55778:187;;55817:40;55849:7;56992:10;:17;;56965:24;;;;:15;:24;;;;;:44;;;57020:24;;;;;;;;;;;;56888:164;55817:40;55778:187;;;55887:2;-1:-1:-1;;;;;55879:10:0;:4;-1:-1:-1;;;;;55879:10:0;;55875:90;;55906:47;55939:4;55945:7;55906:32;:47::i;:::-;-1:-1:-1;;;;;55979:16:0;;55975:183;;56012:45;56049:7;56012:36;:45::i;55975:183::-;56085:4;-1:-1:-1;;;;;56079:10:0;:2;-1:-1:-1;;;;;56079:10:0;;56075:83;;56106:40;56134:2;56138:7;56106:27;:40::i;2266:701::-;2349:7;2392:4;2349:7;2407:523;2431:5;:12;2427:1;:16;2407:523;;;2465:20;2488:5;2494:1;2488:8;;;;;;;;:::i;:::-;;;;;;;2465:31;;2531:12;2515;:28;2511:408;;2668:44;;;;;;7534:19:1;;;7569:12;;;7562:28;;;7606:12;;2668:44:0;;;;;;;;;;;;2658:55;;;;;;2643:70;;2511:408;;;2858:44;;;;;;7534:19:1;;;7569:12;;;7562:28;;;7606:12;;2858:44:0;;;;;;;;;;;;2848:55;;;;;;2833:70;;2511:408;-1:-1:-1;2445:3:0;;;;:::i;:::-;;;;2407:523;;;-1:-1:-1;2947:12:0;2266:701;-1:-1:-1;;;2266:701:0:o;47296:321::-;47426:18;47432:2;47436:7;47426:5;:18::i;:::-;47477:54;47508:1;47512:2;47516:7;47525:5;47477:22;:54::i;:::-;47455:154;;;;-1:-1:-1;;;47455:154:0;;;;;;;:::i;50696:803::-;50851:4;-1:-1:-1;;;;;50872:13:0;;31219:20;31267:8;50868:624;;50908:72;;-1:-1:-1;;;50908:72:0;;-1:-1:-1;;;;;50908:36:0;;;;;:72;;23801:10;;50959:4;;50965:7;;50974:5;;50908:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;50908:72:0;;;;;;;;-1:-1:-1;;50908:72:0;;;;;;;;;;;;:::i;:::-;;;50904:533;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;51154:13:0;;51150:272;;51197:60;;-1:-1:-1;;;51197:60:0;;;;;;;:::i;51150:272::-;51372:6;51366:13;51357:6;51353:2;51349:15;51342:38;50904:533;-1:-1:-1;;;;;;51031:55:0;-1:-1:-1;;;51031:55:0;;-1:-1:-1;51024:62:0;;50868:624;-1:-1:-1;51476:4:0;50696:803;;;;;;:::o;57679:988::-;57945:22;57995:1;57970:22;57987:4;57970:16;:22::i;:::-;:26;;;;:::i;:::-;58007:18;58028:26;;;:17;:26;;;;;;57945:51;;-1:-1:-1;58161:28:0;;;58157:328;;-1:-1:-1;;;;;58228:18:0;;58206:19;58228:18;;;:12;:18;;;;;;;;:34;;;;;;;;;58279:30;;;;;;:44;;;58396:30;;:17;:30;;;;;:43;;;58157:328;-1:-1:-1;58581:26:0;;;;:17;:26;;;;;;;;58574:33;;;-1:-1:-1;;;;;58625:18:0;;;;;:12;:18;;;;;:34;;;;;;;58618:41;57679:988::o;58962:1079::-;59240:10;:17;59215:22;;59240:21;;59260:1;;59240:21;:::i;:::-;59272:18;59293:24;;;:15;:24;;;;;;59666:10;:26;;59215:46;;-1:-1:-1;59293:24:0;;59215:46;;59666:26;;;;;;:::i;:::-;;;;;;;;;59644:48;;59730:11;59705:10;59716;59705:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;59810:28;;;:15;:28;;;;;;;:41;;;59982:24;;;;;59975:31;60017:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;59033:1008;;;58962:1079;:::o;56466:221::-;56551:14;56568:20;56585:2;56568:16;:20::i;:::-;-1:-1:-1;;;;;56599:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;56644:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;56466:221:0:o;47953:382::-;-1:-1:-1;;;;;48033:16:0;;48025:61;;;;-1:-1:-1;;;48025:61:0;;18697:2:1;48025:61:0;;;18679:21:1;;;18716:18;;;18709:30;18775:34;18755:18;;;18748:62;18827:18;;48025:61:0;18495:356:1;48025:61:0;48106:16;48114:7;48106;:16::i;:::-;48105:17;48097:58;;;;-1:-1:-1;;;48097:58:0;;13785:2:1;48097:58:0;;;13767:21:1;13824:2;13804:18;;;13797:30;13863;13843:18;;;13836:58;13911:18;;48097:58:0;13583:352:1;48097:58:0;48168:45;48197:1;48201:2;48205:7;48168:20;:45::i;:::-;-1:-1:-1;;;;;48226:13:0;;;;;;:9;:13;;;;;:18;;48243:1;;48226:13;:18;;48243:1;;48226:18;:::i;:::-;;;;-1:-1:-1;;48255:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;48255:21:0;-1:-1:-1;;;;;48255:21:0;;;;;;;;48294:33;;48255:16;;;48294:33;;48255:16;;48294:33;47953:382;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:406:1;78:5;112:18;104:6;101:30;98:56;;;134:18;;:::i;:::-;172:57;217:2;196:15;;-1:-1:-1;;192:29:1;223:4;188:40;172:57;:::i;:::-;163:66;;252:6;245:5;238:21;292:3;283:6;278:3;274:16;271:25;268:45;;;309:1;306;299:12;268:45;358:6;353:3;346:4;339:5;335:16;322:43;412:1;405:4;396:6;389:5;385:18;381:29;374:40;14:406;;;;;:::o;425:173::-;493:20;;-1:-1:-1;;;;;542:31:1;;532:42;;522:70;;588:1;585;578:12;522:70;425:173;;;:::o;603:186::-;662:6;715:2;703:9;694:7;690:23;686:32;683:52;;;731:1;728;721:12;683:52;754:29;773:9;754:29;:::i;:::-;744:39;603:186;-1:-1:-1;;;603:186:1:o;794:260::-;862:6;870;923:2;911:9;902:7;898:23;894:32;891:52;;;939:1;936;929:12;891:52;962:29;981:9;962:29;:::i;:::-;952:39;;1010:38;1044:2;1033:9;1029:18;1010:38;:::i;:::-;1000:48;;794:260;;;;;:::o;1059:328::-;1136:6;1144;1152;1205:2;1193:9;1184:7;1180:23;1176:32;1173:52;;;1221:1;1218;1211:12;1173:52;1244:29;1263:9;1244:29;:::i;:::-;1234:39;;1292:38;1326:2;1315:9;1311:18;1292:38;:::i;:::-;1282:48;;1377:2;1366:9;1362:18;1349:32;1339:42;;1059:328;;;;;:::o;1392:666::-;1487:6;1495;1503;1511;1564:3;1552:9;1543:7;1539:23;1535:33;1532:53;;;1581:1;1578;1571:12;1532:53;1604:29;1623:9;1604:29;:::i;:::-;1594:39;;1652:38;1686:2;1675:9;1671:18;1652:38;:::i;:::-;1642:48;;1737:2;1726:9;1722:18;1709:32;1699:42;;1792:2;1781:9;1777:18;1764:32;1819:18;1811:6;1808:30;1805:50;;;1851:1;1848;1841:12;1805:50;1874:22;;1927:4;1919:13;;1915:27;-1:-1:-1;1905:55:1;;1956:1;1953;1946:12;1905:55;1979:73;2044:7;2039:2;2026:16;2021:2;2017;2013:11;1979:73;:::i;:::-;1969:83;;;1392:666;;;;;;;:::o;2063:315::-;2128:6;2136;2189:2;2177:9;2168:7;2164:23;2160:32;2157:52;;;2205:1;2202;2195:12;2157:52;2228:29;2247:9;2228:29;:::i;:::-;2218:39;;2307:2;2296:9;2292:18;2279:32;2320:28;2342:5;2320:28;:::i;:::-;2367:5;2357:15;;;2063:315;;;;;:::o;2383:254::-;2451:6;2459;2512:2;2500:9;2491:7;2487:23;2483:32;2480:52;;;2528:1;2525;2518:12;2480:52;2551:29;2570:9;2551:29;:::i;:::-;2541:39;2627:2;2612:18;;;;2599:32;;-1:-1:-1;;;2383:254:1:o;2642:957::-;2726:6;2757:2;2800;2788:9;2779:7;2775:23;2771:32;2768:52;;;2816:1;2813;2806:12;2768:52;2856:9;2843:23;2885:18;2926:2;2918:6;2915:14;2912:34;;;2942:1;2939;2932:12;2912:34;2980:6;2969:9;2965:22;2955:32;;3025:7;3018:4;3014:2;3010:13;3006:27;2996:55;;3047:1;3044;3037:12;2996:55;3083:2;3070:16;3105:2;3101;3098:10;3095:36;;;3111:18;;:::i;:::-;3157:2;3154:1;3150:10;3140:20;;3180:28;3204:2;3200;3196:11;3180:28;:::i;:::-;3242:15;;;3273:12;;;;3305:11;;;3335;;;3331:20;;3328:33;-1:-1:-1;3325:53:1;;;3374:1;3371;3364:12;3325:53;3396:1;3387:10;;3406:163;3420:2;3417:1;3414:9;3406:163;;;3477:17;;3465:30;;3438:1;3431:9;;;;;3515:12;;;;3547;;3406:163;;;-1:-1:-1;3588:5:1;2642:957;-1:-1:-1;;;;;;;;2642:957:1:o;3604:245::-;3671:6;3724:2;3712:9;3703:7;3699:23;3695:32;3692:52;;;3740:1;3737;3730:12;3692:52;3772:9;3766:16;3791:28;3813:5;3791:28;:::i;3854:180::-;3913:6;3966:2;3954:9;3945:7;3941:23;3937:32;3934:52;;;3982:1;3979;3972:12;3934:52;-1:-1:-1;4005:23:1;;3854:180;-1:-1:-1;3854:180:1:o;4039:248::-;4107:6;4115;4168:2;4156:9;4147:7;4143:23;4139:32;4136:52;;;4184:1;4181;4174:12;4136:52;-1:-1:-1;;4207:23:1;;;4277:2;4262:18;;;4249:32;;-1:-1:-1;4039:248:1:o;4292:245::-;4350:6;4403:2;4391:9;4382:7;4378:23;4374:32;4371:52;;;4419:1;4416;4409:12;4371:52;4458:9;4445:23;4477:30;4501:5;4477:30;:::i;4542:249::-;4611:6;4664:2;4652:9;4643:7;4639:23;4635:32;4632:52;;;4680:1;4677;4670:12;4632:52;4712:9;4706:16;4731:30;4755:5;4731:30;:::i;4796:450::-;4865:6;4918:2;4906:9;4897:7;4893:23;4889:32;4886:52;;;4934:1;4931;4924:12;4886:52;4974:9;4961:23;5007:18;4999:6;4996:30;4993:50;;;5039:1;5036;5029:12;4993:50;5062:22;;5115:4;5107:13;;5103:27;-1:-1:-1;5093:55:1;;5144:1;5141;5134:12;5093:55;5167:73;5232:7;5227:2;5214:16;5209:2;5205;5201:11;5167:73;:::i;5436:184::-;5506:6;5559:2;5547:9;5538:7;5534:23;5530:32;5527:52;;;5575:1;5572;5565:12;5527:52;-1:-1:-1;5598:16:1;;5436:184;-1:-1:-1;5436:184:1:o;5625:273::-;5693:6;5746:2;5734:9;5725:7;5721:23;5717:32;5714:52;;;5762:1;5759;5752:12;5714:52;5794:9;5788:16;5844:4;5837:5;5833:16;5826:5;5823:27;5813:55;;5864:1;5861;5854:12;5903:257;5944:3;5982:5;5976:12;6009:6;6004:3;5997:19;6025:63;6081:6;6074:4;6069:3;6065:14;6058:4;6051:5;6047:16;6025:63;:::i;:::-;6142:2;6121:15;-1:-1:-1;;6117:29:1;6108:39;;;;6149:4;6104:50;;5903:257;-1:-1:-1;;5903:257:1:o;6165:973::-;6250:12;;6215:3;;6305:1;6325:18;;;;6378;;;;6405:61;;6459:4;6451:6;6447:17;6437:27;;6405:61;6485:2;6533;6525:6;6522:14;6502:18;6499:38;6496:161;;;6579:10;6574:3;6570:20;6567:1;6560:31;6614:4;6611:1;6604:15;6642:4;6639:1;6632:15;6496:161;6673:18;6700:104;;;;6818:1;6813:319;;;;6666:466;;6700:104;-1:-1:-1;;6733:24:1;;6721:37;;6778:16;;;;-1:-1:-1;6700:104:1;;6813:319;23921:1;23914:14;;;23958:4;23945:18;;6907:1;6921:165;6935:6;6932:1;6929:13;6921:165;;;7013:14;;7000:11;;;6993:35;7056:16;;;;6950:10;;6921:165;;;6925:3;;7115:6;7110:3;7106:16;7099:23;;6666:466;;;;;;;6165:973;;;;:::o;7881:456::-;8102:3;8130:38;8164:3;8156:6;8130:38;:::i;:::-;8197:6;8191:13;8213:52;8258:6;8254:2;8247:4;8239:6;8235:17;8213:52;:::i;:::-;8281:50;8323:6;8319:2;8315:15;8307:6;8281:50;:::i;:::-;8274:57;7881:456;-1:-1:-1;;;;;;;7881:456:1:o;8342:525::-;8581:19;;;8656:3;8634:16;;;;-1:-1:-1;;;;;;8630:43:1;8625:2;8616:12;;8609:65;8712:2;8708:15;;;;-1:-1:-1;;8704:53:1;8699:2;8690:12;;8683:75;8783:2;8774:12;;8767:28;8820:2;8811:12;;8804:28;8857:3;8848:13;;8342:525::o;9080:488::-;-1:-1:-1;;;;;9349:15:1;;;9331:34;;9401:15;;9396:2;9381:18;;9374:43;9448:2;9433:18;;9426:34;;;9496:3;9491:2;9476:18;;9469:31;;;9274:4;;9517:45;;9542:19;;9534:6;9517:45;:::i;:::-;9509:53;9080:488;-1:-1:-1;;;;;;9080:488:1:o;9573:385::-;9805:1;9801;9796:3;9792:11;9788:19;9780:6;9776:32;9765:9;9758:51;9845:6;9840:2;9829:9;9825:18;9818:34;9888:2;9883;9872:9;9868:18;9861:30;9739:4;9908:44;9948:2;9937:9;9933:18;9925:6;9908:44;:::i;:::-;9900:52;9573:385;-1:-1:-1;;;;;9573:385:1:o;11012:219::-;11161:2;11150:9;11143:21;11124:4;11181:44;11221:2;11210:9;11206:18;11198:6;11181:44;:::i;12757:414::-;12959:2;12941:21;;;12998:2;12978:18;;;12971:30;13037:34;13032:2;13017:18;;13010:62;-1:-1:-1;;;13103:2:1;13088:18;;13081:48;13161:3;13146:19;;12757:414::o;16232:341::-;16434:2;16416:21;;;16473:2;16453:18;;;16446:30;-1:-1:-1;;;16507:2:1;16492:18;;16485:47;16564:2;16549:18;;16232:341::o;19627:356::-;19829:2;19811:21;;;19848:18;;;19841:30;19907:34;19902:2;19887:18;;19880:62;19974:2;19959:18;;19627:356::o;21509:413::-;21711:2;21693:21;;;21750:2;21730:18;;;21723:30;21789:34;21784:2;21769:18;;21762:62;-1:-1:-1;;;21855:2:1;21840:18;;21833:47;21912:3;21897:19;;21509:413::o;22682:355::-;22884:2;22866:21;;;22923:2;22903:18;;;22896:30;22962:33;22957:2;22942:18;;22935:61;23028:2;23013:18;;22682:355::o;23042:339::-;23244:2;23226:21;;;23283:2;23263:18;;;23256:30;-1:-1:-1;;;23317:2:1;23302:18;;23295:45;23372:2;23357:18;;23042:339::o;23568:275::-;23639:2;23633:9;23704:2;23685:13;;-1:-1:-1;;23681:27:1;23669:40;;23739:18;23724:34;;23760:22;;;23721:62;23718:88;;;23786:18;;:::i;:::-;23822:2;23815:22;23568:275;;-1:-1:-1;23568:275:1:o;23974:128::-;24014:3;24045:1;24041:6;24038:1;24035:13;24032:39;;;24051:18;;:::i;:::-;-1:-1:-1;24087:9:1;;23974:128::o;24107:228::-;24146:3;24174:10;24211:2;24208:1;24204:10;24241:2;24238:1;24234:10;24272:3;24268:2;24264:12;24259:3;24256:21;24253:47;;;24280:18;;:::i;:::-;24316:13;;24107:228;-1:-1:-1;;;;24107:228:1:o;24340:120::-;24380:1;24406;24396:35;;24411:18;;:::i;:::-;-1:-1:-1;24445:9:1;;24340:120::o;24465:125::-;24505:4;24533:1;24530;24527:8;24524:34;;;24538:18;;:::i;:::-;-1:-1:-1;24575:9:1;;24465:125::o;24595:258::-;24667:1;24677:113;24691:6;24688:1;24685:13;24677:113;;;24767:11;;;24761:18;24748:11;;;24741:39;24713:2;24706:10;24677:113;;;24808:6;24805:1;24802:13;24799:48;;;-1:-1:-1;;24843:1:1;24825:16;;24818:27;24595:258::o;24858:380::-;24937:1;24933:12;;;;24980;;;25001:61;;25055:4;25047:6;25043:17;25033:27;;25001:61;25108:2;25100:6;25097:14;25077:18;25074:38;25071:161;;;25154:10;25149:3;25145:20;25142:1;25135:31;25189:4;25186:1;25179:15;25217:4;25214:1;25207:15;25071:161;;24858:380;;;:::o;25243:135::-;25282:3;-1:-1:-1;;25303:17:1;;25300:43;;;25323:18;;:::i;:::-;-1:-1:-1;25370:1:1;25359:13;;25243:135::o;25383:112::-;25415:1;25441;25431:35;;25446:18;;:::i;:::-;-1:-1:-1;25480:9:1;;25383:112::o;25500:183::-;25531:1;25557:10;25594:2;25591:1;25587:10;25616:3;25606:37;;25623:18;;:::i;:::-;25661:10;;25657:20;;;;;25500:183;-1:-1:-1;;25500:183:1:o;25688:127::-;25749:10;25744:3;25740:20;25737:1;25730:31;25780:4;25777:1;25770:15;25804:4;25801:1;25794:15;25820:127;25881:10;25876:3;25872:20;25869:1;25862:31;25912:4;25909:1;25902:15;25936:4;25933:1;25926:15;25952:127;26013:10;26008:3;26004:20;26001:1;25994:31;26044:4;26041:1;26034:15;26068:4;26065:1;26058:15;26084:127;26145:10;26140:3;26136:20;26133:1;26126:31;26176:4;26173:1;26166:15;26200:4;26197:1;26190:15;26216:127;26277:10;26272:3;26268:20;26265:1;26258:31;26308:4;26305:1;26298:15;26332:4;26329:1;26322:15;26348:118;26434:5;26427:13;26420:21;26413:5;26410:32;26400:60;;26456:1;26453;26446:12;26471:131;-1:-1:-1;;;;;;26545:32:1;;26535:43;;26525:71;;26592:1;26589;26582:12

Swarm Source

ipfs://622aee37c71a3534e9b98a0a595722189f668df9e79436d6f54f66939e712952
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.