ETH Price: $3,397.62 (+1.89%)

Token

Squirrelly Squirrels (SQRLY)
 

Overview

Max Total Supply

1,252 SQRLY

Holders

370

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
tims17.eth
Balance
3 SQRLY
0x7a8f94051c8a575f07d0f6e53c5f62b78d49f320
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:
SquirrellySquirrels

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-02-09
*/

// Sources flattened with hardhat v2.8.3 https://hardhat.org

// File @openzeppelin/contracts/utils/cryptography/[email protected]

// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/cryptography/MerkleProof.sol)

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

// File @openzeppelin/contracts/utils/[email protected]

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

pragma solidity ^0.8.0;

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

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

// File @openzeppelin/contracts/access/[email protected]

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

// File @chainlink/contracts/src/v0.8/interfaces/[email protected]

pragma solidity ^0.8.0;

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

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

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

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

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

  function increaseApproval(address spender, uint256 subtractedValue) external;

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

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

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

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

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

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

// File @chainlink/contracts/src/v0.8/[email protected]

pragma solidity ^0.8.0;

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

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

// File @chainlink/contracts/src/v0.8/[email protected]

pragma solidity ^0.8.0;

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

// File @openzeppelin/contracts/utils/introspection/[email protected]

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

pragma solidity ^0.8.0;

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

// File @openzeppelin/contracts/token/ERC721/[email protected]

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

// File @openzeppelin/contracts/token/ERC721/[email protected]

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

pragma solidity ^0.8.0;

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

// File @openzeppelin/contracts/token/ERC721/extensions/[email protected]

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

pragma solidity ^0.8.0;

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

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

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

// File @openzeppelin/contracts/token/ERC721/extensions/[email protected]

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

pragma solidity ^0.8.0;

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

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

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

// File @openzeppelin/contracts/utils/[email protected]

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

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File @openzeppelin/contracts/utils/[email protected]

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

pragma solidity ^0.8.0;

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

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

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

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

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

// File @openzeppelin/contracts/utils/introspection/[email protected]

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

pragma solidity ^0.8.0;

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

// File contracts/token/ERC721/ERC721.sol

// Creators: locationtba.eth, 2pmflow.eth

pragma solidity ^0.8.0;

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata and Enumerable extension. Built to optimize for lower gas during batch mints.
 *
 * Assumes serials are sequentially minted starting at 0 (e.g. 0, 1, 2, 3..).
 *
 * Does not support burning tokens to address(0).
 */
abstract contract ERC721 is
  Context,
  ERC165,
  IERC721,
  IERC721Metadata,
  IERC721Enumerable
{
  using Address for address;
  using Strings for uint256;

  struct TokenOwnership {
    address addr;
    uint64 startTimestamp;
  }

  struct AddressData {
    uint128 balance;
    uint128 numberMinted;
  }

  uint256 private currentIndex = 0;

  uint256 internal immutable maxBatchSize;

  // Token name
  string private _name;

  // Token symbol
  string private _symbol;

  // Mapping from token ID to ownership details
  // An empty struct value does not necessarily mean the token is unowned. See ownershipOf implementation for details.
  mapping(uint256 => TokenOwnership) private _ownerships;

  // Mapping owner address to address data
  mapping(address => AddressData) private _addressData;

  // 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
   * `maxBatchSize` refers to how much a minter can mint at a time.
   */
  constructor(
    string memory name_,
    string memory symbol_,
    uint256 maxBatchSize_
  ) {
    require(maxBatchSize_ > 0, "ERC721: max batch size must be nonzero");
    _name = name_;
    _symbol = symbol_;
    maxBatchSize = maxBatchSize_;
  }

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

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

  /**
   * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
   * This read function is O(totalSupply). If calling from a separate contract, be sure to test gas first.
   * It may also degrade with extremely large collection sizes (e.g >> 10000), test for your use case.
   */
  function tokenOfOwnerByIndex(address owner, uint256 index)
    public
    view
    override
    returns (uint256)
  {
    require(index < balanceOf(owner), "ERC721: owner index out of bounds");
    uint256 numMintedSoFar = totalSupply();
    uint256 tokenIdsIdx = 0;
    address currOwnershipAddr = address(0);
    for (uint256 i = 0; i < numMintedSoFar; i++) {
      TokenOwnership memory ownership = _ownerships[i];
      if (ownership.addr != address(0)) {
        currOwnershipAddr = ownership.addr;
      }
      if (currOwnershipAddr == owner) {
        if (tokenIdsIdx == index) {
          return i;
        }
        tokenIdsIdx++;
      }
    }
    revert("ERC721: unable to get token of owner by index");
  }

  /**
   * @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 ||
      interfaceId == type(IERC721Enumerable).interfaceId ||
      super.supportsInterface(interfaceId);
  }

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

  function _numberMinted(address owner) internal view returns (uint256) {
    require(
      owner != address(0),
      "ERC721: number minted query for the zero address"
    );
    return uint256(_addressData[owner].numberMinted);
  }

  function ownershipOf(uint256 tokenId)
    internal
    view
    returns (TokenOwnership memory)
  {
    require(_exists(tokenId), "ERC721: owner query for nonexistent token");

    uint256 lowestTokenToCheck;
    if (tokenId >= maxBatchSize) {
      lowestTokenToCheck = tokenId - maxBatchSize + 1;
    }

    for (uint256 curr = tokenId; curr >= lowestTokenToCheck; curr--) {
      TokenOwnership memory ownership = _ownerships[curr];
      if (ownership.addr != address(0)) {
        return ownership;
      }
    }

    revert("ERC721: unable to determine the owner of token");
  }

  /**
   * @dev See {IERC721-ownerOf}.
   */
  function ownerOf(uint256 tokenId) public view override returns (address) {
    return ownershipOf(tokenId).addr;
  }

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

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

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

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

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

  /**
   * @dev See {IERC721-approve}.
   */
  function approve(address to, uint256 tokenId) public 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, owner);
  }

  /**
   * @dev See {IERC721-getApproved}.
   */
  function getApproved(uint256 tokenId) public view 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 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 override {
    _transfer(from, to, tokenId);
  }

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

  /**
   * @dev See {IERC721-safeTransferFrom}.
   */
  function safeTransferFrom(
    address from,
    address to,
    uint256 tokenId,
    bytes memory _data
  ) public override {
    _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`),
   */
  function _exists(uint256 tokenId) internal view returns (bool) {
    return tokenId < currentIndex;
  }

  function _safeMint(address to, uint256 quantity) internal {
    _safeMint(to, quantity, "");
  }

  /**
   * @dev Mints `quantity` tokens and transfers them to `to`.
   *
   * Requirements:
   *
   * - `to` cannot be the zero address.
   * - `quantity` cannot be larger than the max batch size.
   *
   * Emits a {Transfer} event.
   */
  function _safeMint(
    address to,
    uint256 quantity,
    bytes memory _data
  ) internal {
    uint256 startTokenId = currentIndex;
    require(to != address(0), "ERC721: mint to the zero address");
    // We know if the first token in the batch doesn't exist, the other ones don't as well, because of serial ordering.
    require(!_exists(startTokenId), "ERC721: token already minted");
    require(quantity <= maxBatchSize, "ERC721: quantity to mint too high");

    _beforeTokenTransfers(address(0), to, startTokenId, quantity);

    AddressData memory addressData = _addressData[to];
    _addressData[to] = AddressData(
      addressData.balance + uint128(quantity),
      addressData.numberMinted + uint128(quantity)
    );
    _ownerships[startTokenId] = TokenOwnership(to, uint64(block.timestamp));

    uint256 updatedIndex = startTokenId;

    for (uint256 i = 0; i < quantity; i++) {
      emit Transfer(address(0), to, updatedIndex);
      require(
        _checkOnERC721Received(address(0), to, updatedIndex, _data),
        "ERC721: transfer to non ERC721Receiver implementer"
      );
      updatedIndex++;
    }

    currentIndex = updatedIndex;
    _afterTokenTransfers(address(0), to, startTokenId, quantity);
  }

  /**
   * @dev Transfers `tokenId` from `from` to `to`.
   *
   * 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
  ) private {
    TokenOwnership memory prevOwnership = ownershipOf(tokenId);

    bool isApprovedOrOwner = (_msgSender() == prevOwnership.addr ||
      getApproved(tokenId) == _msgSender() ||
      isApprovedForAll(prevOwnership.addr, _msgSender()));

    require(
      isApprovedOrOwner,
      "ERC721: transfer caller is not owner nor approved"
    );

    require(
      prevOwnership.addr == from,
      "ERC721: transfer from incorrect owner"
    );
    require(to != address(0), "ERC721: transfer to the zero address");

    _beforeTokenTransfers(from, to, tokenId, 1);

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

    _addressData[from].balance -= 1;
    _addressData[to].balance += 1;
    _ownerships[tokenId] = TokenOwnership(to, uint64(block.timestamp));

    // If the ownership slot of tokenId+1 is not explicitly set, that means the transfer initiator owns it.
    // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
    uint256 nextTokenId = tokenId + 1;
    if (_ownerships[nextTokenId].addr == address(0)) {
      if (_exists(nextTokenId)) {
        _ownerships[nextTokenId] = TokenOwnership(
          prevOwnership.addr,
          prevOwnership.startTimestamp
        );
      }
    }

    emit Transfer(from, to, tokenId);
    _afterTokenTransfers(from, to, tokenId, 1);
  }

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

  uint256 public nextOwnerToExplicitlySet = 0;

  /**
   * @dev Explicitly set `owners` to eliminate loops in future calls of ownerOf().
   */
  function _setOwnersExplicit(uint256 quantity) internal {
    uint256 oldNextOwnerToSet = nextOwnerToExplicitlySet;
    require(quantity > 0, "quantity must be nonzero");
    uint256 endIndex = oldNextOwnerToSet + quantity - 1;
    if (endIndex > currentIndex - 1) {
      endIndex = currentIndex - 1;
    }
    // We know if the last one in the group exists, all in the group exist, due to serial ordering.
    require(_exists(endIndex), "not enough minted yet for this cleanup");
    for (uint256 i = oldNextOwnerToSet; i <= endIndex; i++) {
      if (_ownerships[i].addr == address(0)) {
        TokenOwnership memory ownership = ownershipOf(i);
        _ownerships[i] = TokenOwnership(
          ownership.addr,
          ownership.startTimestamp
        );
      }
    }
    nextOwnerToExplicitlySet = endIndex + 1;
  }

  /**
   * @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 a set of serially-ordered token ids are about to be transferred. This includes minting.
   *
   * startTokenId - the first token id to be transferred
   * quantity - the amount to be transferred
   *
   * 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`.
   */
  function _beforeTokenTransfers(
    address from,
    address to,
    uint256 startTokenId,
    uint256 quantity
  ) internal virtual {}

  /**
   * @dev Hook that is called after a set of serially-ordered token ids have been transferred. This includes
   * minting.
   *
   * startTokenId - the first token id to be transferred
   * quantity - the amount to be transferred
   *
   * Calling conditions:
   *
   * - when `from` and `to` are both non-zero.
   * - `from` and `to` are never both zero.
   */
  function _afterTokenTransfers(
    address from,
    address to,
    uint256 startTokenId,
    uint256 quantity
  ) internal virtual {}
}

// File contracts/SquirrellySquirrels.sol

//                              ██
//                            ██
//                            ██
//                        ██████████
//                    ██████████████████
//                  ██████████████████████
//                  ██████████████████████
//                ██████████████████████████
//                  ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
//                  ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
//                  ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
//                  ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
//                  ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
//                  ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
//                  ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
//                  ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
//                    ▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒
//                      ▒▒▒▒▒▒▒▒▒▒▒▒▒▒
//                          ▒▒▒▒▒▒
//
//  ____   ___  _   _ ___ ____  ____  _____ _     _  __   __
// / ___| / _ \| | | |_ _|  _ \|  _ \| ____| |   | | \ \ / /
// \___ \| | | | | | || || |_) | |_) |  _| | |   | |  \ V /
//  ___) | |_| | |_| || ||  _ <|  _ <| |___| |___| |___| |
// |____/ \__\_\\___/|___|_| \_\_| \_\_____|_____|_____|_|
//
//    ____   ___  _   _ ___ ____  ____  _____ _     ____
//   / ___| / _ \| | | |_ _|  _ \|  _ \| ____| |   / ___|
//   \___ \| | | | | | || || |_) | |_) |  _| | |   \___ \
//    ___) | |_| | |_| || ||  _ <|  _ <| |___| |___ ___) |
//   |____/ \__\_\\___/|___|_| \_\_| \_\_____|_____|____/

pragma solidity ^0.8.0;

contract SquirrellySquirrels is VRFConsumerBase, ERC721, Ownable {
  using Strings for uint256;

  uint256 public constant NFT_1_PRICE = 0.16 ether;
  uint256 public constant NFT_3_PRICE = 0.39 ether;
  uint256 public constant NFT_5_PRICE = 0.45 ether;
  uint256 public constant MAX_NFT_PURCHASE_PRESALE = 5;
  uint256 public constant MAX_MINT_PER_TX = 5;
  uint256 public constant MAX_SUPPLY = 10000;

  bool public saleIsActive = false;
  bool public presaleIsActive = false;

  bool public revealed = false;

  uint256 public reserve = 300;
  uint256 public startingIndex;

  mapping(address => uint256) public allowListNumClaimed;
  bytes32 public allowListMerkleRoot;
  bytes32 public startingIndexRequestId;

  string public uriPrefix = "";
  string public uriSuffix = ".json";
  string public hiddenMetadataUri = "";
  string public provenance;

  string private _baseURIExtended;

  modifier mintCompliance(uint256 _numberOfTokens) {
    require(
      _numberOfTokens > 0 &&
        _numberOfTokens != 2 &&
        _numberOfTokens != 4 &&
        _numberOfTokens <= MAX_MINT_PER_TX,
      "Invalid mint amount"
    );

    require(
      (_numberOfTokens == 1 && msg.value == NFT_1_PRICE) ||
        (_numberOfTokens == 3 && msg.value == NFT_3_PRICE) ||
        (_numberOfTokens == 5 && msg.value == NFT_5_PRICE),
      "Sent ether value is incorrect"
    );

    _;
  }

  constructor(
    address _vrfCoordinator,
    address _link,
    address _owner
  )
    ERC721("Squirrelly Squirrels", "SQRLY", 300)
    VRFConsumerBase(_vrfCoordinator, _link)
  {
    transferOwnership(_owner);
  }

  function requestStartingIndex(bytes32 _keyHash, uint256 _fee)
    external
    onlyOwner
    returns (bytes32 requestId)
  {
    require(startingIndex == 0, "startingIndex has already been set");
    bytes32 _requestId = requestRandomness(_keyHash, _fee);
    startingIndexRequestId = _requestId;
    return _requestId;
  }

  function fulfillRandomness(bytes32 _requestId, uint256 _randomness)
    internal
    override
  {
    if (startingIndexRequestId == _requestId) {
      startingIndex = _randomness % MAX_SUPPLY;
    }
  }

  function claimReserve(address _to, uint256 _reserveAmount)
    external
    onlyOwner
  {
    require(
      _reserveAmount > 0 && _reserveAmount <= reserve,
      "Not enough reserve left for team"
    );

    reserve = reserve - _reserveAmount;

    _safeMint(_to, _reserveAmount);
  }

  function flipSaleState() external onlyOwner {
    saleIsActive = !saleIsActive;
  }

  function flipPresaleState() external onlyOwner {
    presaleIsActive = !presaleIsActive;
  }

  function isAllowListed(bytes32[] memory _proof, address _address)
    public
    view
    returns (bool)
  {
    require(_address != address(0), "Zero address not on Allow List");

    bytes32 leaf = keccak256(abi.encodePacked(_address));
    return MerkleProof.verify(_proof, allowListMerkleRoot, leaf);
  }

  function setAllowListMerkleRoot(bytes32 _allowListMerkleRoot)
    external
    onlyOwner
  {
    allowListMerkleRoot = _allowListMerkleRoot;
  }

  function mintPresale(bytes32[] memory _proof, uint256 _numberOfTokens)
    external
    payable
    mintCompliance(_numberOfTokens)
  {
    require(presaleIsActive, "Presale is not active at the moment");
    require(
      isAllowListed(_proof, msg.sender),
      "This address is not allow listed for the presale"
    );
    require(
      allowListNumClaimed[msg.sender] + _numberOfTokens <=
        MAX_NFT_PURCHASE_PRESALE,
      "Exceeds allowed presale you can mint"
    );
    require(
      totalSupply() + _numberOfTokens <= MAX_SUPPLY - reserve,
      "Purchase would exceed max supply"
    );

    _safeMint(msg.sender, _numberOfTokens);

    allowListNumClaimed[msg.sender] += _numberOfTokens;
  }

  function mint(uint256 _numberOfTokens)
    external
    payable
    mintCompliance(_numberOfTokens)
  {
    require(saleIsActive, "Sale is not active at the moment");
    require(
      totalSupply() + _numberOfTokens <= MAX_SUPPLY - reserve,
      "Purchase would exceed max supply"
    );

    _safeMint(msg.sender, _numberOfTokens);
  }

  function walletOfOwner(address _owner)
    external
    view
    returns (uint256[] memory)
  {
    uint256 ownerTokenCount = balanceOf(_owner);
    uint256[] memory ownedTokenIds = new uint256[](ownerTokenCount);

    for (uint256 i = 0; i < ownerTokenCount; i++) {
      ownedTokenIds[i] = tokenOfOwnerByIndex(_owner, i);
    }

    return ownedTokenIds;
  }

  function tokenURI(uint256 _tokenId)
    public
    view
    virtual
    override
    returns (string memory)
  {
    require(
      _exists(_tokenId),
      "ERC721Metadata: URI query for nonexistent token"
    );

    if (revealed == false) {
      return hiddenMetadataUri;
    }

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

  function setHiddenMetadataUri(string memory _hiddenMetadataUri)
    external
    onlyOwner
  {
    hiddenMetadataUri = _hiddenMetadataUri;
  }

  function setUriPrefix(string memory _uriPrefix) external onlyOwner {
    uriPrefix = _uriPrefix;
  }

  function setUriSuffix(string memory _uriSuffix) external onlyOwner {
    uriSuffix = _uriSuffix;
  }

  function setRevealed(bool _state) external onlyOwner {
    revealed = _state;
  }

  function setProvenance(string calldata _provenance) external onlyOwner {
    provenance = _provenance;
  }

  function withdraw() external onlyOwner {
    (bool os, ) = payable(owner()).call{ value: address(this).balance }("");
    require(os, "withdraw: transfer failed");
  }

  function _baseURI() internal view virtual override returns (string memory) {
    return uriPrefix;
  }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_vrfCoordinator","type":"address"},{"internalType":"address","name":"_link","type":"address"},{"internalType":"address","name":"_owner","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":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":[],"name":"MAX_MINT_PER_TX","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_NFT_PURCHASE_PRESALE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NFT_1_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NFT_3_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"NFT_5_PRICE","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"allowListMerkleRoot","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"allowListNumClaimed","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_reserveAmount","type":"uint256"}],"name":"claimReserve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flipPresaleState","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"flipSaleState","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":[],"name":"hiddenMetadataUri","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"},{"internalType":"address","name":"_address","type":"address"}],"name":"isAllowListed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_numberOfTokens","type":"uint256"}],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"bytes32[]","name":"_proof","type":"bytes32[]"},{"internalType":"uint256","name":"_numberOfTokens","type":"uint256"}],"name":"mintPresale","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"nextOwnerToExplicitlySet","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"presaleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"provenance","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"bytes32","name":"_keyHash","type":"bytes32"},{"internalType":"uint256","name":"_fee","type":"uint256"}],"name":"requestStartingIndex","outputs":[{"internalType":"bytes32","name":"requestId","type":"bytes32"}],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"reserve","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"revealed","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"saleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes32","name":"_allowListMerkleRoot","type":"bytes32"}],"name":"setAllowListMerkleRoot","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":"_hiddenMetadataUri","type":"string"}],"name":"setHiddenMetadataUri","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_provenance","type":"string"}],"name":"setProvenance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bool","name":"_state","type":"bool"}],"name":"setRevealed","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uriPrefix","type":"string"}],"name":"setUriPrefix","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_uriSuffix","type":"string"}],"name":"setUriSuffix","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startingIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startingIndexRequestId","outputs":[{"internalType":"bytes32","name":"","type":"bytes32"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uriPrefix","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"uriSuffix","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"walletOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

6000600181905560088190556009805462ffffff60a01b1916905561012c600a55610100604081905260e08290526200003c91600f9190620002ae565b5060408051808201909152600580825264173539b7b760d91b60209092019182526200006b91601091620002ae565b506040805160208101918290526000908190526200008c91601191620002ae565b503480156200009a57600080fd5b50604051620038d7380380620038d7833981016040819052620000bd9162000371565b604080518082018252601481527f537175697272656c6c7920537175697272656c73000000000000000000000000602080830191909152825180840190935260058352645351524c5960d81b908301526001600160601b0319606086811b821660a05285901b166080529061012c6200013a565b60405180910390fd5b82516200014f906002906020860190620002ae565b50815162000165906003906020850190620002ae565b5060c05250620001779050336200018b565b6200018281620001dd565b505050620003f7565b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6009546001600160a01b03163314620002395760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604482015260640162000131565b6001600160a01b038116620002a05760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b606482015260840162000131565b620002ab816200018b565b50565b828054620002bc90620003ba565b90600052602060002090601f016020900481019282620002e057600085556200032b565b82601f10620002fb57805160ff19168380011785556200032b565b828001600101855582156200032b579182015b828111156200032b5782518255916020019190600101906200030e565b50620003399291506200033d565b5090565b5b808211156200033957600081556001016200033e565b80516001600160a01b03811681146200036c57600080fd5b919050565b60008060006060848603121562000386578283fd5b620003918462000354565b9250620003a16020850162000354565b9150620003b16040850162000354565b90509250925092565b600181811c90821680620003cf57607f821691505b60208210811415620003f157634e487b7160e01b600052602260045260246000fd5b50919050565b60805160601c60a05160601c60c051613495620004426000396000818161222c0152818161225601526128450152600081816112fd01526123f4015260006123c501526134956000f3fe6080604052600436106103355760003560e01c8063715018a6116101ab578063b848d298116100f7578063e985e9c511610095578063f2fde38b1161006f578063f2fde38b1461090d578063f3b674a41461092d578063f81227d41461094d578063ffe630b51461096257600080fd5b8063e985e9c514610883578063ea7a42e4146108cc578063eb8d2444146108ec57600080fd5b8063cb774d47116100d1578063cb774d4714610821578063cd3293de14610837578063d7224ba01461084d578063e0a808531461086357600080fd5b8063b848d298146107c5578063b88d4fde146107e1578063c87b56dd1461080157600080fd5b80639bb906e011610164578063a22cb4651161013e578063a22cb4651461075d578063a45ba8e71461077d578063ad7f1ea114610792578063b806d11c146107a557600080fd5b80639bb906e014610734578063a06a513f146106ea578063a0712d681461074a57600080fd5b8063715018a6146106975780637ec4a659146106ac5780638da5cb5b146106cc5780638ecad721146106ea57806394985ddd146106ff57806395d89b411461071f57600080fd5b806334918dfd116102855780634fdd43cb116102235780635d6477f7116101fd5780635d6477f71461061557806362b99ad4146106425780636352211e1461065757806370a082311461067757600080fd5b80634fdd43cb146105bf57806351830227146105df5780635503a0e81461060057600080fd5b8063415013661161025f578063415013661461053c57806342842e0e14610552578063438b6300146105725780634f6ccce71461059f57600080fd5b806334918dfd146104f65780633ccfd60b1461050b578063412051591461052057600080fd5b80630f7309e8116102f257806323b872dd116102cc57806323b872dd1461047f5780632f745c591461049f57806330f72cd4146104bf57806332cb6b0c146104e057600080fd5b80630f7309e81461043557806316ba10e01461044a57806318160ddd1461046a57600080fd5b806301ffc9a71461033a57806306fdde031461036f578063081812fc14610391578063095ea7b3146103c957806309e62b91146103eb5780630bb8a33c1461040b575b600080fd5b34801561034657600080fd5b5061035a610355366004612f64565b610982565b60405190151581526020015b60405180910390f35b34801561037b57600080fd5b506103846109ef565b60405161036691906131ec565b34801561039d57600080fd5b506103b16103ac366004612f2b565b610a81565b6040516001600160a01b039091168152602001610366565b3480156103d557600080fd5b506103e96103e4366004612e46565b610b10565b005b3480156103f757600080fd5b506103e9610406366004612e46565b610c27565b34801561041757600080fd5b506104276702386f26fc10000081565b604051908152602001610366565b34801561044157600080fd5b50610384610cce565b34801561045657600080fd5b506103e9610465366004613008565b610d5c565b34801561047657600080fd5b50600154610427565b34801561048b57600080fd5b506103e961049a366004612d5d565b610d99565b3480156104ab57600080fd5b506104276104ba366004612e46565b610da4565b3480156104cb57600080fd5b5060095461035a90600160a81b900460ff1681565b3480156104ec57600080fd5b5061042761271081565b34801561050257600080fd5b506103e9610f1a565b34801561051757600080fd5b506103e9610f65565b34801561052c57600080fd5b5061042767063eb89da4ed000081565b34801561054857600080fd5b50610427600e5481565b34801561055e57600080fd5b506103e961056d366004612d5d565b611046565b34801561057e57600080fd5b5061059261058d366004612d11565b611061565b60405161036691906131a8565b3480156105ab57600080fd5b506104276105ba366004612f2b565b61111e565b3480156105cb57600080fd5b506103e96105da366004613008565b611186565b3480156105eb57600080fd5b5060095461035a90600160b01b900460ff1681565b34801561060c57600080fd5b506103846111c3565b34801561062157600080fd5b50610427610630366004612d11565b600c6020526000908152604090205481565b34801561064e57600080fd5b506103846111d0565b34801561066357600080fd5b506103b1610672366004612f2b565b6111dd565b34801561068357600080fd5b50610427610692366004612d11565b6111ef565b3480156106a357600080fd5b506103e961127f565b3480156106b857600080fd5b506103e96106c7366004613008565b6112b5565b3480156106d857600080fd5b506009546001600160a01b03166103b1565b3480156106f657600080fd5b50610427600581565b34801561070b57600080fd5b506103e961071a366004612f43565b6112f2565b34801561072b57600080fd5b50610384611374565b34801561074057600080fd5b50610427600d5481565b6103e9610758366004612f2b565b611383565b34801561076957600080fd5b506103e9610778366004612e10565b611562565b34801561078957600080fd5b50610384611627565b6103e96107a0366004612eb1565b611634565b3480156107b157600080fd5b506104276107c0366004612f43565b61192f565b3480156107d157600080fd5b506104276705698eef0667000081565b3480156107ed57600080fd5b506103e96107fc366004612d98565b6119d0565b34801561080d57600080fd5b5061038461081c366004612f2b565b611a09565b34801561082d57600080fd5b50610427600b5481565b34801561084357600080fd5b50610427600a5481565b34801561085957600080fd5b5061042760085481565b34801561086f57600080fd5b506103e961087e366004612ef3565b611b7c565b34801561088f57600080fd5b5061035a61089e366004612d2b565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b3480156108d857600080fd5b506103e96108e7366004612f2b565b611bc4565b3480156108f857600080fd5b5060095461035a90600160a01b900460ff1681565b34801561091957600080fd5b506103e9610928366004612d11565b611bf3565b34801561093957600080fd5b5061035a610948366004612e6f565b611c8b565b34801561095957600080fd5b506103e9611d32565b34801561096e57600080fd5b506103e961097d366004612f9c565b611d7d565b60006001600160e01b031982166380ac58cd60e01b14806109b357506001600160e01b03198216635b5e139f60e01b145b806109ce57506001600160e01b0319821663780e9d6360e01b145b806109e957506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600280546109fe9061338f565b80601f0160208091040260200160405190810160405280929190818152602001828054610a2a9061338f565b8015610a775780601f10610a4c57610100808354040283529160200191610a77565b820191906000526020600020905b815481529060010190602001808311610a5a57829003601f168201915b5050505050905090565b6000610a8e826001541190565b610af45760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600660205260409020546001600160a01b031690565b6000610b1b826111dd565b9050806001600160a01b0316836001600160a01b03161415610b895760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610aeb565b336001600160a01b0382161480610ba55750610ba5813361089e565b610c175760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610aeb565b610c22838383611db3565b505050565b6009546001600160a01b03163314610c515760405162461bcd60e51b8152600401610aeb90613251565b600081118015610c635750600a548111155b610caf5760405162461bcd60e51b815260206004820181905260248201527f4e6f7420656e6f7567682072657365727665206c65667420666f72207465616d6044820152606401610aeb565b80600a54610cbd9190613335565b600a55610cca8282611e0f565b5050565b60128054610cdb9061338f565b80601f0160208091040260200160405190810160405280929190818152602001828054610d079061338f565b8015610d545780601f10610d2957610100808354040283529160200191610d54565b820191906000526020600020905b815481529060010190602001808311610d3757829003601f168201915b505050505081565b6009546001600160a01b03163314610d865760405162461bcd60e51b8152600401610aeb90613251565b8051610cca906010906020840190612b13565b610c22838383611e29565b6000610daf836111ef565b8210610e075760405162461bcd60e51b815260206004820152602160248201527f4552433732313a206f776e657220696e646578206f7574206f6620626f756e646044820152607360f81b6064820152608401610aeb565b6000610e1260015490565b905060008060005b83811015610ebb576000818152600460209081526040918290208251808401909352546001600160a01b038116808452600160a01b9091046001600160401b03169183019190915215610e6c57805192505b876001600160a01b0316836001600160a01b03161415610ea85786841415610e9a575093506109e992505050565b83610ea4816133ca565b9450505b5080610eb3816133ca565b915050610e1a565b5060405162461bcd60e51b815260206004820152602d60248201527f4552433732313a20756e61626c6520746f2067657420746f6b656e206f66206f60448201526c0eedccae440c4f240d2dcc8caf609b1b6064820152608401610aeb565b6009546001600160a01b03163314610f445760405162461bcd60e51b8152600401610aeb90613251565b6009805460ff60a01b198116600160a01b9182900460ff1615909102179055565b6009546001600160a01b03163314610f8f5760405162461bcd60e51b8152600401610aeb90613251565b6000610fa36009546001600160a01b031690565b6001600160a01b03164760405160006040518083038185875af1925050503d8060008114610fed576040519150601f19603f3d011682016040523d82523d6000602084013e610ff2565b606091505b50509050806110435760405162461bcd60e51b815260206004820152601960248201527f77697468647261773a207472616e73666572206661696c6564000000000000006044820152606401610aeb565b50565b610c22838383604051806020016040528060008152506119d0565b6060600061106e836111ef565b90506000816001600160401b0381111561109857634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156110c1578160200160208202803683370190505b50905060005b82811015611116576110d98582610da4565b8282815181106110f957634e487b7160e01b600052603260045260246000fd5b60209081029190910101528061110e816133ca565b9150506110c7565b509392505050565b600061112960015490565b82106111825760405162461bcd60e51b815260206004820152602260248201527f4552433732313a20676c6f62616c20696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610aeb565b5090565b6009546001600160a01b031633146111b05760405162461bcd60e51b8152600401610aeb90613251565b8051610cca906011906020840190612b13565b60108054610cdb9061338f565b600f8054610cdb9061338f565b60006111e8826121ab565b5192915050565b60006001600160a01b03821661125a5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610aeb565b506001600160a01b03166000908152600560205260409020546001600160801b031690565b6009546001600160a01b031633146112a95760405162461bcd60e51b8152600401610aeb90613251565b6112b36000612352565b565b6009546001600160a01b031633146112df5760405162461bcd60e51b8152600401610aeb90613251565b8051610cca90600f906020840190612b13565b336001600160a01b037f0000000000000000000000000000000000000000000000000000000000000000161461136a5760405162461bcd60e51b815260206004820152601f60248201527f4f6e6c7920565246436f6f7264696e61746f722063616e2066756c66696c6c006044820152606401610aeb565b610cca82826123a4565b6060600380546109fe9061338f565b80600081118015611395575080600214155b80156113a2575080600414155b80156113af575060058111155b6113f15760405162461bcd60e51b8152602060048201526013602482015272125b9d985b1a59081b5a5b9d08185b5bdd5b9d606a1b6044820152606401610aeb565b80600114801561140857506702386f26fc10000034145b80611425575080600314801561142557506705698eef0667000034145b806114425750806005148015611442575067063eb89da4ed000034145b61148e5760405162461bcd60e51b815260206004820152601d60248201527f53656e742065746865722076616c756520697320696e636f72726563740000006044820152606401610aeb565b600954600160a01b900460ff166114e75760405162461bcd60e51b815260206004820181905260248201527f53616c65206973206e6f742061637469766520617420746865206d6f6d656e746044820152606401610aeb565b600a546114f690612710613335565b8261150060015490565b61150a91906132e1565b11156115585760405162461bcd60e51b815260206004820181905260248201527f507572636861736520776f756c6420657863656564206d617820737570706c796044820152606401610aeb565b610cca3383611e0f565b6001600160a01b0382163314156115bb5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610aeb565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60118054610cdb9061338f565b80600081118015611646575080600214155b8015611653575080600414155b8015611660575060058111155b6116a25760405162461bcd60e51b8152602060048201526013602482015272125b9d985b1a59081b5a5b9d08185b5bdd5b9d606a1b6044820152606401610aeb565b8060011480156116b957506702386f26fc10000034145b806116d657508060031480156116d657506705698eef0667000034145b806116f357508060051480156116f3575067063eb89da4ed000034145b61173f5760405162461bcd60e51b815260206004820152601d60248201527f53656e742065746865722076616c756520697320696e636f72726563740000006044820152606401610aeb565b600954600160a81b900460ff166117a45760405162461bcd60e51b815260206004820152602360248201527f50726573616c65206973206e6f742061637469766520617420746865206d6f6d604482015262195b9d60ea1b6064820152608401610aeb565b6117ae8333611c8b565b6118135760405162461bcd60e51b815260206004820152603060248201527f546869732061646472657373206973206e6f7420616c6c6f77206c697374656460448201526f20666f72207468652070726573616c6560801b6064820152608401610aeb565b336000908152600c60205260409020546005906118319084906132e1565b111561188b5760405162461bcd60e51b8152602060048201526024808201527f4578636565647320616c6c6f7765642070726573616c6520796f752063616e206044820152631b5a5b9d60e21b6064820152608401610aeb565b600a5461189a90612710613335565b826118a460015490565b6118ae91906132e1565b11156118fc5760405162461bcd60e51b815260206004820181905260248201527f507572636861736520776f756c6420657863656564206d617820737570706c796044820152606401610aeb565b6119063383611e0f565b336000908152600c6020526040812080548492906119259084906132e1565b9091555050505050565b6009546000906001600160a01b0316331461195c5760405162461bcd60e51b8152600401610aeb90613251565b600b54156119b75760405162461bcd60e51b815260206004820152602260248201527f7374617274696e67496e6465782068617320616c7265616479206265656e2073604482015261195d60f21b6064820152608401610aeb565b60006119c384846123c1565b600e819055949350505050565b6119db848484611e29565b6119e784848484612547565b611a035760405162461bcd60e51b8152600401610aeb906131ff565b50505050565b6060611a16826001541190565b611a7a5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610aeb565b600954600160b01b900460ff16611b1d5760118054611a989061338f565b80601f0160208091040260200160405190810160405280929190818152602001828054611ac49061338f565b8015611b115780601f10611ae657610100808354040283529160200191611b11565b820191906000526020600020905b815481529060010190602001808311611af457829003601f168201915b50505050509050919050565b6000611b27612654565b90506000815111611b475760405180602001604052806000815250611b75565b80611b5184612663565b6010604051602001611b6593929190613079565b6040516020818303038152906040525b9392505050565b6009546001600160a01b03163314611ba65760405162461bcd60e51b8152600401610aeb90613251565b60098054911515600160b01b0260ff60b01b19909216919091179055565b6009546001600160a01b03163314611bee5760405162461bcd60e51b8152600401610aeb90613251565b600d55565b6009546001600160a01b03163314611c1d5760405162461bcd60e51b8152600401610aeb90613251565b6001600160a01b038116611c825760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610aeb565b61104381612352565b60006001600160a01b038216611ce35760405162461bcd60e51b815260206004820152601e60248201527f5a65726f2061646472657373206e6f74206f6e20416c6c6f77204c69737400006044820152606401610aeb565b6040516bffffffffffffffffffffffff19606084901b166020820152600090603401604051602081830303815290604052805190602001209050611d2a84600d548361277c565b949350505050565b6009546001600160a01b03163314611d5c5760405162461bcd60e51b8152600401610aeb90613251565b6009805460ff60a81b198116600160a81b9182900460ff1615909102179055565b6009546001600160a01b03163314611da75760405162461bcd60e51b8152600401610aeb90613251565b610c2260128383612b93565b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b610cca828260405180602001604052806000815250612792565b6000611e34826121ab565b80519091506000906001600160a01b0316336001600160a01b03161480611e6b575033611e6084610a81565b6001600160a01b0316145b80611e7d57508151611e7d903361089e565b905080611ee65760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6044820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b6064820152608401610aeb565b846001600160a01b031682600001516001600160a01b031614611f595760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610aeb565b6001600160a01b038416611fbb5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610aeb565b611fcb6000848460000151611db3565b6001600160a01b0385166000908152600560205260408120805460019290611ffd9084906001600160801b031661330d565b82546101009290920a6001600160801b038181021990931691831602179091556001600160a01b03861660009081526005602052604081208054600194509092612049918591166132b6565b82546001600160801b039182166101009390930a9283029190920219909116179055506040805180820182526001600160a01b0380871682526001600160401b03428116602080850191825260008981526004909152948520935184549151909216600160a01b026001600160e01b031990911691909216171790556120d08460016132e1565b6000818152600460205260409020549091506001600160a01b0316612161576120fa816001541190565b156121615760408051808201825284516001600160a01b0390811682526020808701516001600160401b039081168285019081526000878152600490935294909120925183549451909116600160a01b026001600160e01b03199094169116179190911790555b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b505050505050565b60408051808201909152600080825260208201526121ca826001541190565b6122285760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610aeb565b60007f000000000000000000000000000000000000000000000000000000000000000083106122895761227b7f000000000000000000000000000000000000000000000000000000000000000084613335565b6122869060016132e1565b90505b825b8181106122f2576000818152600460209081526040918290208251808401909352546001600160a01b038116808452600160a01b9091046001600160401b031691830191909152156122df57949350505050565b50806122ea81613378565b91505061228b565b5060405162461bcd60e51b815260206004820152602e60248201527f4552433732313a20756e61626c6520746f2064657465726d696e65207468652060448201526d37bbb732b91037b3103a37b5b2b760911b6064820152608401610aeb565b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b81600e541415610cca576123ba612710826133e5565b600b555050565b60007f00000000000000000000000000000000000000000000000000000000000000006001600160a01b0316634000aea07f000000000000000000000000000000000000000000000000000000000000000084866000604051602001612431929190918252602082015260400190565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161245e93929190613178565b602060405180830381600087803b15801561247857600080fd5b505af115801561248c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124b09190612f0f565b5060008381526020818152604080832054815180840188905280830185905230606082015260808082018390528351808303909101815260a09091019092528151918301919091208684529290915261250a9060016132e1565b6000858152602081815260409182902092909255805180830187905280820184905281518082038301815260609091019091528051910120611d2a565b60006001600160a01b0384163b1561264957604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061258b90339089908890889060040161313b565b602060405180830381600087803b1580156125a557600080fd5b505af19250505080156125d5575060408051601f3d908101601f191682019092526125d291810190612f80565b60015b61262f573d808015612603576040519150601f19603f3d011682016040523d82523d6000602084013e612608565b606091505b5080516126275760405162461bcd60e51b8152600401610aeb906131ff565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611d2a565b506001949350505050565b6060600f80546109fe9061338f565b6060816126875750506040805180820190915260018152600360fc1b602082015290565b8160005b81156126b1578061269b816133ca565b91506126aa9050600a836132f9565b915061268b565b6000816001600160401b038111156126d957634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612703576020820181803683370190505b5090505b8415611d2a57612718600183613335565b9150612725600a866133e5565b6127309060306132e1565b60f81b81838151811061275357634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350612775600a866132f9565b9450612707565b6000826127898584612a61565b14949350505050565b6001546001600160a01b0384166127eb5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610aeb565b6127f6816001541190565b156128435760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610aeb565b7f00000000000000000000000000000000000000000000000000000000000000008311156128bd5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a207175616e7469747920746f206d696e7420746f6f206869676044820152600d60fb1b6064820152608401610aeb565b6001600160a01b0384166000908152600560209081526040918290208251808401845290546001600160801b038082168352600160801b90910416918101919091528151808301909252805190919081906129199087906132b6565b6001600160801b0316815260200185836020015161293791906132b6565b6001600160801b039081169091526001600160a01b0380881660008181526005602090815260408083208751978301518716600160801b029790961696909617909455845180860186529182526001600160401b034281168386019081528883526004909552948120915182549451909516600160a01b026001600160e01b031990941694909216939093179190911790915582905b85811015612a565760405182906001600160a01b038916906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4612a1a6000888488612547565b612a365760405162461bcd60e51b8152600401610aeb906131ff565b81612a40816133ca565b9250508080612a4e906133ca565b9150506129cd565b5060018190556121a3565b600081815b8451811015611116576000858281518110612a9157634e487b7160e01b600052603260045260246000fd5b60200260200101519050808311612ad3576040805160208101859052908101829052606001604051602081830303815290604052805190602001209250612b00565b60408051602081018390529081018490526060016040516020818303038152906040528051906020012092505b5080612b0b816133ca565b915050612a66565b828054612b1f9061338f565b90600052602060002090601f016020900481019282612b415760008555612b87565b82601f10612b5a57805160ff1916838001178555612b87565b82800160010185558215612b87579182015b82811115612b87578251825591602001919060010190612b6c565b50611182929150612c07565b828054612b9f9061338f565b90600052602060002090601f016020900481019282612bc15760008555612b87565b82601f10612bda5782800160ff19823516178555612b87565b82800160010185558215612b87579182015b82811115612b87578235825591602001919060010190612bec565b5b808211156111825760008155600101612c08565b60006001600160401b03831115612c3557612c35613425565b612c48601f8401601f1916602001613286565b9050828152838383011115612c5c57600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b0381168114612c8a57600080fd5b919050565b600082601f830112612c9f578081fd5b813560206001600160401b03821115612cba57612cba613425565b8160051b612cc9828201613286565b838152828101908684018388018501891015612ce3578687fd5b8693505b85841015612d05578035835260019390930192918401918401612ce7565b50979650505050505050565b600060208284031215612d22578081fd5b611b7582612c73565b60008060408385031215612d3d578081fd5b612d4683612c73565b9150612d5460208401612c73565b90509250929050565b600080600060608486031215612d71578081fd5b612d7a84612c73565b9250612d8860208501612c73565b9150604084013590509250925092565b60008060008060808587031215612dad578081fd5b612db685612c73565b9350612dc460208601612c73565b92506040850135915060608501356001600160401b03811115612de5578182fd5b8501601f81018713612df5578182fd5b612e0487823560208401612c1c565b91505092959194509250565b60008060408385031215612e22578182fd5b612e2b83612c73565b91506020830135612e3b8161343b565b809150509250929050565b60008060408385031215612e58578182fd5b612e6183612c73565b946020939093013593505050565b60008060408385031215612e81578182fd5b82356001600160401b03811115612e96578283fd5b612ea285828601612c8f565b925050612d5460208401612c73565b60008060408385031215612ec3578182fd5b82356001600160401b03811115612ed8578283fd5b612ee485828601612c8f565b95602094909401359450505050565b600060208284031215612f04578081fd5b8135611b758161343b565b600060208284031215612f20578081fd5b8151611b758161343b565b600060208284031215612f3c578081fd5b5035919050565b60008060408385031215612f55578182fd5b50508035926020909101359150565b600060208284031215612f75578081fd5b8135611b7581613449565b600060208284031215612f91578081fd5b8151611b7581613449565b60008060208385031215612fae578182fd5b82356001600160401b0380821115612fc4578384fd5b818501915085601f830112612fd7578384fd5b813581811115612fe5578485fd5b866020828501011115612ff6578485fd5b60209290920196919550909350505050565b600060208284031215613019578081fd5b81356001600160401b0381111561302e578182fd5b8201601f8101841361303e578182fd5b611d2a84823560208401612c1c565b6000815180845261306581602086016020860161334c565b601f01601f19169290920160200192915050565b60008451602061308c8285838a0161334c565b85519184019161309f8184848a0161334c565b85549201918390600181811c90808316806130bb57607f831692505b8583108114156130d957634e487b7160e01b88526022600452602488fd5b8080156130ed57600181146130fe5761312a565b60ff1985168852838801955061312a565b60008b815260209020895b858110156131225781548a820152908401908801613109565b505083880195505b50939b9a5050505050505050505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061316e9083018461304d565b9695505050505050565b60018060a01b038416815282602082015260606040820152600061319f606083018461304d565b95945050505050565b6020808252825182820181905260009190848201906040850190845b818110156131e0578351835292840192918401916001016131c4565b50909695505050505050565b602081526000611b75602083018461304d565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b604051601f8201601f191681016001600160401b03811182821017156132ae576132ae613425565b604052919050565b60006001600160801b038083168185168083038211156132d8576132d86133f9565b01949350505050565b600082198211156132f4576132f46133f9565b500190565b6000826133085761330861340f565b500490565b60006001600160801b038381169083168181101561332d5761332d6133f9565b039392505050565b600082821015613347576133476133f9565b500390565b60005b8381101561336757818101518382015260200161334f565b83811115611a035750506000910152565b600081613387576133876133f9565b506000190190565b600181811c908216806133a357607f821691505b602082108114156133c457634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156133de576133de6133f9565b5060010190565b6000826133f4576133f461340f565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b801515811461104357600080fd5b6001600160e01b03198116811461104357600080fdfea264697066735822122087aa85241c1a85e9fa2a9ac9a59f2893feca7091f47a2591a196718ab8f159dd64736f6c63430008040033000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb7952000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca000000000000000000000000d3d114775f17f0d10d2bbb81c3a1c36e95d2bd73

Deployed Bytecode

0x6080604052600436106103355760003560e01c8063715018a6116101ab578063b848d298116100f7578063e985e9c511610095578063f2fde38b1161006f578063f2fde38b1461090d578063f3b674a41461092d578063f81227d41461094d578063ffe630b51461096257600080fd5b8063e985e9c514610883578063ea7a42e4146108cc578063eb8d2444146108ec57600080fd5b8063cb774d47116100d1578063cb774d4714610821578063cd3293de14610837578063d7224ba01461084d578063e0a808531461086357600080fd5b8063b848d298146107c5578063b88d4fde146107e1578063c87b56dd1461080157600080fd5b80639bb906e011610164578063a22cb4651161013e578063a22cb4651461075d578063a45ba8e71461077d578063ad7f1ea114610792578063b806d11c146107a557600080fd5b80639bb906e014610734578063a06a513f146106ea578063a0712d681461074a57600080fd5b8063715018a6146106975780637ec4a659146106ac5780638da5cb5b146106cc5780638ecad721146106ea57806394985ddd146106ff57806395d89b411461071f57600080fd5b806334918dfd116102855780634fdd43cb116102235780635d6477f7116101fd5780635d6477f71461061557806362b99ad4146106425780636352211e1461065757806370a082311461067757600080fd5b80634fdd43cb146105bf57806351830227146105df5780635503a0e81461060057600080fd5b8063415013661161025f578063415013661461053c57806342842e0e14610552578063438b6300146105725780634f6ccce71461059f57600080fd5b806334918dfd146104f65780633ccfd60b1461050b578063412051591461052057600080fd5b80630f7309e8116102f257806323b872dd116102cc57806323b872dd1461047f5780632f745c591461049f57806330f72cd4146104bf57806332cb6b0c146104e057600080fd5b80630f7309e81461043557806316ba10e01461044a57806318160ddd1461046a57600080fd5b806301ffc9a71461033a57806306fdde031461036f578063081812fc14610391578063095ea7b3146103c957806309e62b91146103eb5780630bb8a33c1461040b575b600080fd5b34801561034657600080fd5b5061035a610355366004612f64565b610982565b60405190151581526020015b60405180910390f35b34801561037b57600080fd5b506103846109ef565b60405161036691906131ec565b34801561039d57600080fd5b506103b16103ac366004612f2b565b610a81565b6040516001600160a01b039091168152602001610366565b3480156103d557600080fd5b506103e96103e4366004612e46565b610b10565b005b3480156103f757600080fd5b506103e9610406366004612e46565b610c27565b34801561041757600080fd5b506104276702386f26fc10000081565b604051908152602001610366565b34801561044157600080fd5b50610384610cce565b34801561045657600080fd5b506103e9610465366004613008565b610d5c565b34801561047657600080fd5b50600154610427565b34801561048b57600080fd5b506103e961049a366004612d5d565b610d99565b3480156104ab57600080fd5b506104276104ba366004612e46565b610da4565b3480156104cb57600080fd5b5060095461035a90600160a81b900460ff1681565b3480156104ec57600080fd5b5061042761271081565b34801561050257600080fd5b506103e9610f1a565b34801561051757600080fd5b506103e9610f65565b34801561052c57600080fd5b5061042767063eb89da4ed000081565b34801561054857600080fd5b50610427600e5481565b34801561055e57600080fd5b506103e961056d366004612d5d565b611046565b34801561057e57600080fd5b5061059261058d366004612d11565b611061565b60405161036691906131a8565b3480156105ab57600080fd5b506104276105ba366004612f2b565b61111e565b3480156105cb57600080fd5b506103e96105da366004613008565b611186565b3480156105eb57600080fd5b5060095461035a90600160b01b900460ff1681565b34801561060c57600080fd5b506103846111c3565b34801561062157600080fd5b50610427610630366004612d11565b600c6020526000908152604090205481565b34801561064e57600080fd5b506103846111d0565b34801561066357600080fd5b506103b1610672366004612f2b565b6111dd565b34801561068357600080fd5b50610427610692366004612d11565b6111ef565b3480156106a357600080fd5b506103e961127f565b3480156106b857600080fd5b506103e96106c7366004613008565b6112b5565b3480156106d857600080fd5b506009546001600160a01b03166103b1565b3480156106f657600080fd5b50610427600581565b34801561070b57600080fd5b506103e961071a366004612f43565b6112f2565b34801561072b57600080fd5b50610384611374565b34801561074057600080fd5b50610427600d5481565b6103e9610758366004612f2b565b611383565b34801561076957600080fd5b506103e9610778366004612e10565b611562565b34801561078957600080fd5b50610384611627565b6103e96107a0366004612eb1565b611634565b3480156107b157600080fd5b506104276107c0366004612f43565b61192f565b3480156107d157600080fd5b506104276705698eef0667000081565b3480156107ed57600080fd5b506103e96107fc366004612d98565b6119d0565b34801561080d57600080fd5b5061038461081c366004612f2b565b611a09565b34801561082d57600080fd5b50610427600b5481565b34801561084357600080fd5b50610427600a5481565b34801561085957600080fd5b5061042760085481565b34801561086f57600080fd5b506103e961087e366004612ef3565b611b7c565b34801561088f57600080fd5b5061035a61089e366004612d2b565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b3480156108d857600080fd5b506103e96108e7366004612f2b565b611bc4565b3480156108f857600080fd5b5060095461035a90600160a01b900460ff1681565b34801561091957600080fd5b506103e9610928366004612d11565b611bf3565b34801561093957600080fd5b5061035a610948366004612e6f565b611c8b565b34801561095957600080fd5b506103e9611d32565b34801561096e57600080fd5b506103e961097d366004612f9c565b611d7d565b60006001600160e01b031982166380ac58cd60e01b14806109b357506001600160e01b03198216635b5e139f60e01b145b806109ce57506001600160e01b0319821663780e9d6360e01b145b806109e957506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600280546109fe9061338f565b80601f0160208091040260200160405190810160405280929190818152602001828054610a2a9061338f565b8015610a775780601f10610a4c57610100808354040283529160200191610a77565b820191906000526020600020905b815481529060010190602001808311610a5a57829003601f168201915b5050505050905090565b6000610a8e826001541190565b610af45760405162461bcd60e51b815260206004820152602c60248201527f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860448201526b34b9ba32b73a103a37b5b2b760a11b60648201526084015b60405180910390fd5b506000908152600660205260409020546001600160a01b031690565b6000610b1b826111dd565b9050806001600160a01b0316836001600160a01b03161415610b895760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b6064820152608401610aeb565b336001600160a01b0382161480610ba55750610ba5813361089e565b610c175760405162461bcd60e51b815260206004820152603860248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760448201527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006064820152608401610aeb565b610c22838383611db3565b505050565b6009546001600160a01b03163314610c515760405162461bcd60e51b8152600401610aeb90613251565b600081118015610c635750600a548111155b610caf5760405162461bcd60e51b815260206004820181905260248201527f4e6f7420656e6f7567682072657365727665206c65667420666f72207465616d6044820152606401610aeb565b80600a54610cbd9190613335565b600a55610cca8282611e0f565b5050565b60128054610cdb9061338f565b80601f0160208091040260200160405190810160405280929190818152602001828054610d079061338f565b8015610d545780601f10610d2957610100808354040283529160200191610d54565b820191906000526020600020905b815481529060010190602001808311610d3757829003601f168201915b505050505081565b6009546001600160a01b03163314610d865760405162461bcd60e51b8152600401610aeb90613251565b8051610cca906010906020840190612b13565b610c22838383611e29565b6000610daf836111ef565b8210610e075760405162461bcd60e51b815260206004820152602160248201527f4552433732313a206f776e657220696e646578206f7574206f6620626f756e646044820152607360f81b6064820152608401610aeb565b6000610e1260015490565b905060008060005b83811015610ebb576000818152600460209081526040918290208251808401909352546001600160a01b038116808452600160a01b9091046001600160401b03169183019190915215610e6c57805192505b876001600160a01b0316836001600160a01b03161415610ea85786841415610e9a575093506109e992505050565b83610ea4816133ca565b9450505b5080610eb3816133ca565b915050610e1a565b5060405162461bcd60e51b815260206004820152602d60248201527f4552433732313a20756e61626c6520746f2067657420746f6b656e206f66206f60448201526c0eedccae440c4f240d2dcc8caf609b1b6064820152608401610aeb565b6009546001600160a01b03163314610f445760405162461bcd60e51b8152600401610aeb90613251565b6009805460ff60a01b198116600160a01b9182900460ff1615909102179055565b6009546001600160a01b03163314610f8f5760405162461bcd60e51b8152600401610aeb90613251565b6000610fa36009546001600160a01b031690565b6001600160a01b03164760405160006040518083038185875af1925050503d8060008114610fed576040519150601f19603f3d011682016040523d82523d6000602084013e610ff2565b606091505b50509050806110435760405162461bcd60e51b815260206004820152601960248201527f77697468647261773a207472616e73666572206661696c6564000000000000006044820152606401610aeb565b50565b610c22838383604051806020016040528060008152506119d0565b6060600061106e836111ef565b90506000816001600160401b0381111561109857634e487b7160e01b600052604160045260246000fd5b6040519080825280602002602001820160405280156110c1578160200160208202803683370190505b50905060005b82811015611116576110d98582610da4565b8282815181106110f957634e487b7160e01b600052603260045260246000fd5b60209081029190910101528061110e816133ca565b9150506110c7565b509392505050565b600061112960015490565b82106111825760405162461bcd60e51b815260206004820152602260248201527f4552433732313a20676c6f62616c20696e646578206f7574206f6620626f756e604482015261647360f01b6064820152608401610aeb565b5090565b6009546001600160a01b031633146111b05760405162461bcd60e51b8152600401610aeb90613251565b8051610cca906011906020840190612b13565b60108054610cdb9061338f565b600f8054610cdb9061338f565b60006111e8826121ab565b5192915050565b60006001600160a01b03821661125a5760405162461bcd60e51b815260206004820152602a60248201527f4552433732313a2062616c616e636520717565727920666f7220746865207a65604482015269726f206164647265737360b01b6064820152608401610aeb565b506001600160a01b03166000908152600560205260409020546001600160801b031690565b6009546001600160a01b031633146112a95760405162461bcd60e51b8152600401610aeb90613251565b6112b36000612352565b565b6009546001600160a01b031633146112df5760405162461bcd60e51b8152600401610aeb90613251565b8051610cca90600f906020840190612b13565b336001600160a01b037f000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb7952161461136a5760405162461bcd60e51b815260206004820152601f60248201527f4f6e6c7920565246436f6f7264696e61746f722063616e2066756c66696c6c006044820152606401610aeb565b610cca82826123a4565b6060600380546109fe9061338f565b80600081118015611395575080600214155b80156113a2575080600414155b80156113af575060058111155b6113f15760405162461bcd60e51b8152602060048201526013602482015272125b9d985b1a59081b5a5b9d08185b5bdd5b9d606a1b6044820152606401610aeb565b80600114801561140857506702386f26fc10000034145b80611425575080600314801561142557506705698eef0667000034145b806114425750806005148015611442575067063eb89da4ed000034145b61148e5760405162461bcd60e51b815260206004820152601d60248201527f53656e742065746865722076616c756520697320696e636f72726563740000006044820152606401610aeb565b600954600160a01b900460ff166114e75760405162461bcd60e51b815260206004820181905260248201527f53616c65206973206e6f742061637469766520617420746865206d6f6d656e746044820152606401610aeb565b600a546114f690612710613335565b8261150060015490565b61150a91906132e1565b11156115585760405162461bcd60e51b815260206004820181905260248201527f507572636861736520776f756c6420657863656564206d617820737570706c796044820152606401610aeb565b610cca3383611e0f565b6001600160a01b0382163314156115bb5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c6572000000000000006044820152606401610aeb565b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b60118054610cdb9061338f565b80600081118015611646575080600214155b8015611653575080600414155b8015611660575060058111155b6116a25760405162461bcd60e51b8152602060048201526013602482015272125b9d985b1a59081b5a5b9d08185b5bdd5b9d606a1b6044820152606401610aeb565b8060011480156116b957506702386f26fc10000034145b806116d657508060031480156116d657506705698eef0667000034145b806116f357508060051480156116f3575067063eb89da4ed000034145b61173f5760405162461bcd60e51b815260206004820152601d60248201527f53656e742065746865722076616c756520697320696e636f72726563740000006044820152606401610aeb565b600954600160a81b900460ff166117a45760405162461bcd60e51b815260206004820152602360248201527f50726573616c65206973206e6f742061637469766520617420746865206d6f6d604482015262195b9d60ea1b6064820152608401610aeb565b6117ae8333611c8b565b6118135760405162461bcd60e51b815260206004820152603060248201527f546869732061646472657373206973206e6f7420616c6c6f77206c697374656460448201526f20666f72207468652070726573616c6560801b6064820152608401610aeb565b336000908152600c60205260409020546005906118319084906132e1565b111561188b5760405162461bcd60e51b8152602060048201526024808201527f4578636565647320616c6c6f7765642070726573616c6520796f752063616e206044820152631b5a5b9d60e21b6064820152608401610aeb565b600a5461189a90612710613335565b826118a460015490565b6118ae91906132e1565b11156118fc5760405162461bcd60e51b815260206004820181905260248201527f507572636861736520776f756c6420657863656564206d617820737570706c796044820152606401610aeb565b6119063383611e0f565b336000908152600c6020526040812080548492906119259084906132e1565b9091555050505050565b6009546000906001600160a01b0316331461195c5760405162461bcd60e51b8152600401610aeb90613251565b600b54156119b75760405162461bcd60e51b815260206004820152602260248201527f7374617274696e67496e6465782068617320616c7265616479206265656e2073604482015261195d60f21b6064820152608401610aeb565b60006119c384846123c1565b600e819055949350505050565b6119db848484611e29565b6119e784848484612547565b611a035760405162461bcd60e51b8152600401610aeb906131ff565b50505050565b6060611a16826001541190565b611a7a5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610aeb565b600954600160b01b900460ff16611b1d5760118054611a989061338f565b80601f0160208091040260200160405190810160405280929190818152602001828054611ac49061338f565b8015611b115780601f10611ae657610100808354040283529160200191611b11565b820191906000526020600020905b815481529060010190602001808311611af457829003601f168201915b50505050509050919050565b6000611b27612654565b90506000815111611b475760405180602001604052806000815250611b75565b80611b5184612663565b6010604051602001611b6593929190613079565b6040516020818303038152906040525b9392505050565b6009546001600160a01b03163314611ba65760405162461bcd60e51b8152600401610aeb90613251565b60098054911515600160b01b0260ff60b01b19909216919091179055565b6009546001600160a01b03163314611bee5760405162461bcd60e51b8152600401610aeb90613251565b600d55565b6009546001600160a01b03163314611c1d5760405162461bcd60e51b8152600401610aeb90613251565b6001600160a01b038116611c825760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610aeb565b61104381612352565b60006001600160a01b038216611ce35760405162461bcd60e51b815260206004820152601e60248201527f5a65726f2061646472657373206e6f74206f6e20416c6c6f77204c69737400006044820152606401610aeb565b6040516bffffffffffffffffffffffff19606084901b166020820152600090603401604051602081830303815290604052805190602001209050611d2a84600d548361277c565b949350505050565b6009546001600160a01b03163314611d5c5760405162461bcd60e51b8152600401610aeb90613251565b6009805460ff60a81b198116600160a81b9182900460ff1615909102179055565b6009546001600160a01b03163314611da75760405162461bcd60e51b8152600401610aeb90613251565b610c2260128383612b93565b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b610cca828260405180602001604052806000815250612792565b6000611e34826121ab565b80519091506000906001600160a01b0316336001600160a01b03161480611e6b575033611e6084610a81565b6001600160a01b0316145b80611e7d57508151611e7d903361089e565b905080611ee65760405162461bcd60e51b815260206004820152603160248201527f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f6044820152701ddb995c881b9bdc88185c1c1c9bdd9959607a1b6064820152608401610aeb565b846001600160a01b031682600001516001600160a01b031614611f595760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b6064820152608401610aeb565b6001600160a01b038416611fbb5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b6064820152608401610aeb565b611fcb6000848460000151611db3565b6001600160a01b0385166000908152600560205260408120805460019290611ffd9084906001600160801b031661330d565b82546101009290920a6001600160801b038181021990931691831602179091556001600160a01b03861660009081526005602052604081208054600194509092612049918591166132b6565b82546001600160801b039182166101009390930a9283029190920219909116179055506040805180820182526001600160a01b0380871682526001600160401b03428116602080850191825260008981526004909152948520935184549151909216600160a01b026001600160e01b031990911691909216171790556120d08460016132e1565b6000818152600460205260409020549091506001600160a01b0316612161576120fa816001541190565b156121615760408051808201825284516001600160a01b0390811682526020808701516001600160401b039081168285019081526000878152600490935294909120925183549451909116600160a01b026001600160e01b03199094169116179190911790555b83856001600160a01b0316876001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45b505050505050565b60408051808201909152600080825260208201526121ca826001541190565b6122285760405162461bcd60e51b815260206004820152602960248201527f4552433732313a206f776e657220717565727920666f72206e6f6e657869737460448201526832b73a103a37b5b2b760b91b6064820152608401610aeb565b60007f000000000000000000000000000000000000000000000000000000000000012c83106122895761227b7f000000000000000000000000000000000000000000000000000000000000012c84613335565b6122869060016132e1565b90505b825b8181106122f2576000818152600460209081526040918290208251808401909352546001600160a01b038116808452600160a01b9091046001600160401b031691830191909152156122df57949350505050565b50806122ea81613378565b91505061228b565b5060405162461bcd60e51b815260206004820152602e60248201527f4552433732313a20756e61626c6520746f2064657465726d696e65207468652060448201526d37bbb732b91037b3103a37b5b2b760911b6064820152608401610aeb565b600980546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b81600e541415610cca576123ba612710826133e5565b600b555050565b60007f000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca6001600160a01b0316634000aea07f000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb795284866000604051602001612431929190918252602082015260400190565b6040516020818303038152906040526040518463ffffffff1660e01b815260040161245e93929190613178565b602060405180830381600087803b15801561247857600080fd5b505af115801561248c573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906124b09190612f0f565b5060008381526020818152604080832054815180840188905280830185905230606082015260808082018390528351808303909101815260a09091019092528151918301919091208684529290915261250a9060016132e1565b6000858152602081815260409182902092909255805180830187905280820184905281518082038301815260609091019091528051910120611d2a565b60006001600160a01b0384163b1561264957604051630a85bd0160e11b81526001600160a01b0385169063150b7a029061258b90339089908890889060040161313b565b602060405180830381600087803b1580156125a557600080fd5b505af19250505080156125d5575060408051601f3d908101601f191682019092526125d291810190612f80565b60015b61262f573d808015612603576040519150601f19603f3d011682016040523d82523d6000602084013e612608565b606091505b5080516126275760405162461bcd60e51b8152600401610aeb906131ff565b805181602001fd5b6001600160e01b031916630a85bd0160e11b149050611d2a565b506001949350505050565b6060600f80546109fe9061338f565b6060816126875750506040805180820190915260018152600360fc1b602082015290565b8160005b81156126b1578061269b816133ca565b91506126aa9050600a836132f9565b915061268b565b6000816001600160401b038111156126d957634e487b7160e01b600052604160045260246000fd5b6040519080825280601f01601f191660200182016040528015612703576020820181803683370190505b5090505b8415611d2a57612718600183613335565b9150612725600a866133e5565b6127309060306132e1565b60f81b81838151811061275357634e487b7160e01b600052603260045260246000fd5b60200101906001600160f81b031916908160001a905350612775600a866132f9565b9450612707565b6000826127898584612a61565b14949350505050565b6001546001600160a01b0384166127eb5760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f20616464726573736044820152606401610aeb565b6127f6816001541190565b156128435760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006044820152606401610aeb565b7f000000000000000000000000000000000000000000000000000000000000012c8311156128bd5760405162461bcd60e51b815260206004820152602160248201527f4552433732313a207175616e7469747920746f206d696e7420746f6f206869676044820152600d60fb1b6064820152608401610aeb565b6001600160a01b0384166000908152600560209081526040918290208251808401845290546001600160801b038082168352600160801b90910416918101919091528151808301909252805190919081906129199087906132b6565b6001600160801b0316815260200185836020015161293791906132b6565b6001600160801b039081169091526001600160a01b0380881660008181526005602090815260408083208751978301518716600160801b029790961696909617909455845180860186529182526001600160401b034281168386019081528883526004909552948120915182549451909516600160a01b026001600160e01b031990941694909216939093179190911790915582905b85811015612a565760405182906001600160a01b038916906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a4612a1a6000888488612547565b612a365760405162461bcd60e51b8152600401610aeb906131ff565b81612a40816133ca565b9250508080612a4e906133ca565b9150506129cd565b5060018190556121a3565b600081815b8451811015611116576000858281518110612a9157634e487b7160e01b600052603260045260246000fd5b60200260200101519050808311612ad3576040805160208101859052908101829052606001604051602081830303815290604052805190602001209250612b00565b60408051602081018390529081018490526060016040516020818303038152906040528051906020012092505b5080612b0b816133ca565b915050612a66565b828054612b1f9061338f565b90600052602060002090601f016020900481019282612b415760008555612b87565b82601f10612b5a57805160ff1916838001178555612b87565b82800160010185558215612b87579182015b82811115612b87578251825591602001919060010190612b6c565b50611182929150612c07565b828054612b9f9061338f565b90600052602060002090601f016020900481019282612bc15760008555612b87565b82601f10612bda5782800160ff19823516178555612b87565b82800160010185558215612b87579182015b82811115612b87578235825591602001919060010190612bec565b5b808211156111825760008155600101612c08565b60006001600160401b03831115612c3557612c35613425565b612c48601f8401601f1916602001613286565b9050828152838383011115612c5c57600080fd5b828260208301376000602084830101529392505050565b80356001600160a01b0381168114612c8a57600080fd5b919050565b600082601f830112612c9f578081fd5b813560206001600160401b03821115612cba57612cba613425565b8160051b612cc9828201613286565b838152828101908684018388018501891015612ce3578687fd5b8693505b85841015612d05578035835260019390930192918401918401612ce7565b50979650505050505050565b600060208284031215612d22578081fd5b611b7582612c73565b60008060408385031215612d3d578081fd5b612d4683612c73565b9150612d5460208401612c73565b90509250929050565b600080600060608486031215612d71578081fd5b612d7a84612c73565b9250612d8860208501612c73565b9150604084013590509250925092565b60008060008060808587031215612dad578081fd5b612db685612c73565b9350612dc460208601612c73565b92506040850135915060608501356001600160401b03811115612de5578182fd5b8501601f81018713612df5578182fd5b612e0487823560208401612c1c565b91505092959194509250565b60008060408385031215612e22578182fd5b612e2b83612c73565b91506020830135612e3b8161343b565b809150509250929050565b60008060408385031215612e58578182fd5b612e6183612c73565b946020939093013593505050565b60008060408385031215612e81578182fd5b82356001600160401b03811115612e96578283fd5b612ea285828601612c8f565b925050612d5460208401612c73565b60008060408385031215612ec3578182fd5b82356001600160401b03811115612ed8578283fd5b612ee485828601612c8f565b95602094909401359450505050565b600060208284031215612f04578081fd5b8135611b758161343b565b600060208284031215612f20578081fd5b8151611b758161343b565b600060208284031215612f3c578081fd5b5035919050565b60008060408385031215612f55578182fd5b50508035926020909101359150565b600060208284031215612f75578081fd5b8135611b7581613449565b600060208284031215612f91578081fd5b8151611b7581613449565b60008060208385031215612fae578182fd5b82356001600160401b0380821115612fc4578384fd5b818501915085601f830112612fd7578384fd5b813581811115612fe5578485fd5b866020828501011115612ff6578485fd5b60209290920196919550909350505050565b600060208284031215613019578081fd5b81356001600160401b0381111561302e578182fd5b8201601f8101841361303e578182fd5b611d2a84823560208401612c1c565b6000815180845261306581602086016020860161334c565b601f01601f19169290920160200192915050565b60008451602061308c8285838a0161334c565b85519184019161309f8184848a0161334c565b85549201918390600181811c90808316806130bb57607f831692505b8583108114156130d957634e487b7160e01b88526022600452602488fd5b8080156130ed57600181146130fe5761312a565b60ff1985168852838801955061312a565b60008b815260209020895b858110156131225781548a820152908401908801613109565b505083880195505b50939b9a5050505050505050505050565b6001600160a01b038581168252841660208201526040810183905260806060820181905260009061316e9083018461304d565b9695505050505050565b60018060a01b038416815282602082015260606040820152600061319f606083018461304d565b95945050505050565b6020808252825182820181905260009190848201906040850190845b818110156131e0578351835292840192918401916001016131c4565b50909695505050505050565b602081526000611b75602083018461304d565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b604051601f8201601f191681016001600160401b03811182821017156132ae576132ae613425565b604052919050565b60006001600160801b038083168185168083038211156132d8576132d86133f9565b01949350505050565b600082198211156132f4576132f46133f9565b500190565b6000826133085761330861340f565b500490565b60006001600160801b038381169083168181101561332d5761332d6133f9565b039392505050565b600082821015613347576133476133f9565b500390565b60005b8381101561336757818101518382015260200161334f565b83811115611a035750506000910152565b600081613387576133876133f9565b506000190190565b600181811c908216806133a357607f821691505b602082108114156133c457634e487b7160e01b600052602260045260246000fd5b50919050565b60006000198214156133de576133de6133f9565b5060010190565b6000826133f4576133f461340f565b500690565b634e487b7160e01b600052601160045260246000fd5b634e487b7160e01b600052601260045260246000fd5b634e487b7160e01b600052604160045260246000fd5b801515811461104357600080fd5b6001600160e01b03198116811461104357600080fdfea264697066735822122087aa85241c1a85e9fa2a9ac9a59f2893feca7091f47a2591a196718ab8f159dd64736f6c63430008040033

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

000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb7952000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca000000000000000000000000d3d114775f17f0d10d2bbb81c3a1c36e95d2bd73

-----Decoded View---------------
Arg [0] : _vrfCoordinator (address): 0xf0d54349aDdcf704F77AE15b96510dEA15cb7952
Arg [1] : _link (address): 0x514910771AF9Ca656af840dff83E8264EcF986CA
Arg [2] : _owner (address): 0xD3d114775F17f0D10d2bbb81c3a1c36E95d2bD73

-----Encoded View---------------
3 Constructor Arguments found :
Arg [0] : 000000000000000000000000f0d54349addcf704f77ae15b96510dea15cb7952
Arg [1] : 000000000000000000000000514910771af9ca656af840dff83e8264ecf986ca
Arg [2] : 000000000000000000000000d3d114775f17f0d10d2bbb81c3a1c36e95d2bd73


Deployed Bytecode Sourcemap

55392:6048:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;41088:370;;;;;;;;;;-1:-1:-1;41088:370:0;;;;;:::i;:::-;;:::i;:::-;;;11825:14:1;;11818:22;11800:41;;11788:2;11773:18;41088:370:0;;;;;;;;42810:94;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;44332:203::-;;;;;;;;;;-1:-1:-1;44332:203:0;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;10093:32:1;;;10075:51;;10063:2;10048:18;44332:203:0;10030:102:1;43898:376:0;;;;;;;;;;-1:-1:-1;43898:376:0;;;;;:::i;:::-;;:::i;:::-;;57607:299;;;;;;;;;;-1:-1:-1;57607:299:0;;;;;:::i;:::-;;:::i;55494:48::-;;;;;;;;;;;;55532:10;55494:48;;;;;11998:25:1;;;11986:2;11971:18;55494:48:0;11953:76:1;56243:24:0;;;;;;;;;;;;;:::i;60846:102::-;;;;;;;;;;-1:-1:-1;60846:102:0;;;;;:::i;:::-;;:::i;39655:94::-;;;;;;;;;;-1:-1:-1;39731:12:0;;39655:94;;45180:142;;;;;;;;;;-1:-1:-1;45180:142:0;;;;;:::i;:::-;;:::i;40282:742::-;;;;;;;;;;-1:-1:-1;40282:742:0;;;;;:::i;:::-;;:::i;55844:35::-;;;;;;;;;;-1:-1:-1;55844:35:0;;;;-1:-1:-1;;;55844:35:0;;;;;;55758:42;;;;;;;;;;;;55795:5;55758:42;;57912:85;;;;;;;;;;;;;:::i;61157:170::-;;;;;;;;;;;;;:::i;55600:48::-;;;;;;;;;;;;55638:10;55600:48;;56087:37;;;;;;;;;;;;;;;;45385:157;;;;;;;;;;-1:-1:-1;45385:157:0;;;;;:::i;:::-;;:::i;59677:373::-;;;;;;;;;;-1:-1:-1;59677:373:0;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;39818:176::-;;;;;;;;;;-1:-1:-1;39818:176:0;;;;;:::i;:::-;;:::i;60585:147::-;;;;;;;;;;-1:-1:-1;60585:147:0;;;;;:::i;:::-;;:::i;55886:28::-;;;;;;;;;;-1:-1:-1;55886:28:0;;;;-1:-1:-1;;;55886:28:0;;;;;;56164:33;;;;;;;;;;;;;:::i;55989:54::-;;;;;;;;;;-1:-1:-1;55989:54:0;;;;;:::i;:::-;;;;;;;;;;;;;;56131:28;;;;;;;;;;;;;:::i;42633:118::-;;;;;;;;;;-1:-1:-1;42633:118:0;;;;;:::i;:::-;;:::i;41514:210::-;;;;;;;;;;-1:-1:-1;41514:210:0;;;;;:::i;:::-;;:::i;4706:97::-;;;;;;;;;;;;;:::i;60738:102::-;;;;;;;;;;-1:-1:-1;60738:102:0;;;;;:::i;:::-;;:::i;4095:81::-;;;;;;;;;;-1:-1:-1;4164:6:0;;-1:-1:-1;;;;;4164:6:0;4095:81;;55710:43;;;;;;;;;;;;55752:1;55710:43;;18219:218;;;;;;;;;;-1:-1:-1;18219:218:0;;;;;:::i;:::-;;:::i;42965:98::-;;;;;;;;;;;;;:::i;56048:34::-;;;;;;;;;;;;;;;;59320:351;;;;;;:::i;:::-;;:::i;44599:273::-;;;;;;;;;;-1:-1:-1;44599:273:0;;;;;:::i;:::-;;:::i;56202:36::-;;;;;;;;;;;;;:::i;58581:733::-;;;;;;:::i;:::-;;:::i;57053:332::-;;;;;;;;;;-1:-1:-1;57053:332:0;;;;;:::i;:::-;;:::i;55547:48::-;;;;;;;;;;;;55585:10;55547:48;;45605:310;;;;;;;;;;-1:-1:-1;45605:310:0;;;;;:::i;:::-;;:::i;60056:523::-;;;;;;;;;;-1:-1:-1;60056:523:0;;;;;:::i;:::-;;:::i;55954:28::-;;;;;;;;;;;;;;;;55921;;;;;;;;;;;;;;;;49928:43;;;;;;;;;;;;;;;;60954:83;;;;;;;;;;-1:-1:-1;60954:83:0;;;;;:::i;:::-;;:::i;44935:186::-;;;;;;;;;;-1:-1:-1;44935:186:0;;;;;:::i;:::-;-1:-1:-1;;;;;45080:25:0;;;45057:4;45080:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;44935:186;58426:149;;;;;;;;;;-1:-1:-1;58426:149:0;;;;;:::i;:::-;;:::i;55807:32::-;;;;;;;;;;-1:-1:-1;55807:32:0;;;;-1:-1:-1;;;55807:32:0;;;;;;4948:191;;;;;;;;;;-1:-1:-1;4948:191:0;;;;;:::i;:::-;;:::i;58103:317::-;;;;;;;;;;-1:-1:-1;58103:317:0;;;;;:::i;:::-;;:::i;58003:94::-;;;;;;;;;;;;;:::i;61043:108::-;;;;;;;;;;-1:-1:-1;61043:108:0;;;;;:::i;:::-;;:::i;41088:370::-;41215:4;-1:-1:-1;;;;;;41245:40:0;;-1:-1:-1;;;41245:40:0;;:99;;-1:-1:-1;;;;;;;41296:48:0;;-1:-1:-1;;;41296:48:0;41245:99;:160;;;-1:-1:-1;;;;;;;41355:50:0;;-1:-1:-1;;;41355:50:0;41245:160;:207;;;-1:-1:-1;;;;;;;;;;37634:40:0;;;41416:36;41231:221;41088:370;-1:-1:-1;;41088:370:0:o;42810:94::-;42864:13;42893:5;42886:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42810:94;:::o;44332:203::-;44400:7;44424:16;44432:7;46241:12;;-1:-1:-1;46231:22:0;46154:105;44424:16;44416:73;;;;-1:-1:-1;;;44416:73:0;;20968:2:1;44416:73:0;;;20950:21:1;21007:2;20987:18;;;20980:30;21046:34;21026:18;;;21019:62;-1:-1:-1;;;21097:18:1;;;21090:42;21149:19;;44416:73:0;;;;;;;;;-1:-1:-1;44505:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;44505:24:0;;44332:203::o;43898:376::-;43967:13;43983:23;43998:7;43983:14;:23::i;:::-;43967:39;;44027:5;-1:-1:-1;;;;;44021:11:0;:2;-1:-1:-1;;;;;44021:11:0;;;44013:57;;;;-1:-1:-1;;;44013:57:0;;22877:2:1;44013:57:0;;;22859:21:1;22916:2;22896:18;;;22889:30;22955:34;22935:18;;;22928:62;-1:-1:-1;;;23006:18:1;;;22999:31;23047:19;;44013:57:0;22849:223:1;44013:57:0;2918:10;-1:-1:-1;;;;;44095:21:0;;;;:62;;-1:-1:-1;44120:37:0;44137:5;2918:10;44935:186;:::i;44120:37::-;44079:152;;;;-1:-1:-1;;;44079:152:0;;17810:2:1;44079:152:0;;;17792:21:1;17849:2;17829:18;;;17822:30;17888:34;17868:18;;;17861:62;17959:26;17939:18;;;17932:54;18003:19;;44079:152:0;17782:246:1;44079:152:0;44240:28;44249:2;44253:7;44262:5;44240:8;:28::i;:::-;43898:376;;;:::o;57607:299::-;4164:6;;-1:-1:-1;;;;;4164:6:0;2918:10;4297:23;4289:68;;;;-1:-1:-1;;;4289:68:0;;;;;;;:::i;:::-;57738:1:::1;57721:14;:18;:47;;;;;57761:7;;57743:14;:25;;57721:47;57705:113;;;::::0;-1:-1:-1;;;57705:113:0;;16287:2:1;57705:113:0::1;::::0;::::1;16269:21:1::0;;;16306:18;;;16299:30;16365:34;16345:18;;;16338:62;16417:18;;57705:113:0::1;16259:182:1::0;57705:113:0::1;57847:14;57837:7;;:24;;;;:::i;:::-;57827:7;:34:::0;57870:30:::1;57880:3:::0;57885:14;57870:9:::1;:30::i;:::-;57607:299:::0;;:::o;56243:24::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;60846:102::-;4164:6;;-1:-1:-1;;;;;4164:6:0;2918:10;4297:23;4289:68;;;;-1:-1:-1;;;4289:68:0;;;;;;;:::i;:::-;60920:22;;::::1;::::0;:9:::1;::::0;:22:::1;::::0;::::1;::::0;::::1;:::i;45180:142::-:0;45288:28;45298:4;45304:2;45308:7;45288:9;:28::i;40282:742::-;40391:7;40426:16;40436:5;40426:9;:16::i;:::-;40418:5;:24;40410:70;;;;-1:-1:-1;;;40410:70:0;;15885:2:1;40410:70:0;;;15867:21:1;15924:2;15904:18;;;15897:30;15963:34;15943:18;;;15936:62;-1:-1:-1;;;16014:18:1;;;16007:31;16055:19;;40410:70:0;15857:223:1;40410:70:0;40487:22;40512:13;39731:12;;;39655:94;40512:13;40487:38;;40532:19;40562:25;40612:9;40607:350;40631:14;40627:1;:18;40607:350;;;40661:31;40695:14;;;:11;:14;;;;;;;;;40661:48;;;;;;;;;-1:-1:-1;;;;;40661:48:0;;;;;-1:-1:-1;;;40661:48:0;;;-1:-1:-1;;;;;40661:48:0;;;;;;;;40722:28;40718:89;;40783:14;;;-1:-1:-1;40718:89:0;40840:5;-1:-1:-1;;;;;40819:26:0;:17;-1:-1:-1;;;;;40819:26:0;;40815:135;;;40877:5;40862:11;:20;40858:59;;;-1:-1:-1;40904:1:0;-1:-1:-1;40897:8:0;;-1:-1:-1;;;40897:8:0;40858:59;40927:13;;;;:::i;:::-;;;;40815:135;-1:-1:-1;40647:3:0;;;;:::i;:::-;;;;40607:350;;;-1:-1:-1;40963:55:0;;-1:-1:-1;;;40963:55:0;;24045:2:1;40963:55:0;;;24027:21:1;24084:2;24064:18;;;24057:30;24123:34;24103:18;;;24096:62;-1:-1:-1;;;24174:18:1;;;24167:43;24227:19;;40963:55:0;24017:235:1;57912:85:0;4164:6;;-1:-1:-1;;;;;4164:6:0;2918:10;4297:23;4289:68;;;;-1:-1:-1;;;4289:68:0;;;;;;;:::i;:::-;57979:12:::1;::::0;;-1:-1:-1;;;;57963:28:0;::::1;-1:-1:-1::0;;;57979:12:0;;;::::1;;;57978:13;57963:28:::0;;::::1;;::::0;;57912:85::o;61157:170::-;4164:6;;-1:-1:-1;;;;;4164:6:0;2918:10;4297:23;4289:68;;;;-1:-1:-1;;;4289:68:0;;;;;;;:::i;:::-;61204:7:::1;61225;4164:6:::0;;-1:-1:-1;;;;;4164:6:0;;4095:81;61225:7:::1;-1:-1:-1::0;;;;;61217:21:0::1;61247;61217:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;61203:71;;;61289:2;61281:40;;;::::0;-1:-1:-1;;;61281:40:0;;13958:2:1;61281:40:0::1;::::0;::::1;13940:21:1::0;13997:2;13977:18;;;13970:30;14036:27;14016:18;;;14009:55;14081:18;;61281:40:0::1;13930:175:1::0;61281:40:0::1;4364:1;61157:170::o:0;45385:157::-;45497:39;45514:4;45520:2;45524:7;45497:39;;;;;;;;;;;;:16;:39::i;59677:373::-;59754:16;59782:23;59808:17;59818:6;59808:9;:17::i;:::-;59782:43;;59832:30;59879:15;-1:-1:-1;;;;;59865:30:0;;;;;-1:-1:-1;;;59865:30:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;59865:30:0;;59832:63;;59909:9;59904:112;59928:15;59924:1;:19;59904:112;;;59978:30;59998:6;60006:1;59978:19;:30::i;:::-;59959:13;59973:1;59959:16;;;;;;-1:-1:-1;;;59959:16:0;;;;;;;;;;;;;;;;;;:49;59945:3;;;;:::i;:::-;;;;59904:112;;;-1:-1:-1;60031:13:0;59677:373;-1:-1:-1;;;59677:373:0:o;39818:176::-;39885:7;39917:13;39731:12;;;39655:94;39917:13;39909:5;:21;39901:68;;;;-1:-1:-1;;;39901:68:0;;14719:2:1;39901:68:0;;;14701:21:1;14758:2;14738:18;;;14731:30;14797:34;14777:18;;;14770:62;-1:-1:-1;;;14848:18:1;;;14841:32;14890:19;;39901:68:0;14691:224:1;39901:68:0;-1:-1:-1;39983:5:0;39818:176::o;60585:147::-;4164:6;;-1:-1:-1;;;;;4164:6:0;2918:10;4297:23;4289:68;;;;-1:-1:-1;;;4289:68:0;;;;;;;:::i;:::-;60688:38;;::::1;::::0;:17:::1;::::0;:38:::1;::::0;::::1;::::0;::::1;:::i;56164:33::-:0;;;;;;;:::i;56131:28::-;;;;;;;:::i;42633:118::-;42697:7;42720:20;42732:7;42720:11;:20::i;:::-;:25;;42633:118;-1:-1:-1;;42633:118:0:o;41514:210::-;41578:7;-1:-1:-1;;;;;41602:19:0;;41594:74;;;;-1:-1:-1;;;41594:74:0;;18650:2:1;41594:74:0;;;18632:21:1;18689:2;18669:18;;;18662:30;18728:34;18708:18;;;18701:62;-1:-1:-1;;;18779:18:1;;;18772:40;18829:19;;41594:74:0;18622:232:1;41594:74:0;-1:-1:-1;;;;;;41690:19:0;;;;;:12;:19;;;;;:27;-1:-1:-1;;;;;41690:27:0;;41514:210::o;4706:97::-;4164:6;;-1:-1:-1;;;;;4164:6:0;2918:10;4297:23;4289:68;;;;-1:-1:-1;;;4289:68:0;;;;;;;:::i;:::-;4767:30:::1;4794:1;4767:18;:30::i;:::-;4706:97::o:0;60738:102::-;4164:6;;-1:-1:-1;;;;;4164:6:0;2918:10;4297:23;4289:68;;;;-1:-1:-1;;;4289:68:0;;;;;;;:::i;:::-;60812:22;;::::1;::::0;:9:::1;::::0;:22:::1;::::0;::::1;::::0;::::1;:::i;18219:218::-:0;18320:10;-1:-1:-1;;;;;18334:14:0;18320:28;;18312:72;;;;-1:-1:-1;;;18312:72:0;;22517:2:1;18312:72:0;;;22499:21:1;22556:2;22536:18;;;22529:30;22595:33;22575:18;;;22568:61;22646:18;;18312:72:0;22489:181:1;18312:72:0;18391:40;18409:9;18420:10;18391:17;:40::i;42965:98::-;43021:13;43050:7;43043:14;;;;;:::i;59320:351::-;59406:15;56402:1;56384:15;:19;:52;;;;;56416:15;56435:1;56416:20;;56384:52;:85;;;;;56449:15;56468:1;56449:20;;56384:85;:132;;;;;55752:1;56482:15;:34;;56384:132;56368:185;;;;-1:-1:-1;;;56368:185:0;;23697:2:1;56368:185:0;;;23679:21:1;23736:2;23716:18;;;23709:30;-1:-1:-1;;;23755:18:1;;;23748:49;23814:18;;56368:185:0;23669:169:1;56368:185:0;56579:15;56598:1;56579:20;:48;;;;;55532:10;56603:9;:24;56579:48;56578:113;;;;56642:15;56661:1;56642:20;:48;;;;;55585:10;56666:9;:24;56642:48;56578:176;;;;56705:15;56724:1;56705:20;:48;;;;;55638:10;56729:9;:24;56705:48;56562:239;;;;-1:-1:-1;;;56562:239:0;;19471:2:1;56562:239:0;;;19453:21:1;19510:2;19490:18;;;19483:30;19549:31;19529:18;;;19522:59;19598:18;;56562:239:0;19443:179:1;56562:239:0;59441:12:::1;::::0;-1:-1:-1;;;59441:12:0;::::1;;;59433:57;;;::::0;-1:-1:-1;;;59433:57:0;;24864:2:1;59433:57:0::1;::::0;::::1;24846:21:1::0;;;24883:18;;;24876:30;24942:34;24922:18;;;24915:62;24994:18;;59433:57:0::1;24836:182:1::0;59433:57:0::1;59561:7;::::0;59548:20:::1;::::0;55795:5:::1;59548:20;:::i;:::-;59529:15;59513:13;39731:12:::0;;;39655:94;59513:13:::1;:31;;;;:::i;:::-;:55;;59497:121;;;::::0;-1:-1:-1;;;59497:121:0;;20246:2:1;59497:121:0::1;::::0;::::1;20228:21:1::0;;;20265:18;;;20258:30;20324:34;20304:18;;;20297:62;20376:18;;59497:121:0::1;20218:182:1::0;59497:121:0::1;59627:38;59637:10;59649:15;59627:9;:38::i;44599:273::-:0;-1:-1:-1;;;;;44690:24:0;;2918:10;44690:24;;44682:62;;;;-1:-1:-1;;;44682:62:0;;17053:2:1;44682:62:0;;;17035:21:1;17092:2;17072:18;;;17065:30;17131:27;17111:18;;;17104:55;17176:18;;44682:62:0;17025:175:1;44682:62:0;2918:10;44753:32;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;44753:42:0;;;;;;;;;;;;:53;;-1:-1:-1;;44753:53:0;;;;;;;;;;44818:48;;11800:41:1;;;44753:42:0;;2918:10;44818:48;;11773:18:1;44818:48:0;;;;;;;44599:273;;:::o;56202:36::-;;;;;;;:::i;58581:733::-;58699:15;56402:1;56384:15;:19;:52;;;;;56416:15;56435:1;56416:20;;56384:52;:85;;;;;56449:15;56468:1;56449:20;;56384:85;:132;;;;;55752:1;56482:15;:34;;56384:132;56368:185;;;;-1:-1:-1;;;56368:185:0;;23697:2:1;56368:185:0;;;23679:21:1;23736:2;23716:18;;;23709:30;-1:-1:-1;;;23755:18:1;;;23748:49;23814:18;;56368:185:0;23669:169:1;56368:185:0;56579:15;56598:1;56579:20;:48;;;;;55532:10;56603:9;:24;56579:48;56578:113;;;;56642:15;56661:1;56642:20;:48;;;;;55585:10;56666:9;:24;56642:48;56578:176;;;;56705:15;56724:1;56705:20;:48;;;;;55638:10;56729:9;:24;56705:48;56562:239;;;;-1:-1:-1;;;56562:239:0;;19471:2:1;56562:239:0;;;19453:21:1;19510:2;19490:18;;;19483:30;19549:31;19529:18;;;19522:59;19598:18;;56562:239:0;19443:179:1;56562:239:0;58734:15:::1;::::0;-1:-1:-1;;;58734:15:0;::::1;;;58726:63;;;::::0;-1:-1:-1;;;58726:63:0;;13135:2:1;58726:63:0::1;::::0;::::1;13117:21:1::0;13174:2;13154:18;;;13147:30;13213:34;13193:18;;;13186:62;-1:-1:-1;;;13264:18:1;;;13257:33;13307:19;;58726:63:0::1;13107:225:1::0;58726:63:0::1;58812:33;58826:6;58834:10;58812:13;:33::i;:::-;58796:115;;;::::0;-1:-1:-1;;;58796:115:0;;19829:2:1;58796:115:0::1;::::0;::::1;19811:21:1::0;19868:2;19848:18;;;19841:30;19907:34;19887:18;;;19880:62;-1:-1:-1;;;19958:18:1;;;19951:46;20014:19;;58796:115:0::1;19801:238:1::0;58796:115:0::1;58954:10;58934:31;::::0;;;:19:::1;:31;::::0;;;;;55704:1:::1;::::0;58934:49:::1;::::0;58968:15;;58934:49:::1;:::i;:::-;:86;;58918:156;;;::::0;-1:-1:-1;;;58918:156:0;;24459:2:1;58918:156:0::1;::::0;::::1;24441:21:1::0;24498:2;24478:18;;;24471:30;24537:34;24517:18;;;24510:62;-1:-1:-1;;;24588:18:1;;;24581:34;24632:19;;58918:156:0::1;24431:226:1::0;58918:156:0::1;59145:7;::::0;59132:20:::1;::::0;55795:5:::1;59132:20;:::i;:::-;59113:15;59097:13;39731:12:::0;;;39655:94;59097:13:::1;:31;;;;:::i;:::-;:55;;59081:121;;;::::0;-1:-1:-1;;;59081:121:0;;20246:2:1;59081:121:0::1;::::0;::::1;20228:21:1::0;;;20265:18;;;20258:30;20324:34;20304:18;;;20297:62;20376:18;;59081:121:0::1;20218:182:1::0;59081:121:0::1;59211:38;59221:10;59233:15;59211:9;:38::i;:::-;59278:10;59258:31;::::0;;;:19:::1;:31;::::0;;;;:50;;59293:15;;59258:31;:50:::1;::::0;59293:15;;59258:50:::1;:::i;:::-;::::0;;;-1:-1:-1;;;;;58581:733:0:o;57053:332::-;4164:6;;57158:17;;-1:-1:-1;;;;;4164:6:0;2918:10;4297:23;4289:68;;;;-1:-1:-1;;;4289:68:0;;;;;;;:::i;:::-;57195:13:::1;::::0;:18;57187:65:::1;;;::::0;-1:-1:-1;;;57187:65:0;;17407:2:1;57187:65:0::1;::::0;::::1;17389:21:1::0;17446:2;17426:18;;;17419:30;17485:34;17465:18;;;17458:62;-1:-1:-1;;;17536:18:1;;;17529:32;17578:19;;57187:65:0::1;17379:224:1::0;57187:65:0::1;57259:18;57280:33;57298:8;57308:4;57280:17;:33::i;:::-;57320:22;:35:::0;;;;57053:332;-1:-1:-1;;;;57053:332:0:o;45605:310::-;45742:28;45752:4;45758:2;45762:7;45742:9;:28::i;:::-;45793:48;45816:4;45822:2;45826:7;45835:5;45793:22;:48::i;:::-;45777:132;;;;-1:-1:-1;;;45777:132:0;;;;;;;:::i;:::-;45605:310;;;;:::o;60056:523::-;60155:13;60196:17;60204:8;46241:12;;-1:-1:-1;46231:22:0;46154:105;60196:17;60180:98;;;;-1:-1:-1;;;60180:98:0;;22101:2:1;60180:98:0;;;22083:21:1;22140:2;22120:18;;;22113:30;22179:34;22159:18;;;22152:62;-1:-1:-1;;;22230:18:1;;;22223:45;22285:19;;60180:98:0;22073:237:1;60180:98:0;60291:8;;-1:-1:-1;;;60291:8:0;;;;60287:64;;60326:17;60319:24;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;60056:523;;;:::o;60287:64::-;60359:28;60390:10;:8;:10::i;:::-;60359:41;;60452:1;60427:14;60421:28;:32;:152;;;;;;;;;;;;;;;;;60501:14;60517:19;:8;:17;:19::i;:::-;60538:9;60484:64;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;60421:152;60407:166;60056:523;-1:-1:-1;;;60056:523:0:o;60954:83::-;4164:6;;-1:-1:-1;;;;;4164:6:0;2918:10;4297:23;4289:68;;;;-1:-1:-1;;;4289:68:0;;;;;;;:::i;:::-;61014:8:::1;:17:::0;;;::::1;;-1:-1:-1::0;;;61014:17:0::1;-1:-1:-1::0;;;;61014:17:0;;::::1;::::0;;;::::1;::::0;;60954:83::o;58426:149::-;4164:6;;-1:-1:-1;;;;;4164:6:0;2918:10;4297:23;4289:68;;;;-1:-1:-1;;;4289:68:0;;;;;;;:::i;:::-;58527:19:::1;:42:::0;58426:149::o;4948:191::-;4164:6;;-1:-1:-1;;;;;4164:6:0;2918:10;4297:23;4289:68;;;;-1:-1:-1;;;4289:68:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;5033:22:0;::::1;5025:73;;;::::0;-1:-1:-1;;;5025:73:0;;14312:2:1;5025:73:0::1;::::0;::::1;14294:21:1::0;14351:2;14331:18;;;14324:30;14390:34;14370:18;;;14363:62;-1:-1:-1;;;14441:18:1;;;14434:36;14487:19;;5025:73:0::1;14284:228:1::0;5025:73:0::1;5105:28;5124:8;5105:18;:28::i;58103:317::-:0;58205:4;-1:-1:-1;;;;;58229:22:0;;58221:65;;;;-1:-1:-1;;;58221:65:0;;21742:2:1;58221:65:0;;;21724:21:1;21781:2;21761:18;;;21754:30;21820:32;21800:18;;;21793:60;21870:18;;58221:65:0;21714:180:1;58221:65:0;58320:26;;-1:-1:-1;;7594:2:1;7590:15;;;7586:53;58320:26:0;;;7574:66:1;58295:12:0;;7656::1;;58320:26:0;;;;;;;;;;;;58310:37;;;;;;58295:52;;58361:53;58380:6;58388:19;;58409:4;58361:18;:53::i;:::-;58354:60;58103:317;-1:-1:-1;;;;58103:317:0:o;58003:94::-;4164:6;;-1:-1:-1;;;;;4164:6:0;2918:10;4297:23;4289:68;;;;-1:-1:-1;;;4289:68:0;;;;;;;:::i;:::-;58076:15:::1;::::0;;-1:-1:-1;;;;58057:34:0;::::1;-1:-1:-1::0;;;58076:15:0;;;::::1;;;58075:16;58057:34:::0;;::::1;;::::0;;58003:94::o;61043:108::-;4164:6;;-1:-1:-1;;;;;4164:6:0;2918:10;4297:23;4289:68;;;;-1:-1:-1;;;4289:68:0;;;;;;;:::i;:::-;61121:24:::1;:10;61134:11:::0;;61121:24:::1;:::i;49750:172::-:0;49847:24;;;;:15;:24;;;;;;:29;;-1:-1:-1;;;;;;49847:29:0;-1:-1:-1;;;;;49847:29:0;;;;;;;;;49888:28;;49847:24;;49888:28;;;;;;;49750:172;;;:::o;46265:98::-;46330:27;46340:2;46344:8;46330:27;;;;;;;;;;;;:9;:27::i;48118:1526::-;48215:35;48253:20;48265:7;48253:11;:20::i;:::-;48324:18;;48215:58;;-1:-1:-1;48282:22:0;;-1:-1:-1;;;;;48308:34:0;2918:10;-1:-1:-1;;;;;48308:34:0;;:81;;;-1:-1:-1;2918:10:0;48353:20;48365:7;48353:11;:20::i;:::-;-1:-1:-1;;;;;48353:36:0;;48308:81;:142;;;-1:-1:-1;48417:18:0;;48400:50;;2918:10;44935:186;:::i;48400:50::-;48282:169;;48476:17;48460:100;;;;-1:-1:-1;;;48460:100:0;;23279:2:1;48460:100:0;;;23261:21:1;23318:2;23298:18;;;23291:30;23357:34;23337:18;;;23330:62;-1:-1:-1;;;23408:18:1;;;23401:47;23465:19;;48460:100:0;23251:239:1;48460:100:0;48607:4;-1:-1:-1;;;;;48585:26:0;:13;:18;;;-1:-1:-1;;;;;48585:26:0;;48569:97;;;;-1:-1:-1;;;48569:97:0;;15122:2:1;48569:97:0;;;15104:21:1;15161:2;15141:18;;;15134:30;15200:34;15180:18;;;15173:62;-1:-1:-1;;;15251:18:1;;;15244:35;15296:19;;48569:97:0;15094:227:1;48569:97:0;-1:-1:-1;;;;;48681:16:0;;48673:65;;;;-1:-1:-1;;;48673:65:0;;16648:2:1;48673:65:0;;;16630:21:1;16687:2;16667:18;;;16660:30;16726:34;16706:18;;;16699:62;-1:-1:-1;;;16777:18:1;;;16770:34;16821:19;;48673:65:0;16620:226:1;48673:65:0;48847:49;48864:1;48868:7;48877:13;:18;;;48847:8;:49::i;:::-;-1:-1:-1;;;;;48905:18:0;;;;;;:12;:18;;;;;:31;;48935:1;;48905:18;:31;;48935:1;;-1:-1:-1;;;;;48905:31:0;;:::i;:::-;;;;;;;;-1:-1:-1;;;;;48905:31:0;;;;;;;;;;;;;;;-1:-1:-1;;;;;48943:16:0;;-1:-1:-1;48943:16:0;;;:12;:16;;;;;:29;;-1:-1:-1;;;48943:16:0;;:29;;-1:-1:-1;;48943:29:0;;:::i;:::-;;;-1:-1:-1;;;;;48943:29:0;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;49002:43:0;;;;;;;;-1:-1:-1;;;;;49002:43:0;;;;;-1:-1:-1;;;;;49028:15:0;49002:43;;;;;;;;;-1:-1:-1;48979:20:0;;;:11;:20;;;;;;:66;;;;;;;;;-1:-1:-1;;;48979:66:0;-1:-1:-1;;;;;;48979:66:0;;;;;;;;;;;49295:11;48991:7;-1:-1:-1;49295:11:0;:::i;:::-;49358:1;49317:24;;;:11;:24;;;;;:29;49273:33;;-1:-1:-1;;;;;;49317:29:0;49313:236;;49375:20;49383:11;46241:12;;-1:-1:-1;46231:22:0;46154:105;49375:20;49371:171;;;49435:97;;;;;;;;49462:18;;-1:-1:-1;;;;;49435:97:0;;;;;;49493:28;;;;-1:-1:-1;;;;;49435:97:0;;;;;;;;;-1:-1:-1;49408:24:0;;;:11;:24;;;;;;;:124;;;;;;;;;-1:-1:-1;;;49408:124:0;-1:-1:-1;;;;;;49408:124:0;;;;;;;;;;;;49371:171;49581:7;49577:2;-1:-1:-1;;;;;49562:27:0;49571:4;-1:-1:-1;;;;;49562:27:0;;;;;;;;;;;49596:42;48118:1526;;;;;;:::o;41975:604::-;-1:-1:-1;;;;;;;;;;;;;;;;;42092:16:0;42100:7;46241:12;;-1:-1:-1;46231:22:0;46154:105;42092:16;42084:70;;;;-1:-1:-1;;;42084:70:0;;19061:2:1;42084:70:0;;;19043:21:1;19100:2;19080:18;;;19073:30;19139:34;19119:18;;;19112:62;-1:-1:-1;;;19190:18:1;;;19183:39;19239:19;;42084:70:0;19033:231:1;42084:70:0;42163:26;42211:12;42200:7;:23;42196:93;;42255:22;42265:12;42255:7;:22;:::i;:::-;:26;;42280:1;42255:26;:::i;:::-;42234:47;;42196:93;42317:7;42297:212;42334:18;42326:4;:26;42297:212;;42371:31;42405:17;;;:11;:17;;;;;;;;;42371:51;;;;;;;;;-1:-1:-1;;;;;42371:51:0;;;;;-1:-1:-1;;;42371:51:0;;;-1:-1:-1;;;;;42371:51:0;;;;;;;;42435:28;42431:71;;42483:9;41975:604;-1:-1:-1;;;;41975:604:0:o;42431:71::-;-1:-1:-1;42354:6:0;;;;:::i;:::-;;;;42297:212;;;-1:-1:-1;42517:56:0;;-1:-1:-1;;;42517:56:0;;18235:2:1;42517:56:0;;;18217:21:1;18274:2;18254:18;;;18247:30;18313:34;18293:18;;;18286:62;-1:-1:-1;;;18364:18:1;;;18357:44;18418:19;;42517:56:0;18207:236:1;5289:177:0;5378:6;;;-1:-1:-1;;;;;5391:17:0;;;-1:-1:-1;;;;;;5391:17:0;;;;;;;5420:40;;5378:6;;;5391:17;5378:6;;5420:40;;5359:16;;5420:40;5289:177;;:::o;57391:210::-;57527:10;57501:22;;:36;57497:99;;;57564:24;55795:5;57564:11;:24;:::i;:::-;57548:13;:40;57391:210;;:::o;16260:1110::-;16347:17;16376:4;-1:-1:-1;;;;;16376:20:0;;16405:14;16428:4;16452:8;15090:1;16441:43;;;;;;;;12208:25:1;;;12264:2;12249:18;;12242:34;12196:2;12181:18;;12163:119;16441:43:0;;;;;;;;;;;;;16376:115;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;-1:-1:-1;16726:15:0;16838:16;;;;;;;;;;;;7775:51;;;;;12518:25:1;;;12559:18;;;12552:34;;;16824:4:0;12602:18:1;;;12595:60;12671:18;;;;12664:34;;;7775:51:0;;;;;;;;;;12490:19:1;;;;7775:51:0;;;7765:62;;;;;;;;;17298:16;;;;;;;:20;;17317:1;17298:20;:::i;:::-;17279:6;:16;;;;;;;;;;;;:39;;;;8363:41;;;;;7836:19:1;;;7871:12;;;7864:28;;;8363:41:0;;;;;;;;;7908:12:1;;;;8363:41:0;;;8353:52;;;;;17332:32;8225:186;51461:689;51598:4;-1:-1:-1;;;;;51615:13:0;;27976:20;28016:8;51611:534;;51654:72;;-1:-1:-1;;;51654:72:0;;-1:-1:-1;;;;;51654:36:0;;;;;:72;;2918:10;;51705:4;;51711:7;;51720:5;;51654:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;51654:72:0;;;;;;;;-1:-1:-1;;51654:72:0;;;;;;;;;;;;:::i;:::-;;;51641:463;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;51885:13:0;;51881:214;;51918:60;;-1:-1:-1;;;51918:60:0;;;;;;;:::i;51881:214::-;52063:6;52057:13;52048:6;52044:2;52040:15;52033:38;51641:463;-1:-1:-1;;;;;;51776:55:0;-1:-1:-1;;;51776:55:0;;-1:-1:-1;51769:62:0;;51611:534;-1:-1:-1;52133:4:0;51461:689;;;;;;:::o;61333:104::-;61393:13;61422:9;61415:16;;;;;:::i;35057:637::-;35113:13;35322:10;35318:43;;-1:-1:-1;;35343:10:0;;;;;;;;;;;;-1:-1:-1;;;35343:10:0;;;;;35057:637::o;35318:43::-;35382:5;35367:12;35415:62;35422:9;;35415:62;;35442:8;;;;:::i;:::-;;-1:-1:-1;35459:10:0;;-1:-1:-1;35467:2:0;35459:10;;:::i;:::-;;;35415:62;;;35483:19;35515:6;-1:-1:-1;;;;;35505:17:0;;;;;-1:-1:-1;;;35505:17:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;35505:17:0;;35483:39;;35529:132;35536:10;;35529:132;;35557:11;35567:1;35557:11;;:::i;:::-;;-1:-1:-1;35620:10:0;35628:2;35620:5;:10;:::i;:::-;35607:24;;:2;:24;:::i;:::-;35594:39;;35577:6;35584;35577:14;;;;;;-1:-1:-1;;;35577:14:0;;;;;;;;;;;;:56;-1:-1:-1;;;;;35577:56:0;;;;;;;;-1:-1:-1;35642:11:0;35651:2;35642:11;;:::i;:::-;;;35529:132;;995:170;1106:4;1155;1126:25;1139:5;1146:4;1126:12;:25::i;:::-;:33;;995:170;-1:-1:-1;;;;995:170:0:o;46618:1268::-;46746:12;;-1:-1:-1;;;;;46773:16:0;;46765:61;;;;-1:-1:-1;;;46765:61:0;;20607:2:1;46765:61:0;;;20589:21:1;;;20626:18;;;20619:30;20685:34;20665:18;;;20658:62;20737:18;;46765:61:0;20579:182:1;46765:61:0;46963:21;46971:12;46241;;-1:-1:-1;46231:22:0;46154:105;46963:21;46962:22;46954:63;;;;-1:-1:-1;;;46954:63:0;;15528:2:1;46954:63:0;;;15510:21:1;15567:2;15547:18;;;15540:30;15606;15586:18;;;15579:58;15654:18;;46954:63:0;15500:178:1;46954:63:0;47044:12;47032:8;:24;;47024:70;;;;-1:-1:-1;;;47024:70:0;;25225:2:1;47024:70:0;;;25207:21:1;25264:2;25244:18;;;25237:30;25303:34;25283:18;;;25276:62;-1:-1:-1;;;25354:18:1;;;25347:31;25395:19;;47024:70:0;25197:223:1;47024:70:0;-1:-1:-1;;;;;47206:16:0;;47173:30;47206:16;;;:12;:16;;;;;;;;;47173:49;;;;;;;;;-1:-1:-1;;;;;47173:49:0;;;;;-1:-1:-1;;;47173:49:0;;;;;;;;;;;47248:119;;;;;;;;47268:19;;47173:49;;47248:119;;;47268:39;;47298:8;;47268:39;:::i;:::-;-1:-1:-1;;;;;47248:119:0;;;;;47351:8;47316:11;:24;;;:44;;;;:::i;:::-;-1:-1:-1;;;;;47248:119:0;;;;;;-1:-1:-1;;;;;47229:16:0;;;;;;;:12;:16;;;;;;;;:138;;;;;;;;-1:-1:-1;;;47229:138:0;;;;;;;;;;;;47402:43;;;;;;;;;;-1:-1:-1;;;;;47428:15:0;47402:43;;;;;;;;47374:25;;;:11;:25;;;;;;:71;;;;;;;;;-1:-1:-1;;;47374:71:0;-1:-1:-1;;;;;;47374:71:0;;;;;;;;;;;;;;;;;;47386:12;;47498:280;47522:8;47518:1;:12;47498:280;;;47551:38;;47576:12;;-1:-1:-1;;;;;47551:38:0;;;47568:1;;47551:38;;47568:1;;47551:38;47616:59;47647:1;47651:2;47655:12;47669:5;47616:22;:59::i;:::-;47598:149;;;;-1:-1:-1;;;47598:149:0;;;;;;;:::i;:::-;47756:14;;;;:::i;:::-;;;;47532:3;;;;;:::i;:::-;;;;47498:280;;;-1:-1:-1;47786:12:0;:27;;;47820:60;45605:310;1509:645;1607:7;1649:4;1607:7;1660:463;1684:5;:12;1680:1;:16;1660:463;;;1712:20;1735:5;1741:1;1735:8;;;;;;-1:-1:-1;;;1735:8:0;;;;;;;;;;;;;;;1712:31;;1772:12;1756;:28;1752:364;;1893:44;;;;;;7836:19:1;;;7871:12;;;7864:28;;;7908:12;;1893:44:0;;;;;;;;;;;;1883:55;;;;;;1868:70;;1752:364;;;2061:44;;;;;;7836:19:1;;;7871:12;;;7864:28;;;7908:12;;2061:44:0;;;;;;;;;;;;2051:55;;;;;;2036:70;;1752:364;-1:-1:-1;1698:3:0;;;;:::i;:::-;;;;1660:463;;-1:-1:-1;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;14:406:1;78:5;-1:-1:-1;;;;;104:6:1;101:30;98:2;;;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:2;;;309:1;306;299:12;268:2;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;88:332;;;;;:::o;425:173::-;493:20;;-1:-1:-1;;;;;542:31:1;;532:42;;522:2;;588:1;585;578:12;522:2;474:124;;;:::o;603:743::-;657:5;710:3;703:4;695:6;691:17;687:27;677:2;;732:5;725;718:20;677:2;772:6;759:20;798:4;-1:-1:-1;;;;;817:2:1;814:26;811:2;;;843:18;;:::i;:::-;889:2;886:1;882:10;912:28;936:2;932;928:11;912:28;:::i;:::-;974:15;;;1005:12;;;;1037:15;;;1071;;;1067:24;;1064:33;-1:-1:-1;1061:2:1;;;1114:5;1107;1100:20;1061:2;1140:5;1131:14;;1154:163;1168:2;1165:1;1162:9;1154:163;;;1225:17;;1213:30;;1186:1;1179:9;;;;;1263:12;;;;1295;;1154:163;;;-1:-1:-1;1335:5:1;667:679;-1:-1:-1;;;;;;;667:679:1:o;1351:196::-;1410:6;1463:2;1451:9;1442:7;1438:23;1434:32;1431:2;;;1484:6;1476;1469:22;1431:2;1512:29;1531:9;1512:29;:::i;1552:270::-;1620:6;1628;1681:2;1669:9;1660:7;1656:23;1652:32;1649:2;;;1702:6;1694;1687:22;1649:2;1730:29;1749:9;1730:29;:::i;:::-;1720:39;;1778:38;1812:2;1801:9;1797:18;1778:38;:::i;:::-;1768:48;;1639:183;;;;;:::o;1827:338::-;1904:6;1912;1920;1973:2;1961:9;1952:7;1948:23;1944:32;1941:2;;;1994:6;1986;1979:22;1941:2;2022:29;2041:9;2022:29;:::i;:::-;2012:39;;2070:38;2104:2;2093:9;2089:18;2070:38;:::i;:::-;2060:48;;2155:2;2144:9;2140:18;2127:32;2117:42;;1931:234;;;;;:::o;2170:696::-;2265:6;2273;2281;2289;2342:3;2330:9;2321:7;2317:23;2313:33;2310:2;;;2364:6;2356;2349:22;2310:2;2392:29;2411:9;2392:29;:::i;:::-;2382:39;;2440:38;2474:2;2463:9;2459:18;2440:38;:::i;:::-;2430:48;;2525:2;2514:9;2510:18;2497:32;2487:42;;2580:2;2569:9;2565:18;2552:32;-1:-1:-1;;;;;2599:6:1;2596:30;2593:2;;;2644:6;2636;2629:22;2593:2;2672:22;;2725:4;2717:13;;2713:27;-1:-1:-1;2703:2:1;;2759:6;2751;2744:22;2703:2;2787:73;2852:7;2847:2;2834:16;2829:2;2825;2821:11;2787:73;:::i;:::-;2777:83;;;2300:566;;;;;;;:::o;2871:325::-;2936:6;2944;2997:2;2985:9;2976:7;2972:23;2968:32;2965:2;;;3018:6;3010;3003:22;2965:2;3046:29;3065:9;3046:29;:::i;:::-;3036:39;;3125:2;3114:9;3110:18;3097:32;3138:28;3160:5;3138:28;:::i;:::-;3185:5;3175:15;;;2955:241;;;;;:::o;3201:264::-;3269:6;3277;3330:2;3318:9;3309:7;3305:23;3301:32;3298:2;;;3351:6;3343;3336:22;3298:2;3379:29;3398:9;3379:29;:::i;:::-;3369:39;3455:2;3440:18;;;;3427:32;;-1:-1:-1;;;3288:177:1:o;3470:442::-;3563:6;3571;3624:2;3612:9;3603:7;3599:23;3595:32;3592:2;;;3645:6;3637;3630:22;3592:2;3690:9;3677:23;-1:-1:-1;;;;;3715:6:1;3712:30;3709:2;;;3760:6;3752;3745:22;3709:2;3788:61;3841:7;3832:6;3821:9;3817:22;3788:61;:::i;:::-;3778:71;;;3868:38;3902:2;3891:9;3887:18;3868:38;:::i;3917:436::-;4010:6;4018;4071:2;4059:9;4050:7;4046:23;4042:32;4039:2;;;4092:6;4084;4077:22;4039:2;4137:9;4124:23;-1:-1:-1;;;;;4162:6:1;4159:30;4156:2;;;4207:6;4199;4192:22;4156:2;4235:61;4288:7;4279:6;4268:9;4264:22;4235:61;:::i;:::-;4225:71;4343:2;4328:18;;;;4315:32;;-1:-1:-1;;;;4029:324:1:o;4358:251::-;4414:6;4467:2;4455:9;4446:7;4442:23;4438:32;4435:2;;;4488:6;4480;4473:22;4435:2;4532:9;4519:23;4551:28;4573:5;4551:28;:::i;4614:255::-;4681:6;4734:2;4722:9;4713:7;4709:23;4705:32;4702:2;;;4755:6;4747;4740:22;4702:2;4792:9;4786:16;4811:28;4833:5;4811:28;:::i;4874:190::-;4933:6;4986:2;4974:9;4965:7;4961:23;4957:32;4954:2;;;5007:6;4999;4992:22;4954:2;-1:-1:-1;5035:23:1;;4944:120;-1:-1:-1;4944:120:1:o;5069:258::-;5137:6;5145;5198:2;5186:9;5177:7;5173:23;5169:32;5166:2;;;5219:6;5211;5204:22;5166:2;-1:-1:-1;;5247:23:1;;;5317:2;5302:18;;;5289:32;;-1:-1:-1;5156:171:1:o;5332:255::-;5390:6;5443:2;5431:9;5422:7;5418:23;5414:32;5411:2;;;5464:6;5456;5449:22;5411:2;5508:9;5495:23;5527:30;5551:5;5527:30;:::i;5592:259::-;5661:6;5714:2;5702:9;5693:7;5689:23;5685:32;5682:2;;;5735:6;5727;5720:22;5682:2;5772:9;5766:16;5791:30;5815:5;5791:30;:::i;5856:642::-;5927:6;5935;5988:2;5976:9;5967:7;5963:23;5959:32;5956:2;;;6009:6;6001;5994:22;5956:2;6054:9;6041:23;-1:-1:-1;;;;;6124:2:1;6116:6;6113:14;6110:2;;;6145:6;6137;6130:22;6110:2;6188:6;6177:9;6173:22;6163:32;;6233:7;6226:4;6222:2;6218:13;6214:27;6204:2;;6260:6;6252;6245:22;6204:2;6305;6292:16;6331:2;6323:6;6320:14;6317:2;;;6352:6;6344;6337:22;6317:2;6402:7;6397:2;6388:6;6384:2;6380:15;6376:24;6373:37;6370:2;;;6428:6;6420;6413:22;6370:2;6464;6456:11;;;;;6486:6;;-1:-1:-1;5946:552:1;;-1:-1:-1;;;;5946:552:1:o;6503:480::-;6572:6;6625:2;6613:9;6604:7;6600:23;6596:32;6593:2;;;6646:6;6638;6631:22;6593:2;6691:9;6678:23;-1:-1:-1;;;;;6716:6:1;6713:30;6710:2;;;6761:6;6753;6746:22;6710:2;6789:22;;6842:4;6834:13;;6830:27;-1:-1:-1;6820:2:1;;6876:6;6868;6861:22;6820:2;6904:73;6969:7;6964:2;6951:16;6946:2;6942;6938:11;6904:73;:::i;7183:257::-;7224:3;7262:5;7256:12;7289:6;7284:3;7277:19;7305:63;7361:6;7354:4;7349:3;7345:14;7338:4;7331:5;7327:16;7305:63;:::i;:::-;7422:2;7401:15;-1:-1:-1;;7397:29:1;7388:39;;;;7429:4;7384:50;;7232:208;-1:-1:-1;;7232:208:1:o;8183:1531::-;8407:3;8445:6;8439:13;8471:4;8484:51;8528:6;8523:3;8518:2;8510:6;8506:15;8484:51;:::i;:::-;8598:13;;8557:16;;;;8620:55;8598:13;8557:16;8642:15;;;8620:55;:::i;:::-;8766:13;;8697:20;;;8737:3;;8826:1;8848:18;;;;8901;;;;8928:2;;9006:4;8996:8;8992:19;8980:31;;8928:2;9069;9059:8;9056:16;9036:18;9033:40;9030:2;;;-1:-1:-1;;;9096:33:1;;9152:4;9149:1;9142:15;9182:4;9103:3;9170:17;9030:2;9213:18;9240:110;;;;9364:1;9359:330;;;;9206:483;;9240:110;-1:-1:-1;;9275:24:1;;9261:39;;9320:20;;;;-1:-1:-1;9240:110:1;;9359:330;25934:4;25953:17;;;26003:4;25987:21;;9454:3;9470:169;9484:8;9481:1;9478:15;9470:169;;;9566:14;;9551:13;;;9544:37;9609:16;;;;9501:10;;9470:169;;;9474:3;;9670:8;9663:5;9659:20;9652:27;;9206:483;-1:-1:-1;9705:3:1;;8415:1299;-1:-1:-1;;;;;;;;;;;8415:1299:1:o;10137:488::-;-1:-1:-1;;;;;10406:15:1;;;10388:34;;10458:15;;10453:2;10438:18;;10431:43;10505:2;10490:18;;10483:34;;;10553:3;10548:2;10533:18;;10526:31;;;10331:4;;10574:45;;10599:19;;10591:6;10574:45;:::i;:::-;10566:53;10340:285;-1:-1:-1;;;;;;10340:285:1:o;10630:385::-;10862:1;10858;10853:3;10849:11;10845:19;10837:6;10833:32;10822:9;10815:51;10902:6;10897:2;10886:9;10882:18;10875:34;10945:2;10940;10929:9;10925:18;10918:30;10796:4;10965:44;11005:2;10994:9;10990:18;10982:6;10965:44;:::i;:::-;10957:52;10805:210;-1:-1:-1;;;;;10805:210:1:o;11020:635::-;11191:2;11243:21;;;11313:13;;11216:18;;;11335:22;;;11162:4;;11191:2;11414:15;;;;11388:2;11373:18;;;11162:4;11460:169;11474:6;11471:1;11468:13;11460:169;;;11535:13;;11523:26;;11604:15;;;;11569:12;;;;11496:1;11489:9;11460:169;;;-1:-1:-1;11646:3:1;;11171:484;-1:-1:-1;;;;;;11171:484:1:o;12709:219::-;12858:2;12847:9;12840:21;12821:4;12878:44;12918:2;12907:9;12903:18;12895:6;12878:44;:::i;13337:414::-;13539:2;13521:21;;;13578:2;13558:18;;;13551:30;13617:34;13612:2;13597:18;;13590:62;-1:-1:-1;;;13683:2:1;13668:18;;13661:48;13741:3;13726:19;;13511:240::o;21179:356::-;21381:2;21363:21;;;21400:18;;;21393:30;21459:34;21454:2;21439:18;;21432:62;21526:2;21511:18;;21353:182::o;25607:275::-;25678:2;25672:9;25743:2;25724:13;;-1:-1:-1;;25720:27:1;25708:40;;-1:-1:-1;;;;;25763:34:1;;25799:22;;;25760:62;25757:2;;;25825:18;;:::i;:::-;25861:2;25854:22;25652:230;;-1:-1:-1;25652:230:1:o;26019:253::-;26059:3;-1:-1:-1;;;;;26148:2:1;26145:1;26141:10;26178:2;26175:1;26171:10;26209:3;26205:2;26201:12;26196:3;26193:21;26190:2;;;26217:18;;:::i;:::-;26253:13;;26067:205;-1:-1:-1;;;;26067:205:1:o;26277:128::-;26317:3;26348:1;26344:6;26341:1;26338:13;26335:2;;;26354:18;;:::i;:::-;-1:-1:-1;26390:9:1;;26325:80::o;26410:120::-;26450:1;26476;26466:2;;26481:18;;:::i;:::-;-1:-1:-1;26515:9:1;;26456:74::o;26535:246::-;26575:4;-1:-1:-1;;;;;26688:10:1;;;;26658;;26710:12;;;26707:2;;;26725:18;;:::i;:::-;26762:13;;26584:197;-1:-1:-1;;;26584:197:1:o;26786:125::-;26826:4;26854:1;26851;26848:8;26845:2;;;26859:18;;:::i;:::-;-1:-1:-1;26896:9:1;;26835:76::o;26916:258::-;26988:1;26998:113;27012:6;27009:1;27006:13;26998:113;;;27088:11;;;27082:18;27069:11;;;27062:39;27034:2;27027:10;26998:113;;;27129:6;27126:1;27123:13;27120:2;;;-1:-1:-1;;27164:1:1;27146:16;;27139:27;26969:205::o;27179:136::-;27218:3;27246:5;27236:2;;27255:18;;:::i;:::-;-1:-1:-1;;;27291:18:1;;27226:89::o;27320:380::-;27399:1;27395:12;;;;27442;;;27463:2;;27517:4;27509:6;27505:17;27495:27;;27463:2;27570;27562:6;27559:14;27539:18;27536:38;27533:2;;;27616:10;27611:3;27607:20;27604:1;27597:31;27651:4;27648:1;27641:15;27679:4;27676:1;27669:15;27533:2;;27375:325;;;:::o;27705:135::-;27744:3;-1:-1:-1;;27765:17:1;;27762:2;;;27785:18;;:::i;:::-;-1:-1:-1;27832:1:1;27821:13;;27752:88::o;27845:112::-;27877:1;27903;27893:2;;27908:18;;:::i;:::-;-1:-1:-1;27942:9:1;;27883:74::o;27962:127::-;28023:10;28018:3;28014:20;28011:1;28004:31;28054:4;28051:1;28044:15;28078:4;28075:1;28068:15;28094:127;28155:10;28150:3;28146:20;28143:1;28136:31;28186:4;28183:1;28176:15;28210:4;28207:1;28200:15;28226:127;28287:10;28282:3;28278:20;28275:1;28268:31;28318:4;28315:1;28308:15;28342:4;28339:1;28332:15;28358:118;28444:5;28437:13;28430:21;28423:5;28420:32;28410:2;;28466:1;28463;28456:12;28481:131;-1:-1:-1;;;;;;28555:32:1;;28545:43;;28535:2;;28602:1;28599;28592:12

Swarm Source

ipfs://87aa85241c1a85e9fa2a9ac9a59f2893feca7091f47a2591a196718ab8f159dd
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.