ETH Price: $2,918.45 (+3.49%)
 

Overview

TokenID

163

Total Transfers

-

Market

Onchain Market Cap

$0.00

Circulating Supply Market Cap

-
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:
TimeTravelers

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Multiple files format)

File 21 of 21: TimeTravelers.sol
// SPDX-License-Identifier: MIT
/*
.___________. __  .___  ___.  _______                                                                
|           ||  | |   \/   | |   ____|                                                               
`---|  |----`|  | |  \  /  | |  |__                                                                  
    |  |     |  | |  |\/|  | |   __|                                                                 
    |  |     |  | |  |  |  | |  |____                                                                
    |__|     |__| |__|  |__| |_______|                                                               
                                                                                                     
.___________..______          ___   ____    ____  _______  __       _______ .______          _______.
|           ||   _  \        /   \  \   \  /   / |   ____||  |     |   ____||   _  \        /       |
`---|  |----`|  |_)  |      /  ^  \  \   \/   /  |  |__   |  |     |  |__   |  |_)  |      |   (----`
    |  |     |      /      /  /_\  \  \      /   |   __|  |  |     |   __|  |      /        \   \    
    |  |     |  |\  \----./  _____  \  \    /    |  |____ |  `----.|  |____ |  |\  \----.----)   |   
    |__|     | _| `._____/__/     \__\  \__/     |_______||_______||_______|| _| `._____|_______/    ⠀⠀⠀⠀⠀⠀                                                                                  
*/
pragma solidity >= 0.8 .9 < 0.9 .0;

import './ERC721AQueryable.sol';
import './Ownable.sol';
import './ReentrancyGuard.sol';
import './SignedTokenVerifier.sol';
import './Pausable.sol';
import './PaymentSplitter.sol';

contract TimeTravelers is ERC721AQueryable, Ownable, ReentrancyGuard, SignedTokenVerifier, Pausable, PaymentSplitter {
  using Strings for uint256;

  string public uriPrefix = '';
  uint256 public cost = 0.006 ether;
  uint256 public maxSupply = 222;
  bool public wlPaused = true;

  mapping(address => bool) public minted;
  string private uriSuffix = '.json';
  address[] _payees = [0xf2f28e73efe05Ddff965449Ae95199ad4a8e96B1, 0xEC46982882CD8b6082A30C086A180444d3759f75, 0x0dC2dAE0674e602EafCC9758150C86a1b19ce4Ea, 0xEC586cca941B63568Aca13A9e3861bf425A704F1];
  uint256[] _shares = [25, 25, 25, 25];

  constructor(address _signer) ERC721A("TimeTravelers", "TT") PaymentSplitter(_payees, _shares) {
    _setSigner(_signer);
  }

  modifier mintCompliance(uint256 _mintAmount) {
    require(totalSupply() + _mintAmount <= maxSupply, 'Max supply exceeded!');
    _;
  }

  modifier mintPriceCompliance(uint256 _mintAmount) {
    require(msg.value >= cost * _mintAmount, 'Insufficient funds!');
    _;
  }

  function mint() public payable mintCompliance(1) mintPriceCompliance(1) whenNotPaused {
    _safeMint(_msgSender(), 1);
  }

  function whitelistMint(bytes calldata _token, string calldata _salt) public payable mintCompliance(1) mintPriceCompliance(1) nonReentrant {
    require(!wlPaused, "Paused");
    require(verifyTokenForAddress(_salt, _token, msg.sender), "Unauthorized");
    require(!minted[msg.sender], "Token already minted!");
    _safeMint(msg.sender, 1);
    minted[msg.sender] = true;
  }

  function teamMint(uint256 _teamAmount) external onlyOwner {
    require(totalSupply() + _teamAmount <= maxSupply, 'Max supply exceeded!');
    _safeMint(_msgSender(), _teamAmount);
  }

  function airdrop(uint256 _mintAmount, address _receiver) public mintCompliance(_mintAmount) onlyOwner {
    _safeMint(_receiver, _mintAmount);
  }

  function airdrops(address[] memory _addresses) public onlyOwner {
    for (uint i = 0; i < _addresses.length; i++) {
      airdrop(1, _addresses[i]);
    }
  }

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

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

  function setCost(uint256 _cost) public onlyOwner {
    cost = _cost;
  }

  function setWlPaused(bool _wlPaused) public onlyOwner {
    wlPaused = _wlPaused;
  }

  function setMaxSupply(uint256 _maxSupply) public onlyOwner {
    maxSupply = _maxSupply;
  }

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

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

  function withdraw() public onlyOwner nonReentrant {
    (bool os, ) = payable(owner()).call {value: address(this).balance}('');
    require(os);
  }

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

  function _startTokenId() internal view virtual override returns(uint256) {
    return 1;
  }
}

File 1 of 21: Address.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.5.0) (utils/Address.sol)

pragma solidity ^0.8.1;

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

        return account.code.length > 0;
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

File 2 of 21: Context.sol
// SPDX-License-Identifier: MIT
// 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 3 of 21: Counters.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/Counters.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

File 4 of 21: ECDSA.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts (last updated v4.7.0) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;

import "./Strings.sol";

/**
 * @dev Elliptic Curve Digital Signature Algorithm (ECDSA) operations.
 *
 * These functions can be used to verify that a message was signed by the holder
 * of the private keys of a given address.
 */
library ECDSA {
    enum RecoverError {
        NoError,
        InvalidSignature,
        InvalidSignatureLength,
        InvalidSignatureS,
        InvalidSignatureV
    }

    function _throwError(RecoverError error) private pure {
        if (error == RecoverError.NoError) {
            return; // no error: do nothing
        } else if (error == RecoverError.InvalidSignature) {
            revert("ECDSA: invalid signature");
        } else if (error == RecoverError.InvalidSignatureLength) {
            revert("ECDSA: invalid signature length");
        } else if (error == RecoverError.InvalidSignatureS) {
            revert("ECDSA: invalid signature 's' value");
        } else if (error == RecoverError.InvalidSignatureV) {
            revert("ECDSA: invalid signature 'v' value");
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature` or error string. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     *
     * Documentation for signature generation:
     * - with https://web3js.readthedocs.io/en/v1.3.4/web3-eth-accounts.html#sign[Web3.js]
     * - with https://docs.ethers.io/v5/api/signer/#Signer-signMessage[ethers]
     *
     * _Available since v4.3._
     */
    function tryRecover(bytes32 hash, bytes memory signature) internal pure returns (address, RecoverError) {
        // Check the signature length
        // - case 65: r,s,v signature (standard)
        // - case 64: r,vs signature (cf https://eips.ethereum.org/EIPS/eip-2098) _Available since v4.1._
        if (signature.length == 65) {
            bytes32 r;
            bytes32 s;
            uint8 v;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            /// @solidity memory-safe-assembly
            assembly {
                r := mload(add(signature, 0x20))
                s := mload(add(signature, 0x40))
                v := byte(0, mload(add(signature, 0x60)))
            }
            return tryRecover(hash, v, r, s);
        } else if (signature.length == 64) {
            bytes32 r;
            bytes32 vs;
            // ecrecover takes the signature parameters, and the only way to get them
            // currently is to use assembly.
            /// @solidity memory-safe-assembly
            assembly {
                r := mload(add(signature, 0x20))
                vs := mload(add(signature, 0x40))
            }
            return tryRecover(hash, r, vs);
        } else {
            return (address(0), RecoverError.InvalidSignatureLength);
        }
    }

    /**
     * @dev Returns the address that signed a hashed message (`hash`) with
     * `signature`. This address can then be used for verification purposes.
     *
     * The `ecrecover` EVM opcode allows for malleable (non-unique) signatures:
     * this function rejects them by requiring the `s` value to be in the lower
     * half order, and the `v` value to be either 27 or 28.
     *
     * IMPORTANT: `hash` _must_ be the result of a hash operation for the
     * verification to be secure: it is possible to craft signatures that
     * recover to arbitrary addresses for non-hashed data. A safe way to ensure
     * this is by receiving a hash of the original message (which may otherwise
     * be too long), and then calling {toEthSignedMessageHash} on it.
     */
    function recover(bytes32 hash, bytes memory signature) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, signature);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `r` and `vs` short-signature fields separately.
     *
     * See https://eips.ethereum.org/EIPS/eip-2098[EIP-2098 short signatures]
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address, RecoverError) {
        bytes32 s = vs & bytes32(0x7fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff);
        uint8 v = uint8((uint256(vs) >> 255) + 27);
        return tryRecover(hash, v, r, s);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `r and `vs` short-signature fields separately.
     *
     * _Available since v4.2._
     */
    function recover(
        bytes32 hash,
        bytes32 r,
        bytes32 vs
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, r, vs);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Overload of {ECDSA-tryRecover} that receives the `v`,
     * `r` and `s` signature fields separately.
     *
     * _Available since v4.3._
     */
    function tryRecover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address, RecoverError) {
        // EIP-2 still allows signature malleability for ecrecover(). Remove this possibility and make the signature
        // unique. Appendix F in the Ethereum Yellow paper (https://ethereum.github.io/yellowpaper/paper.pdf), defines
        // the valid range for s in (301): 0 < s < secp256k1n ÷ 2 + 1, and for v in (302): v ∈ {27, 28}. Most
        // signatures from current libraries generate a unique signature with an s-value in the lower half order.
        //
        // If your library generates malleable signatures, such as s-values in the upper range, calculate a new s-value
        // with 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141 - s1 and flip v from 27 to 28 or
        // vice versa. If your library also generates signatures with 0/1 for v instead 27/28, add 27 to v to accept
        // these malleable signatures as well.
        if (uint256(s) > 0x7FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF5D576E7357A4501DDFE92F46681B20A0) {
            return (address(0), RecoverError.InvalidSignatureS);
        }
        if (v != 27 && v != 28) {
            return (address(0), RecoverError.InvalidSignatureV);
        }

        // If the signature is valid (and not malleable), return the signer address
        address signer = ecrecover(hash, v, r, s);
        if (signer == address(0)) {
            return (address(0), RecoverError.InvalidSignature);
        }

        return (signer, RecoverError.NoError);
    }

    /**
     * @dev Overload of {ECDSA-recover} that receives the `v`,
     * `r` and `s` signature fields separately.
     */
    function recover(
        bytes32 hash,
        uint8 v,
        bytes32 r,
        bytes32 s
    ) internal pure returns (address) {
        (address recovered, RecoverError error) = tryRecover(hash, v, r, s);
        _throwError(error);
        return recovered;
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from a `hash`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes32 hash) internal pure returns (bytes32) {
        // 32 is the length in bytes of hash,
        // enforced by the type signature above
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n32", hash));
    }

    /**
     * @dev Returns an Ethereum Signed Message, created from `s`. This
     * produces hash corresponding to the one signed with the
     * https://eth.wiki/json-rpc/API#eth_sign[`eth_sign`]
     * JSON-RPC method as part of EIP-191.
     *
     * See {recover}.
     */
    function toEthSignedMessageHash(bytes memory s) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19Ethereum Signed Message:\n", Strings.toString(s.length), s));
    }

    /**
     * @dev Returns an Ethereum Signed Typed Data, created from a
     * `domainSeparator` and a `structHash`. This produces hash corresponding
     * to the one signed with the
     * https://eips.ethereum.org/EIPS/eip-712[`eth_signTypedData`]
     * JSON-RPC method as part of EIP-712.
     *
     * See {recover}.
     */
    function toTypedDataHash(bytes32 domainSeparator, bytes32 structHash) internal pure returns (bytes32) {
        return keccak256(abi.encodePacked("\x19\x01", domainSeparator, structHash));
    }
}

File 5 of 21: ERC165.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/introspection/ERC165.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

File 6 of 21: ERC721A.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v3.3.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;

import './IERC721A.sol';
import './IERC721Receiver.sol';
import './Address.sol';
import './Context.sol';
import './Strings.sol';
import './ERC165.sol';

/**
 * @dev Implementation of https://eips.ethereum.org/EIPS/eip-721[ERC721] Non-Fungible Token Standard, including
 * the Metadata extension. Built to optimize for lower gas during batch mints.
 *
 * Assumes serials are sequentially minted starting at _startTokenId() (defaults to 0, e.g. 0, 1, 2, 3..).
 *
 * Assumes that an owner cannot have more than 2**64 - 1 (max value of uint64) of supply.
 *
 * Assumes that the maximum token id cannot exceed 2**256 - 1 (max value of uint256).
 */
contract ERC721A is Context, ERC165, IERC721A {
    using Address for address;
    using Strings for uint256;

    // The tokenId of the next token to be minted.
    uint256 internal _currentIndex;

    // The number of tokens burned.
    uint256 internal _burnCounter;

    // 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) internal _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;

    constructor(string memory name_, string memory symbol_) {
        _name = name_;
        _symbol = symbol_;
        _currentIndex = _startTokenId();
    }

    /**
     * To change the starting tokenId, please override this function.
     */
    function _startTokenId() internal view virtual returns (uint256) {
        return 0;
    }

    /**
     * @dev Burned tokens are calculated here, use _totalMinted() if you want to count just minted tokens.
     */
    function totalSupply() public view override returns (uint256) {
        // Counter underflow is impossible as _burnCounter cannot be incremented
        // more than _currentIndex - _startTokenId() times
        unchecked {
            return _currentIndex - _burnCounter - _startTokenId();
        }
    }

    /**
     * Returns the total amount of tokens minted in the contract.
     */
    function _totalMinted() internal view returns (uint256) {
        // Counter underflow is impossible as _currentIndex does not decrement,
        // and it is initialized to _startTokenId()
        unchecked {
            return _currentIndex - _startTokenId();
        }
    }

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

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view override returns (uint256) {
        if (owner == address(0)) revert BalanceQueryForZeroAddress();
        return uint256(_addressData[owner].balance);
    }

    /**
     * Returns the number of tokens minted by `owner`.
     */
    function _numberMinted(address owner) internal view returns (uint256) {
        return uint256(_addressData[owner].numberMinted);
    }

    /**
     * Returns the number of tokens burned by or on behalf of `owner`.
     */
    function _numberBurned(address owner) internal view returns (uint256) {
        return uint256(_addressData[owner].numberBurned);
    }

    /**
     * Returns the auxillary data for `owner`. (e.g. number of whitelist mint slots used).
     */
    function _getAux(address owner) internal view returns (uint64) {
        return _addressData[owner].aux;
    }

    /**
     * Sets the auxillary data for `owner`. (e.g. number of whitelist mint slots used).
     * If there are multiple variables, please pack them into a uint64.
     */
    function _setAux(address owner, uint64 aux) internal {
        _addressData[owner].aux = aux;
    }

    /**
     * Gas spent here starts off proportional to the maximum mint batch size.
     * It gradually moves to O(1) as tokens get transferred around in the collection over time.
     */
    function _ownershipOf(uint256 tokenId) internal view returns (TokenOwnership memory) {
        uint256 curr = tokenId;

        unchecked {
            if (_startTokenId() <= curr) if (curr < _currentIndex) {
                TokenOwnership memory ownership = _ownerships[curr];
                if (!ownership.burned) {
                    if (ownership.addr != address(0)) {
                        return ownership;
                    }
                    // Invariant:
                    // There will always be an ownership that has an address and is not burned
                    // before an ownership that does not have an address and is not burned.
                    // Hence, curr will not underflow.
                    while (true) {
                        curr--;
                        ownership = _ownerships[curr];
                        if (ownership.addr != address(0)) {
                            return ownership;
                        }
                    }
                }
            }
        }
        revert OwnerQueryForNonexistentToken();
    }

    /**
     * @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) {
        if (!_exists(tokenId)) revert URIQueryForNonexistentToken();

        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 = ERC721A.ownerOf(tokenId);
        if (to == owner) revert ApprovalToCurrentOwner();

        if (_msgSender() != owner) if(!isApprovedForAll(owner, _msgSender())) {
            revert ApprovalCallerNotOwnerNorApproved();
        }

        _approve(to, tokenId, owner);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view override returns (address) {
        if (!_exists(tokenId)) revert ApprovalQueryForNonexistentToken();

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        if (operator == _msgSender()) revert ApproveToCaller();

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

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

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

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

    /**
     * @dev See {IERC721-safeTransferFrom}.
     */
    function safeTransferFrom(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) public virtual override {
        _transfer(from, to, tokenId);
        if (to.isContract()) if(!_checkContractOnERC721Received(from, to, tokenId, _data)) {
            revert TransferToNonERC721ReceiverImplementer();
        }
    }

    /**
     * @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 _startTokenId() <= tokenId && tokenId < _currentIndex && !_ownerships[tokenId].burned;
    }

    /**
     * @dev Equivalent to `_safeMint(to, quantity, '')`.
     */
    function _safeMint(address to, uint256 quantity) internal {
        _safeMint(to, quantity, '');
    }

    /**
     * @dev Safely mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - If `to` refers to a smart contract, it must implement
     *   {IERC721Receiver-onERC721Received}, which is called for each safe transfer.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event.
     */
    function _safeMint(
        address to,
        uint256 quantity,
        bytes memory _data
    ) internal {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();

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

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            _addressData[to].balance += uint64(quantity);
            _addressData[to].numberMinted += uint64(quantity);

            _ownerships[startTokenId].addr = to;
            _ownerships[startTokenId].startTimestamp = uint64(block.timestamp);

            uint256 updatedIndex = startTokenId;
            uint256 end = updatedIndex + quantity;

            if (to.isContract()) {
                do {
                    emit Transfer(address(0), to, updatedIndex);
                    if (!_checkContractOnERC721Received(address(0), to, updatedIndex++, _data)) {
                        revert TransferToNonERC721ReceiverImplementer();
                    }
                } while (updatedIndex < end);
                // Reentrancy protection
                if (_currentIndex != startTokenId) revert();
            } else {
                do {
                    emit Transfer(address(0), to, updatedIndex++);
                } while (updatedIndex < end);
            }
            _currentIndex = updatedIndex;
        }
        _afterTokenTransfers(address(0), to, startTokenId, quantity);
    }

    /**
     * @dev Mints `quantity` tokens and transfers them to `to`.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `quantity` must be greater than 0.
     *
     * Emits a {Transfer} event.
     */
    function _mint(address to, uint256 quantity) internal {
        uint256 startTokenId = _currentIndex;
        if (to == address(0)) revert MintToZeroAddress();
        if (quantity == 0) revert MintZeroQuantity();

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

        // Overflows are incredibly unrealistic.
        // balance or numberMinted overflow if current value of either + quantity > 1.8e19 (2**64) - 1
        // updatedIndex overflows if _currentIndex + quantity > 1.2e77 (2**256) - 1
        unchecked {
            _addressData[to].balance += uint64(quantity);
            _addressData[to].numberMinted += uint64(quantity);

            _ownerships[startTokenId].addr = to;
            _ownerships[startTokenId].startTimestamp = uint64(block.timestamp);

            uint256 updatedIndex = startTokenId;
            uint256 end = updatedIndex + quantity;

            do {
                emit Transfer(address(0), to, updatedIndex++);
            } while (updatedIndex < end);

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

        if (prevOwnership.addr != from) revert TransferFromIncorrectOwner();

        bool isApprovedOrOwner = (_msgSender() == from ||
            isApprovedForAll(from, _msgSender()) ||
            getApproved(tokenId) == _msgSender());

        if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        if (to == address(0)) revert TransferToZeroAddress();

        _beforeTokenTransfers(from, to, tokenId, 1);

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

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
        unchecked {
            _addressData[from].balance -= 1;
            _addressData[to].balance += 1;

            TokenOwnership storage currSlot = _ownerships[tokenId];
            currSlot.addr = to;
            currSlot.startTimestamp = 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;
            TokenOwnership storage nextSlot = _ownerships[nextTokenId];
            if (nextSlot.addr == address(0)) {
                // This will suffice for checking _exists(nextTokenId),
                // as a burned slot cannot contain the zero address.
                if (nextTokenId != _currentIndex) {
                    nextSlot.addr = from;
                    nextSlot.startTimestamp = prevOwnership.startTimestamp;
                }
            }
        }

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

    /**
     * @dev Equivalent to `_burn(tokenId, false)`.
     */
    function _burn(uint256 tokenId) internal virtual {
        _burn(tokenId, false);
    }

    /**
     * @dev Destroys `tokenId`.
     * The approval is cleared when the token is burned.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     *
     * Emits a {Transfer} event.
     */
    function _burn(uint256 tokenId, bool approvalCheck) internal virtual {
        TokenOwnership memory prevOwnership = _ownershipOf(tokenId);

        address from = prevOwnership.addr;

        if (approvalCheck) {
            bool isApprovedOrOwner = (_msgSender() == from ||
                isApprovedForAll(from, _msgSender()) ||
                getApproved(tokenId) == _msgSender());

            if (!isApprovedOrOwner) revert TransferCallerNotOwnerNorApproved();
        }

        _beforeTokenTransfers(from, address(0), tokenId, 1);

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

        // Underflow of the sender's balance is impossible because we check for
        // ownership above and the recipient's balance can't realistically overflow.
        // Counter overflow is incredibly unrealistic as tokenId would have to be 2**256.
        unchecked {
            AddressData storage addressData = _addressData[from];
            addressData.balance -= 1;
            addressData.numberBurned += 1;

            // Keep track of who burned the token, and the timestamp of burning.
            TokenOwnership storage currSlot = _ownerships[tokenId];
            currSlot.addr = from;
            currSlot.startTimestamp = uint64(block.timestamp);
            currSlot.burned = true;

            // If the ownership slot of tokenId+1 is not explicitly set, that means the burn initiator owns it.
            // Set the slot of tokenId+1 explicitly in storage to maintain correctness for ownerOf(tokenId+1) calls.
            uint256 nextTokenId = tokenId + 1;
            TokenOwnership storage nextSlot = _ownerships[nextTokenId];
            if (nextSlot.addr == address(0)) {
                // This will suffice for checking _exists(nextTokenId),
                // as a burned slot cannot contain the zero address.
                if (nextTokenId != _currentIndex) {
                    nextSlot.addr = from;
                    nextSlot.startTimestamp = prevOwnership.startTimestamp;
                }
            }
        }

        emit Transfer(from, address(0), tokenId);
        _afterTokenTransfers(from, address(0), tokenId, 1);

        // Overflow not possible, as _burnCounter cannot be exceed _currentIndex times.
        unchecked {
            _burnCounter++;
        }
    }

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

    /**
     * @dev Internal function to invoke {IERC721Receiver-onERC721Received} on a target 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 _checkContractOnERC721Received(
        address from,
        address to,
        uint256 tokenId,
        bytes memory _data
    ) private returns (bool) {
        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 TransferToNonERC721ReceiverImplementer();
            } else {
                assembly {
                    revert(add(32, reason), mload(reason))
                }
            }
        }
    }

    /**
     * @dev Hook that is called before a set of serially-ordered token ids are about to be transferred. This includes minting.
     * And also called before burning one token.
     *
     * 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`.
     * - When `to` is zero, `tokenId` will be burned by `from`.
     * - `from` and `to` are never both zero.
     */
    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.
     * And also called after one token has been burned.
     *
     * 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` has been
     * transferred to `to`.
     * - When `from` is zero, `tokenId` has been minted for `to`.
     * - When `to` is zero, `tokenId` has been burned by `from`.
     * - `from` and `to` are never both zero.
     */
    function _afterTokenTransfers(
        address from,
        address to,
        uint256 startTokenId,
        uint256 quantity
    ) internal virtual {}
}

File 7 of 21: ERC721AQueryable.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v3.3.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;

import './IERC721AQueryable.sol';
import './ERC721A.sol';

/**
 * @title ERC721A Queryable
 * @dev ERC721A subclass with convenience query functions.
 */
abstract contract ERC721AQueryable is ERC721A, IERC721AQueryable {
    /**
     * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting.
     *
     * If the `tokenId` is out of bounds:
     *   - `addr` = `address(0)`
     *   - `startTimestamp` = `0`
     *   - `burned` = `false`
     *
     * If the `tokenId` is burned:
     *   - `addr` = `<Address of owner before token was burned>`
     *   - `startTimestamp` = `<Timestamp when token was burned>`
     *   - `burned = `true`
     *
     * Otherwise:
     *   - `addr` = `<Address of owner>`
     *   - `startTimestamp` = `<Timestamp of start of ownership>`
     *   - `burned = `false`
     */
    function explicitOwnershipOf(uint256 tokenId) public view override returns (TokenOwnership memory) {
        TokenOwnership memory ownership;
        if (tokenId < _startTokenId() || tokenId >= _currentIndex) {
            return ownership;
        }
        ownership = _ownerships[tokenId];
        if (ownership.burned) {
            return ownership;
        }
        return _ownershipOf(tokenId);
    }

    /**
     * @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order.
     * See {ERC721AQueryable-explicitOwnershipOf}
     */
    function explicitOwnershipsOf(uint256[] memory tokenIds) external view override returns (TokenOwnership[] memory) {
        unchecked {
            uint256 tokenIdsLength = tokenIds.length;
            TokenOwnership[] memory ownerships = new TokenOwnership[](tokenIdsLength);
            for (uint256 i; i != tokenIdsLength; ++i) {
                ownerships[i] = explicitOwnershipOf(tokenIds[i]);
            }
            return ownerships;
        }
    }

    /**
     * @dev Returns an array of token IDs owned by `owner`,
     * in the range [`start`, `stop`)
     * (i.e. `start <= tokenId < stop`).
     *
     * This function allows for tokens to be queried if the collection
     * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}.
     *
     * Requirements:
     *
     * - `start` < `stop`
     */
    function tokensOfOwnerIn(
        address owner,
        uint256 start,
        uint256 stop
    ) external view override returns (uint256[] memory) {
        unchecked {
            if (start >= stop) revert InvalidQueryRange();
            uint256 tokenIdsIdx;
            uint256 stopLimit = _currentIndex;
            // Set `start = max(start, _startTokenId())`.
            if (start < _startTokenId()) {
                start = _startTokenId();
            }
            // Set `stop = min(stop, _currentIndex)`.
            if (stop > stopLimit) {
                stop = stopLimit;
            }
            uint256 tokenIdsMaxLength = balanceOf(owner);
            // Set `tokenIdsMaxLength = min(balanceOf(owner), stop - start)`,
            // to cater for cases where `balanceOf(owner)` is too big.
            if (start < stop) {
                uint256 rangeLength = stop - start;
                if (rangeLength < tokenIdsMaxLength) {
                    tokenIdsMaxLength = rangeLength;
                }
            } else {
                tokenIdsMaxLength = 0;
            }
            uint256[] memory tokenIds = new uint256[](tokenIdsMaxLength);
            if (tokenIdsMaxLength == 0) {
                return tokenIds;
            }
            // We need to call `explicitOwnershipOf(start)`,
            // because the slot at `start` may not be initialized.
            TokenOwnership memory ownership = explicitOwnershipOf(start);
            address currOwnershipAddr;
            // If the starting slot exists (i.e. not burned), initialize `currOwnershipAddr`.
            // `ownership.address` will not be zero, as `start` is clamped to the valid token ID range.
            if (!ownership.burned) {
                currOwnershipAddr = ownership.addr;
            }
            for (uint256 i = start; i != stop && tokenIdsIdx != tokenIdsMaxLength; ++i) {
                ownership = _ownerships[i];
                if (ownership.burned) {
                    continue;
                }
                if (ownership.addr != address(0)) {
                    currOwnershipAddr = ownership.addr;
                }
                if (currOwnershipAddr == owner) {
                    tokenIds[tokenIdsIdx++] = i;
                }
            }
            // Downsize the array to fit.
            assembly {
                mstore(tokenIds, tokenIdsIdx)
            }
            return tokenIds;
        }
    }

    /**
     * @dev Returns an array of token IDs owned by `owner`.
     *
     * This function scans the ownership mapping and is O(totalSupply) in complexity.
     * It is meant to be called off-chain.
     *
     * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into
     * multiple smaller scans if the collection is large enough to cause
     * an out-of-gas error (10K pfp collections should be fine).
     */
    function tokensOfOwner(address owner) external view override returns (uint256[] memory) {
        unchecked {
            uint256 tokenIdsIdx;
            address currOwnershipAddr;
            uint256 tokenIdsLength = balanceOf(owner);
            uint256[] memory tokenIds = new uint256[](tokenIdsLength);
            TokenOwnership memory ownership;
            for (uint256 i = _startTokenId(); tokenIdsIdx != tokenIdsLength; ++i) {
                ownership = _ownerships[i];
                if (ownership.burned) {
                    continue;
                }
                if (ownership.addr != address(0)) {
                    currOwnershipAddr = ownership.addr;
                }
                if (currOwnershipAddr == owner) {
                    tokenIds[tokenIdsIdx++] = i;
                }
            }
            return tokenIds;
        }
    }
}

File 8 of 21: IERC165.sol
// SPDX-License-Identifier: MIT
// 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 9 of 21: IERC721.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

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

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

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

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

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

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

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

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

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

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

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

File 10 of 21: IERC721A.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v3.3.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;

import './IERC721.sol';
import './IERC721Metadata.sol';

/**
 * @dev Interface of an ERC721A compliant contract.
 */
interface IERC721A is IERC721, IERC721Metadata {
    /**
     * The caller must own the token or be an approved operator.
     */
    error ApprovalCallerNotOwnerNorApproved();

    /**
     * The token does not exist.
     */
    error ApprovalQueryForNonexistentToken();

    /**
     * The caller cannot approve to their own address.
     */
    error ApproveToCaller();

    /**
     * The caller cannot approve to the current owner.
     */
    error ApprovalToCurrentOwner();

    /**
     * Cannot query the balance for the zero address.
     */
    error BalanceQueryForZeroAddress();

    /**
     * Cannot mint to the zero address.
     */
    error MintToZeroAddress();

    /**
     * The quantity of tokens minted must be more than zero.
     */
    error MintZeroQuantity();

    /**
     * The token does not exist.
     */
    error OwnerQueryForNonexistentToken();

    /**
     * The caller must own the token or be an approved operator.
     */
    error TransferCallerNotOwnerNorApproved();

    /**
     * The token must be owned by `from`.
     */
    error TransferFromIncorrectOwner();

    /**
     * Cannot safely transfer to a contract that does not implement the ERC721Receiver interface.
     */
    error TransferToNonERC721ReceiverImplementer();

    /**
     * Cannot transfer to the zero address.
     */
    error TransferToZeroAddress();

    /**
     * The token does not exist.
     */
    error URIQueryForNonexistentToken();

    // Compiler will pack this into a single 256bit word.
    struct TokenOwnership {
        // The address of the owner.
        address addr;
        // Keeps track of the start time of ownership with minimal overhead for tokenomics.
        uint64 startTimestamp;
        // Whether the token has been burned.
        bool burned;
    }

    // Compiler will pack this into a single 256bit word.
    struct AddressData {
        // Realistically, 2**64-1 is more than enough.
        uint64 balance;
        // Keeps track of mint count with minimal overhead for tokenomics.
        uint64 numberMinted;
        // Keeps track of burn count with minimal overhead for tokenomics.
        uint64 numberBurned;
        // For miscellaneous variable(s) pertaining to the address
        // (e.g. number of whitelist mint slots used).
        // If there are multiple variables, please pack them into a uint64.
        uint64 aux;
    }

    /**
     * @dev Returns the total amount of tokens stored by the contract.
     * 
     * Burned tokens are calculated here, use `_totalMinted()` if you want to count just minted tokens.
     */
    function totalSupply() external view returns (uint256);
}

File 11 of 21: IERC721AQueryable.sol
// SPDX-License-Identifier: MIT
// ERC721A Contracts v3.3.0
// Creator: Chiru Labs

pragma solidity ^0.8.4;

import './IERC721A.sol';

/**
 * @dev Interface of an ERC721AQueryable compliant contract.
 */
interface IERC721AQueryable is IERC721A {
    /**
     * Invalid query range (`start` >= `stop`).
     */
    error InvalidQueryRange();

    /**
     * @dev Returns the `TokenOwnership` struct at `tokenId` without reverting.
     *
     * If the `tokenId` is out of bounds:
     *   - `addr` = `address(0)`
     *   - `startTimestamp` = `0`
     *   - `burned` = `false`
     *
     * If the `tokenId` is burned:
     *   - `addr` = `<Address of owner before token was burned>`
     *   - `startTimestamp` = `<Timestamp when token was burned>`
     *   - `burned = `true`
     *
     * Otherwise:
     *   - `addr` = `<Address of owner>`
     *   - `startTimestamp` = `<Timestamp of start of ownership>`
     *   - `burned = `false`
     */
    function explicitOwnershipOf(uint256 tokenId) external view returns (TokenOwnership memory);

    /**
     * @dev Returns an array of `TokenOwnership` structs at `tokenIds` in order.
     * See {ERC721AQueryable-explicitOwnershipOf}
     */
    function explicitOwnershipsOf(uint256[] memory tokenIds) external view returns (TokenOwnership[] memory);

    /**
     * @dev Returns an array of token IDs owned by `owner`,
     * in the range [`start`, `stop`)
     * (i.e. `start <= tokenId < stop`).
     *
     * This function allows for tokens to be queried if the collection
     * grows too big for a single call of {ERC721AQueryable-tokensOfOwner}.
     *
     * Requirements:
     *
     * - `start` < `stop`
     */
    function tokensOfOwnerIn(
        address owner,
        uint256 start,
        uint256 stop
    ) external view returns (uint256[] memory);

    /**
     * @dev Returns an array of token IDs owned by `owner`.
     *
     * This function scans the ownership mapping and is O(totalSupply) in complexity.
     * It is meant to be called off-chain.
     *
     * See {ERC721AQueryable-tokensOfOwnerIn} for splitting the scan into
     * multiple smaller scans if the collection is large enough to cause
     * an out-of-gas error (10K pfp collections should be fine).
     */
    function tokensOfOwner(address owner) external view returns (uint256[] memory);
}

File 12 of 21: IERC721Metadata.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (token/ERC721/extensions/IERC721Metadata.sol)

pragma solidity ^0.8.0;

import "./IERC721.sol";

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

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

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

File 13 of 21: IERC721Receiver.sol
// SPDX-License-Identifier: MIT
// 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 14 of 21: Ownable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (access/Ownable.sol)

pragma solidity ^0.8.0;

import "./Context.sol";

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

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor() {
        _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 15 of 21: Pausable.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/Pausable.sol)

pragma solidity ^0.8.0;

import "./Context.sol";

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

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

    bool private _paused;

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

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

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

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

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

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

File 16 of 21: PaymentSplitter.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./Address.sol";
import "./Context.sol";
import "./SafeMath.sol";
import "./ReentrancyGuard.sol";


contract PaymentSplitter is Context, ReentrancyGuard {
    event PayeeAdded(address account, uint256 shares);
    event PaymentReleased(address to, uint256 amount);

    uint256 private _totalShares;
    uint256 private _totalReleased;

    mapping(address => uint256) private _shares;
    mapping(address => uint256) private _released;
    address[] private _payees;

    /**
     * @dev Creates an instance of `PaymentSplitter` where each account in `payees` is assigned the number of shares at
     * the matching position in the `shares` array.
     *
     * All addresses in `payees` must be non-zero. Both arrays must have the same non-zero length, and there must be no
     * duplicates in `payees`.
     */
    constructor(address[] memory payees, uint256[] memory shares_) payable {
        require(payees.length == shares_.length, "PaymentSplitter: payees and shares length mismatch");
        require(payees.length > 0, "PaymentSplitter: no payees");

        for (uint256 i = 0; i < payees.length; i++) {
            _addPayee(payees[i], shares_[i]);
        }
    }

    /**
     * @dev Getter for the amount of shares held by an account.
     */
    function shares(address account) public view returns (uint256) {
        return _shares[account];
    }

    /**
     * @dev Triggers a transfer to `account` of the amount of Ether they are owed, according to their percentage of the
     * total shares and their previous withdrawals.
     */
    function release(address payable account) nonReentrant public virtual {
        require(_shares[account] > 0, "PaymentSplitter: account has no shares");

        uint256 totalReceived = address(this).balance + _totalReleased;
        uint256 payment = (totalReceived * _shares[account]) / _totalShares - _released[account];
        require(payment != 0, "PaymentSplitter: account is not due payment");

        _released[account] = _released[account] + payment;
        _totalReleased = _totalReleased + payment;

        Address.sendValue(account, payment);
        emit PaymentReleased(account, payment);
    }

    /**
     * @dev Add a new payee to the contract.
     * @param account The address of the payee to add.
     * @param shares_ The number of shares owned by the payee.
     */
    function _addPayee(address account, uint256 shares_) private {
        require(account != address(0), "PaymentSplitter: account is the zero address");
        require(shares_ > 0, "PaymentSplitter: shares are 0");
        require(_shares[account] == 0, "PaymentSplitter: account already has shares");

        _payees.push(account);
        _shares[account] = shares_;
        _totalShares = _totalShares + shares_;
        emit PayeeAdded(account, shares_);
    } 
    
}

File 17 of 21: ReentrancyGuard.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (security/ReentrancyGuard.sol)

pragma solidity ^0.8.0;

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

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

    uint256 private _status;

    constructor() {
        _status = _NOT_ENTERED;
    }

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

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

        _;

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

File 18 of 21: SafeMath.sol
// SPDX-License-Identifier: MIT
// OpenZeppelin Contracts v4.4.1 (utils/math/SafeMath.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

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

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

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

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

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

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

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

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

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

File 19 of 21: SignedTokenVerifier.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.4;

import "./Ownable.sol";
import "./ECDSA.sol";

contract SignedTokenVerifier {
    using ECDSA for bytes32;

    address private _signer;
    event SignerUpdated(address newSigner);

    constructor() {
    }

    function _setSigner(address _newSigner) internal {
        _signer = _newSigner;
        emit SignerUpdated(_signer);
    }

    function _hash(string calldata _salt, address _address)
        internal
        view
        returns (bytes32)
    {
        return keccak256(abi.encode(_salt, address(this), _address));
    }

    function _recover(bytes32 hash, bytes memory token)
        internal
        pure
        returns (address)
    {
        return hash.toEthSignedMessageHash().recover(token);
    }

    function getAddress(
        string calldata _salt,
        bytes calldata _token,
        address _address
    ) internal view returns (address) {
        return _recover(_hash(_salt, _address), _token);
    }

    function verifyTokenForAddress(
        string calldata _salt,
        bytes calldata _token,
        address _address
    ) internal view returns (bool) {
        return getAddress(_salt, _token, _address) == _signer;
    }
}

File 20 of 21: Strings.sol
// SPDX-License-Identifier: MIT
// 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);
    }

    function toHexString(bytes memory data) internal pure returns(string memory) {
        bytes memory str = new bytes(2 + data.length * 2);
        str[0] = "0";
        str[1] = "x";
        for (uint i = 0; i < data.length; i++) {
          str[2+i*2] = _HEX_SYMBOLS[uint(uint8(data[i] >> 4))];
            str[3+i*2] = _HEX_SYMBOLS[uint(uint8(data[i] & 0x0f))];
        }
        return string(str);
    }

   function toString(address account) internal pure returns(string memory) {
    return toHexString(abi.encodePacked(account));
   }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"address","name":"_signer","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"inputs":[],"name":"ApprovalCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"ApprovalQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"ApprovalToCurrentOwner","type":"error"},{"inputs":[],"name":"ApproveToCaller","type":"error"},{"inputs":[],"name":"BalanceQueryForZeroAddress","type":"error"},{"inputs":[],"name":"InvalidQueryRange","type":"error"},{"inputs":[],"name":"MintToZeroAddress","type":"error"},{"inputs":[],"name":"MintZeroQuantity","type":"error"},{"inputs":[],"name":"OwnerQueryForNonexistentToken","type":"error"},{"inputs":[],"name":"TransferCallerNotOwnerNorApproved","type":"error"},{"inputs":[],"name":"TransferFromIncorrectOwner","type":"error"},{"inputs":[],"name":"TransferToNonERC721ReceiverImplementer","type":"error"},{"inputs":[],"name":"TransferToZeroAddress","type":"error"},{"inputs":[],"name":"URIQueryForNonexistentToken","type":"error"},{"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":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"},{"indexed":false,"internalType":"uint256","name":"shares","type":"uint256"}],"name":"PayeeAdded","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"amount","type":"uint256"}],"name":"PaymentReleased","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"newSigner","type":"address"}],"name":"SignerUpdated","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[{"internalType":"uint256","name":"_mintAmount","type":"uint256"},{"internalType":"address","name":"_receiver","type":"address"}],"name":"airdrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address[]","name":"_addresses","type":"address[]"}],"name":"airdrops","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"cost","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"explicitOwnershipOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"}],"internalType":"struct IERC721A.TokenOwnership","name":"","type":"tuple"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256[]","name":"tokenIds","type":"uint256[]"}],"name":"explicitOwnershipsOf","outputs":[{"components":[{"internalType":"address","name":"addr","type":"address"},{"internalType":"uint64","name":"startTimestamp","type":"uint64"},{"internalType":"bool","name":"burned","type":"bool"}],"internalType":"struct IERC721A.TokenOwnership[]","name":"","type":"tuple[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"maxSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"mint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"address","name":"","type":"address"}],"name":"minted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address payable","name":"account","type":"address"}],"name":"release","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_cost","type":"uint256"}],"name":"setCost","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_maxSupply","type":"uint256"}],"name":"setMaxSupply","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":[{"internalType":"bool","name":"_wlPaused","type":"bool"}],"name":"setWlPaused","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"account","type":"address"}],"name":"shares","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_teamAmount","type":"uint256"}],"name":"teamMint","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"_tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"tokensOfOwner","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"start","type":"uint256"},{"internalType":"uint256","name":"stop","type":"uint256"}],"name":"tokensOfOwnerIn","outputs":[{"internalType":"uint256[]","name":"","type":"uint256[]"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalSupply","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"transferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"newOwner","type":"address"}],"name":"transferOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"uriPrefix","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes","name":"_token","type":"bytes"},{"internalType":"string","name":"_salt","type":"string"}],"name":"whitelistMint","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"wlPaused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"}]

60a06040819052600060808190526200001b9160109162000679565b50661550f7dca7000060115560de6012556013805460ff1916600117905560408051808201909152600580825264173539b7b760d91b6020909201918252620000679160159162000679565b506040805160808101825273f2f28e73efe05ddff965449ae95199ad4a8e96b1815273ec46982882cd8b6082a30c086a180444d3759f756020820152730dc2dae0674e602eafcc9758150c86a1b19ce4ea9181019190915273ec586cca941b63568aca13a9e3861bf425a704f16060820152620000e990601690600462000708565b506040805160808101825260198082526020820181905291810182905260608101919091526200011e90601790600462000760565b503480156200012c57600080fd5b50604051620039ba380380620039ba8339810160408190526200014f91620007ba565b6016805480602002602001604051908101604052809291908181526020018280548015620001a757602002820191906000526020600020905b81546001600160a01b0316815260019091019060200180831162000188575b50505050506017805480602002602001604051908101604052809291908181526020018280548015620001fa57602002820191906000526020600020905b815481526020019060010190808311620001e5575b50505050506040518060400160405280600d81526020016c54696d6554726176656c65727360981b81525060405180604001604052806002815260200161151560f21b81525081600290805190602001906200025892919062000679565b5080516200026e90600390602084019062000679565b50506001600055506200028133620003e5565b6001600955600a805460ff60a01b1916600160a01b17905580518251146200030b5760405162461bcd60e51b815260206004820152603260248201527f5061796d656e7453706c69747465723a2070617965657320616e6420736861726044820152710cae640d8cadccee8d040dad2e6dac2e8c6d60731b60648201526084015b60405180910390fd5b60008251116200035e5760405162461bcd60e51b815260206004820152601a60248201527f5061796d656e7453706c69747465723a206e6f20706179656573000000000000604482015260640162000302565b60005b8251811015620003ca57620003b5838281518110620003845762000384620007ec565b6020026020010151838381518110620003a157620003a1620007ec565b60200260200101516200043760201b60201c565b80620003c18162000818565b91505062000361565b505050620003de816200062560201b60201c565b506200088e565b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b038216620004a45760405162461bcd60e51b815260206004820152602c60248201527f5061796d656e7453706c69747465723a206163636f756e74206973207468652060448201526b7a65726f206164647265737360a01b606482015260840162000302565b60008111620004f65760405162461bcd60e51b815260206004820152601d60248201527f5061796d656e7453706c69747465723a20736861726573206172652030000000604482015260640162000302565b6001600160a01b0382166000908152600d602052604090205415620005725760405162461bcd60e51b815260206004820152602b60248201527f5061796d656e7453706c69747465723a206163636f756e7420616c726561647960448201526a206861732073686172657360a81b606482015260840162000302565b600f8054600181019091557f8d1108e10bcb7c27dddfc02ed9d693a074039d026cf4ea4240b40f7d581ac8020180546001600160a01b0319166001600160a01b0384169081179091556000908152600d60205260409020819055600b54620005dc90829062000836565b600b55604080516001600160a01b0384168152602081018390527f40c340f65e17194d14ddddb073d3c9f888e3cb52b5aae0c6c7706b4fbc905fac910160405180910390a15050565b600a80546001600160a01b0319166001600160a01b0383169081179091556040519081527f5553331329228fbd4123164423717a4a7539f6dfa1c3279a923b98fd681a6c739060200160405180910390a150565b828054620006879062000851565b90600052602060002090601f016020900481019282620006ab5760008555620006f6565b82601f10620006c657805160ff1916838001178555620006f6565b82800160010185558215620006f6579182015b82811115620006f6578251825591602001919060010190620006d9565b5062000704929150620007a3565b5090565b828054828255906000526020600020908101928215620006f6579160200282015b82811115620006f657825182546001600160a01b0319166001600160a01b0390911617825560209092019160019091019062000729565b828054828255906000526020600020908101928215620006f6579160200282015b82811115620006f6578251829060ff1690559160200191906001019062000781565b5b80821115620007045760008155600101620007a4565b600060208284031215620007cd57600080fd5b81516001600160a01b0381168114620007e557600080fd5b9392505050565b634e487b7160e01b600052603260045260246000fd5b634e487b7160e01b600052601160045260246000fd5b60006000198214156200082f576200082f62000802565b5060010190565b600082198211156200084c576200084c62000802565b500190565b600181811c908216806200086657607f821691505b602082108114156200088857634e487b7160e01b600052602260045260246000fd5b50919050565b61311c806200089e6000396000f3fe60806040526004361061023b5760003560e01c80636352211e1161012e57806399a2557a116100ab578063c87b56dd1161006f578063c87b56dd146106a7578063ce7c2ac2146106c7578063d5abeb01146106fd578063e985e9c514610713578063f2fde38b1461073357600080fd5b806399a2557a146105fa578063a22cb4651461061a578063b88d4fde1461063a578063bc63f02e1461065a578063c23dc68f1461067a57600080fd5b80637ec4a659116100f25780637ec4a659146105675780638462151c146105875780638b6adcca146105b45780638da5cb5b146105c757806395d89b41146105e557600080fd5b80636352211e146104d85780636f8b44b0146104f857806370a0823114610518578063715018a61461053857806372e537eb1461054d57600080fd5b806323b872dd116101bc57806344a0d68a1161018057806344a0d68a146104375780634e99d51e146104575780635bbb2177146104775780635c975abb146104a457806362b99ad4146104c357600080fd5b806323b872dd146103a25780632fbba115146103c25780633a8d7a37146103e25780633ccfd60b1461040257806342842e0e1461041757600080fd5b806313faede61161020357806313faede6146102f957806316ba10e01461031d57806318160ddd1461033d57806319165587146103525780631e7269c51461037257600080fd5b806301ffc9a71461024057806306fdde0314610275578063081812fc14610297578063095ea7b3146102cf5780631249c58b146102f1575b600080fd5b34801561024c57600080fd5b5061026061025b366004612768565b610753565b60405190151581526020015b60405180910390f35b34801561028157600080fd5b5061028a6107a5565b60405161026c91906127dd565b3480156102a357600080fd5b506102b76102b23660046127f0565b610837565b6040516001600160a01b03909116815260200161026c565b3480156102db57600080fd5b506102ef6102ea36600461281e565b61087b565b005b6102ef610902565b34801561030557600080fd5b5061030f60115481565b60405190815260200161026c565b34801561032957600080fd5b506102ef6103383660046128e7565b6109f2565b34801561034957600080fd5b5061030f610a2f565b34801561035e57600080fd5b506102ef61036d36600461292f565b610a3d565b34801561037e57600080fd5b5061026061038d36600461292f565b60146020526000908152604090205460ff1681565b3480156103ae57600080fd5b506102ef6103bd36600461294c565b610c3b565b3480156103ce57600080fd5b506102ef6103dd3660046127f0565b610c46565b3480156103ee57600080fd5b506102ef6103fd3660046129a2565b610cb1565b34801561040e57600080fd5b506102ef610cee565b34801561042357600080fd5b506102ef61043236600461294c565b610db9565b34801561044357600080fd5b506102ef6104523660046127f0565b610dd4565b34801561046357600080fd5b506102ef6104723660046129e0565b610e03565b34801561048357600080fd5b50610497610492366004612a7e565b610e6f565b60405161026c9190612b03565b3480156104b057600080fd5b50600a54600160a01b900460ff16610260565b3480156104cf57600080fd5b5061028a610f35565b3480156104e457600080fd5b506102b76104f33660046127f0565b610fc3565b34801561050457600080fd5b506102ef6105133660046127f0565b610fd5565b34801561052457600080fd5b5061030f61053336600461292f565b611004565b34801561054457600080fd5b506102ef611052565b34801561055957600080fd5b506013546102609060ff1681565b34801561057357600080fd5b506102ef6105823660046128e7565b611088565b34801561059357600080fd5b506105a76105a236600461292f565b6110c5565b60405161026c9190612b6d565b6102ef6105c2366004612be6565b611212565b3480156105d357600080fd5b506008546001600160a01b03166102b7565b3480156105f157600080fd5b5061028a6113d4565b34801561060657600080fd5b506105a7610615366004612c51565b6113e3565b34801561062657600080fd5b506102ef610635366004612c86565b6115a9565b34801561064657600080fd5b506102ef610655366004612cbb565b61163f565b34801561066657600080fd5b506102ef610675366004612d3a565b611689565b34801561068657600080fd5b5061069a6106953660046127f0565b6116f2565b60405161026c9190612d6a565b3480156106b357600080fd5b5061028a6106c23660046127f0565b6117ac565b3480156106d357600080fd5b5061030f6106e236600461292f565b6001600160a01b03166000908152600d602052604090205490565b34801561070957600080fd5b5061030f60125481565b34801561071f57600080fd5b5061026061072e366004612d9f565b611879565b34801561073f57600080fd5b506102ef61074e36600461292f565b6118a7565b60006001600160e01b031982166380ac58cd60e01b148061078457506001600160e01b03198216635b5e139f60e01b145b8061079f57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600280546107b490612dcd565b80601f01602080910402602001604051908101604052809291908181526020018280546107e090612dcd565b801561082d5780601f106108025761010080835404028352916020019161082d565b820191906000526020600020905b81548152906001019060200180831161081057829003601f168201915b5050505050905090565b60006108428261193f565b61085f576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b600061088682610fc3565b9050806001600160a01b0316836001600160a01b031614156108bb5760405163250fdee360e21b815260040160405180910390fd5b336001600160a01b038216146108f2576108d58133611879565b6108f2576040516367d9dca160e11b815260040160405180910390fd5b6108fd838383611978565b505050565b600160125481610910610a2f565b61091a9190612e1e565b11156109415760405162461bcd60e51b815260040161093890612e36565b60405180910390fd5b6001806011546109519190612e64565b3410156109965760405162461bcd60e51b8152602060048201526013602482015272496e73756666696369656e742066756e64732160681b6044820152606401610938565b600a54600160a01b900460ff16156109e35760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610938565b6109ee3360016119d4565b5050565b6008546001600160a01b03163314610a1c5760405162461bcd60e51b815260040161093890612e83565b80516109ee9060159060208401906126b9565b600154600054036000190190565b60026009541415610a605760405162461bcd60e51b815260040161093890612eb8565b60026009556001600160a01b0381166000908152600d6020526040902054610ad95760405162461bcd60e51b815260206004820152602660248201527f5061796d656e7453706c69747465723a206163636f756e7420686173206e6f2060448201526573686172657360d01b6064820152608401610938565b6000600c5447610ae99190612e1e565b6001600160a01b0383166000908152600e6020908152604080832054600b54600d909352908320549394509192610b209085612e64565b610b2a9190612f05565b610b349190612f19565b905080610b975760405162461bcd60e51b815260206004820152602b60248201527f5061796d656e7453706c69747465723a206163636f756e74206973206e6f742060448201526a191d59481c185e5b595b9d60aa1b6064820152608401610938565b6001600160a01b0383166000908152600e6020526040902054610bbb908290612e1e565b6001600160a01b0384166000908152600e6020526040902055600c54610be2908290612e1e565b600c55610bef83826119ee565b604080516001600160a01b0385168152602081018390527fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b056910160405180910390a15050600160095550565b6108fd838383611b07565b6008546001600160a01b03163314610c705760405162461bcd60e51b815260040161093890612e83565b60125481610c7c610a2f565b610c869190612e1e565b1115610ca45760405162461bcd60e51b815260040161093890612e36565b610cae33826119d4565b50565b6008546001600160a01b03163314610cdb5760405162461bcd60e51b815260040161093890612e83565b6013805460ff1916911515919091179055565b6008546001600160a01b03163314610d185760405162461bcd60e51b815260040161093890612e83565b60026009541415610d3b5760405162461bcd60e51b815260040161093890612eb8565b60026009556000610d546008546001600160a01b031690565b6001600160a01b03164760405160006040518083038185875af1925050503d8060008114610d9e576040519150601f19603f3d011682016040523d82523d6000602084013e610da3565b606091505b5050905080610db157600080fd5b506001600955565b6108fd8383836040518060200160405280600081525061163f565b6008546001600160a01b03163314610dfe5760405162461bcd60e51b815260040161093890612e83565b601155565b6008546001600160a01b03163314610e2d5760405162461bcd60e51b815260040161093890612e83565b60005b81518110156109ee57610e5d6001838381518110610e5057610e50612f30565b6020026020010151611689565b80610e6781612f46565b915050610e30565b80516060906000816001600160401b03811115610e8e57610e8e61284a565b604051908082528060200260200182016040528015610ed957816020015b6040805160608101825260008082526020808301829052928201528252600019909201910181610eac5790505b50905060005b828114610f2d57610f08858281518110610efb57610efb612f30565b60200260200101516116f2565b828281518110610f1a57610f1a612f30565b6020908102919091010152600101610edf565b509392505050565b60108054610f4290612dcd565b80601f0160208091040260200160405190810160405280929190818152602001828054610f6e90612dcd565b8015610fbb5780601f10610f9057610100808354040283529160200191610fbb565b820191906000526020600020905b815481529060010190602001808311610f9e57829003601f168201915b505050505081565b6000610fce82611cf4565b5192915050565b6008546001600160a01b03163314610fff5760405162461bcd60e51b815260040161093890612e83565b601255565b60006001600160a01b03821661102d576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b6008546001600160a01b0316331461107c5760405162461bcd60e51b815260040161093890612e83565b6110866000611e16565b565b6008546001600160a01b031633146110b25760405162461bcd60e51b815260040161093890612e83565b80516109ee9060109060208401906126b9565b606060008060006110d585611004565b90506000816001600160401b038111156110f1576110f161284a565b60405190808252806020026020018201604052801561111a578160200160208202803683370190505b509050611140604080516060810182526000808252602082018190529181019190915290565b60015b83861461120657600081815260046020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff161580159282019290925292506111a9576111fe565b81516001600160a01b0316156111be57815194505b876001600160a01b0316856001600160a01b031614156111fe57808387806001019850815181106111f1576111f1612f30565b6020026020010181815250505b600101611143565b50909695505050505050565b600160125481611220610a2f565b61122a9190612e1e565b11156112485760405162461bcd60e51b815260040161093890612e36565b6001806011546112589190612e64565b34101561129d5760405162461bcd60e51b8152602060048201526013602482015272496e73756666696369656e742066756e64732160681b6044820152606401610938565b600260095414156112c05760405162461bcd60e51b815260040161093890612eb8565b600260095560135460ff16156113015760405162461bcd60e51b815260206004820152600660248201526514185d5cd95960d21b6044820152606401610938565b61130e8484888833611e68565b6113495760405162461bcd60e51b815260206004820152600c60248201526b155b985d5d1a1bdc9a5e995960a21b6044820152606401610938565b3360009081526014602052604090205460ff16156113a15760405162461bcd60e51b8152602060048201526015602482015274546f6b656e20616c7265616479206d696e7465642160581b6044820152606401610938565b6113ac3360016119d4565b5050336000908152601460205260409020805460ff1916600190811790915560095550505050565b6060600380546107b490612dcd565b606081831061140557604051631960ccad60e11b815260040160405180910390fd5b60008054600185101561141757600194505b80841115611423578093505b600061142e87611004565b90508486101561144d5785850381811015611447578091505b50611451565b5060005b6000816001600160401b0381111561146b5761146b61284a565b604051908082528060200260200182016040528015611494578160200160208202803683370190505b509050816114a75793506115a292505050565b60006114b2886116f2565b9050600081604001516114c3575080515b885b8881141580156114d55750848714155b1561159657600081815260046020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff161580159282019290925293506115395761158e565b82516001600160a01b03161561154e57825191505b8a6001600160a01b0316826001600160a01b0316141561158e578084888060010199508151811061158157611581612f30565b6020026020010181815250505b6001016114c5565b50505092835250909150505b9392505050565b6001600160a01b0382163314156115d35760405163b06307db60e01b815260040160405180910390fd5b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b61164a848484611b07565b6001600160a01b0383163b156116835761166684848484611e98565b611683576040516368d2bf6b60e11b815260040160405180910390fd5b50505050565b8160125481611696610a2f565b6116a09190612e1e565b11156116be5760405162461bcd60e51b815260040161093890612e36565b6008546001600160a01b031633146116e85760405162461bcd60e51b815260040161093890612e83565b6108fd82846119d4565b6040805160608082018352600080835260208084018290528385018290528451928301855281835282018190529281019290925290600183108061173857506000548310155b156117435792915050565b50600082815260046020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff1615801592820192909252906117a35792915050565b6115a283611cf4565b60606117b78261193f565b61181b5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610938565b6000611825611f90565b9050600081511161184557604051806020016040528060008152506115a2565b8061184f84611f9f565b601560405160200161186393929190612f61565b6040516020818303038152906040529392505050565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b6008546001600160a01b031633146118d15760405162461bcd60e51b815260040161093890612e83565b6001600160a01b0381166119365760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610938565b610cae81611e16565b600081600111158015611953575060005482105b801561079f575050600090815260046020526040902054600160e01b900460ff161590565b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6109ee82826040518060200160405280600081525061209c565b80471015611a3e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610938565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611a8b576040519150601f19603f3d011682016040523d82523d6000602084013e611a90565b606091505b50509050806108fd5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610938565b6000611b1282611cf4565b9050836001600160a01b031681600001516001600160a01b031614611b495760405162a1148160e81b815260040160405180910390fd5b6000336001600160a01b0386161480611b675750611b678533611879565b80611b82575033611b7784610837565b6001600160a01b0316145b905080611ba257604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b038416611bc957604051633a954ecd60e21b815260040160405180910390fd5b611bd560008487611978565b6001600160a01b038581166000908152600560209081526040808320805467ffffffffffffffff198082166001600160401b0392831660001901831617909255898616808652838620805493841693831660019081018416949094179055898652600490945282852080546001600160e01b031916909417600160a01b42909216919091021783558701808452922080549193909116611ca9576000548214611ca957805460208601516001600160401b0316600160a01b026001600160e01b03199091166001600160a01b038a16171781555b50505082846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050505050565b60408051606081018252600080825260208201819052918101919091528180600111611dfd57600054811015611dfd57600081815260046020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff16151591810182905290611dfb5780516001600160a01b031615611d92579392505050565b5060001901600081815260046020908152604091829020825160608101845290546001600160a01b038116808352600160a01b82046001600160401b031693830193909352600160e01b900460ff1615159281019290925215611df6579392505050565b611d92565b505b604051636f96cda160e11b815260040160405180910390fd5b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600a546000906001600160a01b0316611e848787878787612260565b6001600160a01b0316149695505050505050565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290611ecd903390899088908890600401613025565b602060405180830381600087803b158015611ee757600080fd5b505af1925050508015611f17575060408051601f3d908101601f19168201909252611f1491810190613058565b60015b611f72573d808015611f45576040519150601f19603f3d011682016040523d82523d6000602084013e611f4a565b606091505b508051611f6a576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b6060601080546107b490612dcd565b606081611fc35750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611fed5780611fd781612f46565b9150611fe69050600a83612f05565b9150611fc7565b6000816001600160401b038111156120075761200761284a565b6040519080825280601f01601f191660200182016040528015612031576020820181803683370190505b5090505b8415611f8857612046600183612f19565b9150612053600a86613075565b61205e906030612e1e565b60f81b81838151811061207357612073612f30565b60200101906001600160f81b031916908160001a905350612095600a86612f05565b9450612035565b6000546001600160a01b0384166120c557604051622e076360e81b815260040160405180910390fd5b826120e35760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038416600081815260056020908152604080832080546fffffffffffffffffffffffffffffffff1981166001600160401b038083168b0181169182176801000000000000000067ffffffffffffffff1990941690921783900481168b01811690920217909155858452600490925290912080546001600160e01b0319168317600160a01b42909316929092029190911790558190818501903b1561220b575b60405182906001600160a01b038816906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a46121d46000878480600101955087611e98565b6121f1576040516368d2bf6b60e11b815260040160405180910390fd5b80821061218957826000541461220657600080fd5b612250565b5b6040516001830192906001600160a01b038816906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a480821061220c575b5060009081556116839085838684565b60006122ac6122708787856122b6565b85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506122ee92505050565b9695505050505050565b6000838330846040516020016122cf9493929190613089565b6040516020818303038152906040528051906020012090509392505050565b60006115a28261234b856040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90600080600061235b8585612368565b91509150610f2d816123d8565b60008082516041141561239f5760208301516040840151606085015160001a61239387828585612593565b945094505050506123d1565b8251604014156123c957602083015160408401516123be868383612680565b9350935050506123d1565b506000905060025b9250929050565b60008160048111156123ec576123ec6130d0565b14156123f55750565b6001816004811115612409576124096130d0565b14156124575760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610938565b600281600481111561246b5761246b6130d0565b14156124b95760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610938565b60038160048111156124cd576124cd6130d0565b14156125265760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610938565b600481600481111561253a5761253a6130d0565b1415610cae5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610938565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156125ca5750600090506003612677565b8460ff16601b141580156125e257508460ff16601c14155b156125f35750600090506004612677565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612647573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661267057600060019250925050612677565b9150600090505b94509492505050565b6000806001600160ff1b0383168161269d60ff86901c601b612e1e565b90506126ab87828885612593565b935093505050935093915050565b8280546126c590612dcd565b90600052602060002090601f0160209004810192826126e7576000855561272d565b82601f1061270057805160ff191683800117855561272d565b8280016001018555821561272d579182015b8281111561272d578251825591602001919060010190612712565b5061273992915061273d565b5090565b5b80821115612739576000815560010161273e565b6001600160e01b031981168114610cae57600080fd5b60006020828403121561277a57600080fd5b81356115a281612752565b60005b838110156127a0578181015183820152602001612788565b838111156116835750506000910152565b600081518084526127c9816020860160208601612785565b601f01601f19169290920160200192915050565b6020815260006115a260208301846127b1565b60006020828403121561280257600080fd5b5035919050565b6001600160a01b0381168114610cae57600080fd5b6000806040838503121561283157600080fd5b823561283c81612809565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156128885761288861284a565b604052919050565b60006001600160401b038311156128a9576128a961284a565b6128bc601f8401601f1916602001612860565b90508281528383830111156128d057600080fd5b828260208301376000602084830101529392505050565b6000602082840312156128f957600080fd5b81356001600160401b0381111561290f57600080fd5b8201601f8101841361292057600080fd5b611f8884823560208401612890565b60006020828403121561294157600080fd5b81356115a281612809565b60008060006060848603121561296157600080fd5b833561296c81612809565b9250602084013561297c81612809565b929592945050506040919091013590565b8035801515811461299d57600080fd5b919050565b6000602082840312156129b457600080fd5b6115a28261298d565b60006001600160401b038211156129d6576129d661284a565b5060051b60200190565b600060208083850312156129f357600080fd5b82356001600160401b03811115612a0957600080fd5b8301601f81018513612a1a57600080fd5b8035612a2d612a28826129bd565b612860565b81815260059190911b82018301908381019087831115612a4c57600080fd5b928401925b82841015612a73578335612a6481612809565b82529284019290840190612a51565b979650505050505050565b60006020808385031215612a9157600080fd5b82356001600160401b03811115612aa757600080fd5b8301601f81018513612ab857600080fd5b8035612ac6612a28826129bd565b81815260059190911b82018301908381019087831115612ae557600080fd5b928401925b82841015612a7357833582529284019290840190612aea565b6020808252825182820181905260009190848201906040850190845b8181101561120657612b5a83855180516001600160a01b031682526020808201516001600160401b0316908301526040908101511515910152565b9284019260609290920191600101612b1f565b6020808252825182820181905260009190848201906040850190845b8181101561120657835183529284019291840191600101612b89565b60008083601f840112612bb757600080fd5b5081356001600160401b03811115612bce57600080fd5b6020830191508360208285010111156123d157600080fd5b60008060008060408587031215612bfc57600080fd5b84356001600160401b0380821115612c1357600080fd5b612c1f88838901612ba5565b90965094506020870135915080821115612c3857600080fd5b50612c4587828801612ba5565b95989497509550505050565b600080600060608486031215612c6657600080fd5b8335612c7181612809565b95602085013595506040909401359392505050565b60008060408385031215612c9957600080fd5b8235612ca481612809565b9150612cb26020840161298d565b90509250929050565b60008060008060808587031215612cd157600080fd5b8435612cdc81612809565b93506020850135612cec81612809565b92506040850135915060608501356001600160401b03811115612d0e57600080fd5b8501601f81018713612d1f57600080fd5b612d2e87823560208401612890565b91505092959194509250565b60008060408385031215612d4d57600080fd5b823591506020830135612d5f81612809565b809150509250929050565b81516001600160a01b031681526020808301516001600160401b0316908201526040808301511515908201526060810161079f565b60008060408385031215612db257600080fd5b8235612dbd81612809565b91506020830135612d5f81612809565b600181811c90821680612de157607f821691505b60208210811415612e0257634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b60008219821115612e3157612e31612e08565b500190565b6020808252601490820152734d617820737570706c792065786365656465642160601b604082015260600190565b6000816000190483118215151615612e7e57612e7e612e08565b500290565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b634e487b7160e01b600052601260045260246000fd5b600082612f1457612f14612eef565b500490565b600082821015612f2b57612f2b612e08565b500390565b634e487b7160e01b600052603260045260246000fd5b6000600019821415612f5a57612f5a612e08565b5060010190565b600084516020612f748285838a01612785565b855191840191612f878184848a01612785565b8554920191600090600181811c9080831680612fa457607f831692505b858310811415612fc257634e487b7160e01b85526022600452602485fd5b808015612fd65760018114612fe757613014565b60ff19851688528388019550613014565b60008b81526020902060005b8581101561300c5781548a820152908401908801612ff3565b505083880195505b50939b9a5050505050505050505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906122ac908301846127b1565b60006020828403121561306a57600080fd5b81516115a281612752565b60008261308457613084612eef565b500690565b6060815283606082015283856080830137600060808583018101919091526001600160a01b039384166020830152919092166040830152601f909201601f19160101919050565b634e487b7160e01b600052602160045260246000fdfea2646970667358221220bcd577c4a14cef22f29246cb8af8f63e324ea9784463cc02be707ee7cef72ce364736f6c634300080900330000000000000000000000008d10505d63581a18063bb1c94cb6e3caefd4c901

Deployed Bytecode

0x60806040526004361061023b5760003560e01c80636352211e1161012e57806399a2557a116100ab578063c87b56dd1161006f578063c87b56dd146106a7578063ce7c2ac2146106c7578063d5abeb01146106fd578063e985e9c514610713578063f2fde38b1461073357600080fd5b806399a2557a146105fa578063a22cb4651461061a578063b88d4fde1461063a578063bc63f02e1461065a578063c23dc68f1461067a57600080fd5b80637ec4a659116100f25780637ec4a659146105675780638462151c146105875780638b6adcca146105b45780638da5cb5b146105c757806395d89b41146105e557600080fd5b80636352211e146104d85780636f8b44b0146104f857806370a0823114610518578063715018a61461053857806372e537eb1461054d57600080fd5b806323b872dd116101bc57806344a0d68a1161018057806344a0d68a146104375780634e99d51e146104575780635bbb2177146104775780635c975abb146104a457806362b99ad4146104c357600080fd5b806323b872dd146103a25780632fbba115146103c25780633a8d7a37146103e25780633ccfd60b1461040257806342842e0e1461041757600080fd5b806313faede61161020357806313faede6146102f957806316ba10e01461031d57806318160ddd1461033d57806319165587146103525780631e7269c51461037257600080fd5b806301ffc9a71461024057806306fdde0314610275578063081812fc14610297578063095ea7b3146102cf5780631249c58b146102f1575b600080fd5b34801561024c57600080fd5b5061026061025b366004612768565b610753565b60405190151581526020015b60405180910390f35b34801561028157600080fd5b5061028a6107a5565b60405161026c91906127dd565b3480156102a357600080fd5b506102b76102b23660046127f0565b610837565b6040516001600160a01b03909116815260200161026c565b3480156102db57600080fd5b506102ef6102ea36600461281e565b61087b565b005b6102ef610902565b34801561030557600080fd5b5061030f60115481565b60405190815260200161026c565b34801561032957600080fd5b506102ef6103383660046128e7565b6109f2565b34801561034957600080fd5b5061030f610a2f565b34801561035e57600080fd5b506102ef61036d36600461292f565b610a3d565b34801561037e57600080fd5b5061026061038d36600461292f565b60146020526000908152604090205460ff1681565b3480156103ae57600080fd5b506102ef6103bd36600461294c565b610c3b565b3480156103ce57600080fd5b506102ef6103dd3660046127f0565b610c46565b3480156103ee57600080fd5b506102ef6103fd3660046129a2565b610cb1565b34801561040e57600080fd5b506102ef610cee565b34801561042357600080fd5b506102ef61043236600461294c565b610db9565b34801561044357600080fd5b506102ef6104523660046127f0565b610dd4565b34801561046357600080fd5b506102ef6104723660046129e0565b610e03565b34801561048357600080fd5b50610497610492366004612a7e565b610e6f565b60405161026c9190612b03565b3480156104b057600080fd5b50600a54600160a01b900460ff16610260565b3480156104cf57600080fd5b5061028a610f35565b3480156104e457600080fd5b506102b76104f33660046127f0565b610fc3565b34801561050457600080fd5b506102ef6105133660046127f0565b610fd5565b34801561052457600080fd5b5061030f61053336600461292f565b611004565b34801561054457600080fd5b506102ef611052565b34801561055957600080fd5b506013546102609060ff1681565b34801561057357600080fd5b506102ef6105823660046128e7565b611088565b34801561059357600080fd5b506105a76105a236600461292f565b6110c5565b60405161026c9190612b6d565b6102ef6105c2366004612be6565b611212565b3480156105d357600080fd5b506008546001600160a01b03166102b7565b3480156105f157600080fd5b5061028a6113d4565b34801561060657600080fd5b506105a7610615366004612c51565b6113e3565b34801561062657600080fd5b506102ef610635366004612c86565b6115a9565b34801561064657600080fd5b506102ef610655366004612cbb565b61163f565b34801561066657600080fd5b506102ef610675366004612d3a565b611689565b34801561068657600080fd5b5061069a6106953660046127f0565b6116f2565b60405161026c9190612d6a565b3480156106b357600080fd5b5061028a6106c23660046127f0565b6117ac565b3480156106d357600080fd5b5061030f6106e236600461292f565b6001600160a01b03166000908152600d602052604090205490565b34801561070957600080fd5b5061030f60125481565b34801561071f57600080fd5b5061026061072e366004612d9f565b611879565b34801561073f57600080fd5b506102ef61074e36600461292f565b6118a7565b60006001600160e01b031982166380ac58cd60e01b148061078457506001600160e01b03198216635b5e139f60e01b145b8061079f57506301ffc9a760e01b6001600160e01b03198316145b92915050565b6060600280546107b490612dcd565b80601f01602080910402602001604051908101604052809291908181526020018280546107e090612dcd565b801561082d5780601f106108025761010080835404028352916020019161082d565b820191906000526020600020905b81548152906001019060200180831161081057829003601f168201915b5050505050905090565b60006108428261193f565b61085f576040516333d1c03960e21b815260040160405180910390fd5b506000908152600660205260409020546001600160a01b031690565b600061088682610fc3565b9050806001600160a01b0316836001600160a01b031614156108bb5760405163250fdee360e21b815260040160405180910390fd5b336001600160a01b038216146108f2576108d58133611879565b6108f2576040516367d9dca160e11b815260040160405180910390fd5b6108fd838383611978565b505050565b600160125481610910610a2f565b61091a9190612e1e565b11156109415760405162461bcd60e51b815260040161093890612e36565b60405180910390fd5b6001806011546109519190612e64565b3410156109965760405162461bcd60e51b8152602060048201526013602482015272496e73756666696369656e742066756e64732160681b6044820152606401610938565b600a54600160a01b900460ff16156109e35760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b6044820152606401610938565b6109ee3360016119d4565b5050565b6008546001600160a01b03163314610a1c5760405162461bcd60e51b815260040161093890612e83565b80516109ee9060159060208401906126b9565b600154600054036000190190565b60026009541415610a605760405162461bcd60e51b815260040161093890612eb8565b60026009556001600160a01b0381166000908152600d6020526040902054610ad95760405162461bcd60e51b815260206004820152602660248201527f5061796d656e7453706c69747465723a206163636f756e7420686173206e6f2060448201526573686172657360d01b6064820152608401610938565b6000600c5447610ae99190612e1e565b6001600160a01b0383166000908152600e6020908152604080832054600b54600d909352908320549394509192610b209085612e64565b610b2a9190612f05565b610b349190612f19565b905080610b975760405162461bcd60e51b815260206004820152602b60248201527f5061796d656e7453706c69747465723a206163636f756e74206973206e6f742060448201526a191d59481c185e5b595b9d60aa1b6064820152608401610938565b6001600160a01b0383166000908152600e6020526040902054610bbb908290612e1e565b6001600160a01b0384166000908152600e6020526040902055600c54610be2908290612e1e565b600c55610bef83826119ee565b604080516001600160a01b0385168152602081018390527fdf20fd1e76bc69d672e4814fafb2c449bba3a5369d8359adf9e05e6fde87b056910160405180910390a15050600160095550565b6108fd838383611b07565b6008546001600160a01b03163314610c705760405162461bcd60e51b815260040161093890612e83565b60125481610c7c610a2f565b610c869190612e1e565b1115610ca45760405162461bcd60e51b815260040161093890612e36565b610cae33826119d4565b50565b6008546001600160a01b03163314610cdb5760405162461bcd60e51b815260040161093890612e83565b6013805460ff1916911515919091179055565b6008546001600160a01b03163314610d185760405162461bcd60e51b815260040161093890612e83565b60026009541415610d3b5760405162461bcd60e51b815260040161093890612eb8565b60026009556000610d546008546001600160a01b031690565b6001600160a01b03164760405160006040518083038185875af1925050503d8060008114610d9e576040519150601f19603f3d011682016040523d82523d6000602084013e610da3565b606091505b5050905080610db157600080fd5b506001600955565b6108fd8383836040518060200160405280600081525061163f565b6008546001600160a01b03163314610dfe5760405162461bcd60e51b815260040161093890612e83565b601155565b6008546001600160a01b03163314610e2d5760405162461bcd60e51b815260040161093890612e83565b60005b81518110156109ee57610e5d6001838381518110610e5057610e50612f30565b6020026020010151611689565b80610e6781612f46565b915050610e30565b80516060906000816001600160401b03811115610e8e57610e8e61284a565b604051908082528060200260200182016040528015610ed957816020015b6040805160608101825260008082526020808301829052928201528252600019909201910181610eac5790505b50905060005b828114610f2d57610f08858281518110610efb57610efb612f30565b60200260200101516116f2565b828281518110610f1a57610f1a612f30565b6020908102919091010152600101610edf565b509392505050565b60108054610f4290612dcd565b80601f0160208091040260200160405190810160405280929190818152602001828054610f6e90612dcd565b8015610fbb5780601f10610f9057610100808354040283529160200191610fbb565b820191906000526020600020905b815481529060010190602001808311610f9e57829003601f168201915b505050505081565b6000610fce82611cf4565b5192915050565b6008546001600160a01b03163314610fff5760405162461bcd60e51b815260040161093890612e83565b601255565b60006001600160a01b03821661102d576040516323d3ad8160e21b815260040160405180910390fd5b506001600160a01b03166000908152600560205260409020546001600160401b031690565b6008546001600160a01b0316331461107c5760405162461bcd60e51b815260040161093890612e83565b6110866000611e16565b565b6008546001600160a01b031633146110b25760405162461bcd60e51b815260040161093890612e83565b80516109ee9060109060208401906126b9565b606060008060006110d585611004565b90506000816001600160401b038111156110f1576110f161284a565b60405190808252806020026020018201604052801561111a578160200160208202803683370190505b509050611140604080516060810182526000808252602082018190529181019190915290565b60015b83861461120657600081815260046020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff161580159282019290925292506111a9576111fe565b81516001600160a01b0316156111be57815194505b876001600160a01b0316856001600160a01b031614156111fe57808387806001019850815181106111f1576111f1612f30565b6020026020010181815250505b600101611143565b50909695505050505050565b600160125481611220610a2f565b61122a9190612e1e565b11156112485760405162461bcd60e51b815260040161093890612e36565b6001806011546112589190612e64565b34101561129d5760405162461bcd60e51b8152602060048201526013602482015272496e73756666696369656e742066756e64732160681b6044820152606401610938565b600260095414156112c05760405162461bcd60e51b815260040161093890612eb8565b600260095560135460ff16156113015760405162461bcd60e51b815260206004820152600660248201526514185d5cd95960d21b6044820152606401610938565b61130e8484888833611e68565b6113495760405162461bcd60e51b815260206004820152600c60248201526b155b985d5d1a1bdc9a5e995960a21b6044820152606401610938565b3360009081526014602052604090205460ff16156113a15760405162461bcd60e51b8152602060048201526015602482015274546f6b656e20616c7265616479206d696e7465642160581b6044820152606401610938565b6113ac3360016119d4565b5050336000908152601460205260409020805460ff1916600190811790915560095550505050565b6060600380546107b490612dcd565b606081831061140557604051631960ccad60e11b815260040160405180910390fd5b60008054600185101561141757600194505b80841115611423578093505b600061142e87611004565b90508486101561144d5785850381811015611447578091505b50611451565b5060005b6000816001600160401b0381111561146b5761146b61284a565b604051908082528060200260200182016040528015611494578160200160208202803683370190505b509050816114a75793506115a292505050565b60006114b2886116f2565b9050600081604001516114c3575080515b885b8881141580156114d55750848714155b1561159657600081815260046020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff161580159282019290925293506115395761158e565b82516001600160a01b03161561154e57825191505b8a6001600160a01b0316826001600160a01b0316141561158e578084888060010199508151811061158157611581612f30565b6020026020010181815250505b6001016114c5565b50505092835250909150505b9392505050565b6001600160a01b0382163314156115d35760405163b06307db60e01b815260040160405180910390fd5b3360008181526007602090815260408083206001600160a01b03871680855290835292819020805460ff191686151590811790915590519081529192917f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a35050565b61164a848484611b07565b6001600160a01b0383163b156116835761166684848484611e98565b611683576040516368d2bf6b60e11b815260040160405180910390fd5b50505050565b8160125481611696610a2f565b6116a09190612e1e565b11156116be5760405162461bcd60e51b815260040161093890612e36565b6008546001600160a01b031633146116e85760405162461bcd60e51b815260040161093890612e83565b6108fd82846119d4565b6040805160608082018352600080835260208084018290528385018290528451928301855281835282018190529281019290925290600183108061173857506000548310155b156117435792915050565b50600082815260046020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff1615801592820192909252906117a35792915050565b6115a283611cf4565b60606117b78261193f565b61181b5760405162461bcd60e51b815260206004820152602f60248201527f4552433732314d657461646174613a2055524920717565727920666f72206e6f60448201526e3732bc34b9ba32b73a103a37b5b2b760891b6064820152608401610938565b6000611825611f90565b9050600081511161184557604051806020016040528060008152506115a2565b8061184f84611f9f565b601560405160200161186393929190612f61565b6040516020818303038152906040529392505050565b6001600160a01b03918216600090815260076020908152604080832093909416825291909152205460ff1690565b6008546001600160a01b031633146118d15760405162461bcd60e51b815260040161093890612e83565b6001600160a01b0381166119365760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b6064820152608401610938565b610cae81611e16565b600081600111158015611953575060005482105b801561079f575050600090815260046020526040902054600160e01b900460ff161590565b60008281526006602052604080822080546001600160a01b0319166001600160a01b0387811691821790925591518593918516917f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92591a4505050565b6109ee82826040518060200160405280600081525061209c565b80471015611a3e5760405162461bcd60e51b815260206004820152601d60248201527f416464726573733a20696e73756666696369656e742062616c616e63650000006044820152606401610938565b6000826001600160a01b03168260405160006040518083038185875af1925050503d8060008114611a8b576040519150601f19603f3d011682016040523d82523d6000602084013e611a90565b606091505b50509050806108fd5760405162461bcd60e51b815260206004820152603a60248201527f416464726573733a20756e61626c6520746f2073656e642076616c75652c207260448201527f6563697069656e74206d617920686176652072657665727465640000000000006064820152608401610938565b6000611b1282611cf4565b9050836001600160a01b031681600001516001600160a01b031614611b495760405162a1148160e81b815260040160405180910390fd5b6000336001600160a01b0386161480611b675750611b678533611879565b80611b82575033611b7784610837565b6001600160a01b0316145b905080611ba257604051632ce44b5f60e11b815260040160405180910390fd5b6001600160a01b038416611bc957604051633a954ecd60e21b815260040160405180910390fd5b611bd560008487611978565b6001600160a01b038581166000908152600560209081526040808320805467ffffffffffffffff198082166001600160401b0392831660001901831617909255898616808652838620805493841693831660019081018416949094179055898652600490945282852080546001600160e01b031916909417600160a01b42909216919091021783558701808452922080549193909116611ca9576000548214611ca957805460208601516001600160401b0316600160a01b026001600160e01b03199091166001600160a01b038a16171781555b50505082846001600160a01b0316866001600160a01b03167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050505050565b60408051606081018252600080825260208201819052918101919091528180600111611dfd57600054811015611dfd57600081815260046020908152604091829020825160608101845290546001600160a01b0381168252600160a01b81046001600160401b031692820192909252600160e01b90910460ff16151591810182905290611dfb5780516001600160a01b031615611d92579392505050565b5060001901600081815260046020908152604091829020825160608101845290546001600160a01b038116808352600160a01b82046001600160401b031693830193909352600160e01b900460ff1615159281019290925215611df6579392505050565b611d92565b505b604051636f96cda160e11b815260040160405180910390fd5b600880546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b600a546000906001600160a01b0316611e848787878787612260565b6001600160a01b0316149695505050505050565b604051630a85bd0160e11b81526000906001600160a01b0385169063150b7a0290611ecd903390899088908890600401613025565b602060405180830381600087803b158015611ee757600080fd5b505af1925050508015611f17575060408051601f3d908101601f19168201909252611f1491810190613058565b60015b611f72573d808015611f45576040519150601f19603f3d011682016040523d82523d6000602084013e611f4a565b606091505b508051611f6a576040516368d2bf6b60e11b815260040160405180910390fd5b805181602001fd5b6001600160e01b031916630a85bd0160e11b1490505b949350505050565b6060601080546107b490612dcd565b606081611fc35750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611fed5780611fd781612f46565b9150611fe69050600a83612f05565b9150611fc7565b6000816001600160401b038111156120075761200761284a565b6040519080825280601f01601f191660200182016040528015612031576020820181803683370190505b5090505b8415611f8857612046600183612f19565b9150612053600a86613075565b61205e906030612e1e565b60f81b81838151811061207357612073612f30565b60200101906001600160f81b031916908160001a905350612095600a86612f05565b9450612035565b6000546001600160a01b0384166120c557604051622e076360e81b815260040160405180910390fd5b826120e35760405163b562e8dd60e01b815260040160405180910390fd5b6001600160a01b038416600081815260056020908152604080832080546fffffffffffffffffffffffffffffffff1981166001600160401b038083168b0181169182176801000000000000000067ffffffffffffffff1990941690921783900481168b01811690920217909155858452600490925290912080546001600160e01b0319168317600160a01b42909316929092029190911790558190818501903b1561220b575b60405182906001600160a01b038816906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a46121d46000878480600101955087611e98565b6121f1576040516368d2bf6b60e11b815260040160405180910390fd5b80821061218957826000541461220657600080fd5b612250565b5b6040516001830192906001600160a01b038816906000907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a480821061220c575b5060009081556116839085838684565b60006122ac6122708787856122b6565b85858080601f0160208091040260200160405190810160405280939291908181526020018383808284376000920191909152506122ee92505050565b9695505050505050565b6000838330846040516020016122cf9493929190613089565b6040516020818303038152906040528051906020012090509392505050565b60006115a28261234b856040517f19457468657265756d205369676e6564204d6573736167653a0a3332000000006020820152603c8101829052600090605c01604051602081830303815290604052805190602001209050919050565b90600080600061235b8585612368565b91509150610f2d816123d8565b60008082516041141561239f5760208301516040840151606085015160001a61239387828585612593565b945094505050506123d1565b8251604014156123c957602083015160408401516123be868383612680565b9350935050506123d1565b506000905060025b9250929050565b60008160048111156123ec576123ec6130d0565b14156123f55750565b6001816004811115612409576124096130d0565b14156124575760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e617475726500000000000000006044820152606401610938565b600281600481111561246b5761246b6130d0565b14156124b95760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e677468006044820152606401610938565b60038160048111156124cd576124cd6130d0565b14156125265760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b6064820152608401610938565b600481600481111561253a5761253a6130d0565b1415610cae5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b6064820152608401610938565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156125ca5750600090506003612677565b8460ff16601b141580156125e257508460ff16601c14155b156125f35750600090506004612677565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa158015612647573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661267057600060019250925050612677565b9150600090505b94509492505050565b6000806001600160ff1b0383168161269d60ff86901c601b612e1e565b90506126ab87828885612593565b935093505050935093915050565b8280546126c590612dcd565b90600052602060002090601f0160209004810192826126e7576000855561272d565b82601f1061270057805160ff191683800117855561272d565b8280016001018555821561272d579182015b8281111561272d578251825591602001919060010190612712565b5061273992915061273d565b5090565b5b80821115612739576000815560010161273e565b6001600160e01b031981168114610cae57600080fd5b60006020828403121561277a57600080fd5b81356115a281612752565b60005b838110156127a0578181015183820152602001612788565b838111156116835750506000910152565b600081518084526127c9816020860160208601612785565b601f01601f19169290920160200192915050565b6020815260006115a260208301846127b1565b60006020828403121561280257600080fd5b5035919050565b6001600160a01b0381168114610cae57600080fd5b6000806040838503121561283157600080fd5b823561283c81612809565b946020939093013593505050565b634e487b7160e01b600052604160045260246000fd5b604051601f8201601f191681016001600160401b03811182821017156128885761288861284a565b604052919050565b60006001600160401b038311156128a9576128a961284a565b6128bc601f8401601f1916602001612860565b90508281528383830111156128d057600080fd5b828260208301376000602084830101529392505050565b6000602082840312156128f957600080fd5b81356001600160401b0381111561290f57600080fd5b8201601f8101841361292057600080fd5b611f8884823560208401612890565b60006020828403121561294157600080fd5b81356115a281612809565b60008060006060848603121561296157600080fd5b833561296c81612809565b9250602084013561297c81612809565b929592945050506040919091013590565b8035801515811461299d57600080fd5b919050565b6000602082840312156129b457600080fd5b6115a28261298d565b60006001600160401b038211156129d6576129d661284a565b5060051b60200190565b600060208083850312156129f357600080fd5b82356001600160401b03811115612a0957600080fd5b8301601f81018513612a1a57600080fd5b8035612a2d612a28826129bd565b612860565b81815260059190911b82018301908381019087831115612a4c57600080fd5b928401925b82841015612a73578335612a6481612809565b82529284019290840190612a51565b979650505050505050565b60006020808385031215612a9157600080fd5b82356001600160401b03811115612aa757600080fd5b8301601f81018513612ab857600080fd5b8035612ac6612a28826129bd565b81815260059190911b82018301908381019087831115612ae557600080fd5b928401925b82841015612a7357833582529284019290840190612aea565b6020808252825182820181905260009190848201906040850190845b8181101561120657612b5a83855180516001600160a01b031682526020808201516001600160401b0316908301526040908101511515910152565b9284019260609290920191600101612b1f565b6020808252825182820181905260009190848201906040850190845b8181101561120657835183529284019291840191600101612b89565b60008083601f840112612bb757600080fd5b5081356001600160401b03811115612bce57600080fd5b6020830191508360208285010111156123d157600080fd5b60008060008060408587031215612bfc57600080fd5b84356001600160401b0380821115612c1357600080fd5b612c1f88838901612ba5565b90965094506020870135915080821115612c3857600080fd5b50612c4587828801612ba5565b95989497509550505050565b600080600060608486031215612c6657600080fd5b8335612c7181612809565b95602085013595506040909401359392505050565b60008060408385031215612c9957600080fd5b8235612ca481612809565b9150612cb26020840161298d565b90509250929050565b60008060008060808587031215612cd157600080fd5b8435612cdc81612809565b93506020850135612cec81612809565b92506040850135915060608501356001600160401b03811115612d0e57600080fd5b8501601f81018713612d1f57600080fd5b612d2e87823560208401612890565b91505092959194509250565b60008060408385031215612d4d57600080fd5b823591506020830135612d5f81612809565b809150509250929050565b81516001600160a01b031681526020808301516001600160401b0316908201526040808301511515908201526060810161079f565b60008060408385031215612db257600080fd5b8235612dbd81612809565b91506020830135612d5f81612809565b600181811c90821680612de157607f821691505b60208210811415612e0257634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052601160045260246000fd5b60008219821115612e3157612e31612e08565b500190565b6020808252601490820152734d617820737570706c792065786365656465642160601b604082015260600190565b6000816000190483118215151615612e7e57612e7e612e08565b500290565b6020808252818101527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572604082015260600190565b6020808252601f908201527f5265656e7472616e637947756172643a207265656e7472616e742063616c6c00604082015260600190565b634e487b7160e01b600052601260045260246000fd5b600082612f1457612f14612eef565b500490565b600082821015612f2b57612f2b612e08565b500390565b634e487b7160e01b600052603260045260246000fd5b6000600019821415612f5a57612f5a612e08565b5060010190565b600084516020612f748285838a01612785565b855191840191612f878184848a01612785565b8554920191600090600181811c9080831680612fa457607f831692505b858310811415612fc257634e487b7160e01b85526022600452602485fd5b808015612fd65760018114612fe757613014565b60ff19851688528388019550613014565b60008b81526020902060005b8581101561300c5781548a820152908401908801612ff3565b505083880195505b50939b9a5050505050505050505050565b6001600160a01b03858116825284166020820152604081018390526080606082018190526000906122ac908301846127b1565b60006020828403121561306a57600080fd5b81516115a281612752565b60008261308457613084612eef565b500690565b6060815283606082015283856080830137600060808583018101919091526001600160a01b039384166020830152919092166040830152601f909201601f19160101919050565b634e487b7160e01b600052602160045260246000fdfea2646970667358221220bcd577c4a14cef22f29246cb8af8f63e324ea9784463cc02be707ee7cef72ce364736f6c63430008090033

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

0000000000000000000000008d10505d63581a18063bb1c94cb6e3caefd4c901

-----Decoded View---------------
Arg [0] : _signer (address): 0x8d10505d63581A18063Bb1c94cB6e3caefD4c901

-----Encoded View---------------
1 Constructor Arguments found :
Arg [0] : 0000000000000000000000008d10505d63581a18063bb1c94cb6e3caefd4c901


Deployed Bytecode Sourcemap

1709:3294:20:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2986:305:5;;;;;;;;;;-1:-1:-1;2986:305:5;;;;;:::i;:::-;;:::i;:::-;;;565:14:21;;558:22;540:41;;528:2;513:18;2986:305:5;;;;;;;;6101:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;7605:204::-;;;;;;;;;;-1:-1:-1;7605:204:5;;;;;:::i;:::-;;:::i;:::-;;;-1:-1:-1;;;;;1692:32:21;;;1674:51;;1662:2;1647:18;7605:204:5;1528:203:21;7167:372:5;;;;;;;;;;-1:-1:-1;7167:372:5;;;;;:::i;:::-;;:::i;:::-;;2746:125:20;;;:::i;1896:33::-;;;;;;;;;;;;;;;;;;;2338:25:21;;;2326:2;2311:18;1896:33:20;2192:177:21;4428:100:20;;;;;;;;;;-1:-1:-1;4428:100:20;;;;;:::i;:::-;;:::i;2226:312:5:-;;;;;;;;;;;;;:::i;1674:624:15:-;;;;;;;;;;-1:-1:-1;1674:624:15;;;;;:::i;:::-;;:::i;2003:38:20:-;;;;;;;;;;-1:-1:-1;2003:38:20;;;;;:::i;:::-;;;;;;;;;;;;;;;;8470:170:5;;;;;;;;;;-1:-1:-1;8470:170:5;;;;;:::i;:::-;;:::i;3265:187:20:-;;;;;;;;;;-1:-1:-1;3265:187:20;;;;;:::i;:::-;;:::i;4235:87::-;;;;;;;;;;-1:-1:-1;4235:87:20;;;;;:::i;:::-;;:::i;4640:151::-;;;;;;;;;;;;;:::i;8711:185:5:-;;;;;;;;;;-1:-1:-1;8711:185:5;;;;;:::i;:::-;;:::i;4155:74:20:-;;;;;;;;;;-1:-1:-1;4155:74:20;;;;;:::i;:::-;;:::i;3612:163::-;;;;;;;;;;-1:-1:-1;3612:163:20;;;;;:::i;:::-;;:::i;1547:468:6:-;;;;;;;;;;-1:-1:-1;1547:468:6;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;1129:86:14:-;;;;;;;;;;-1:-1:-1;1200:7:14;;-1:-1:-1;;;1200:7:14;;;;1129:86;;1863:28:20;;;;;;;;;;;;;:::i;5909:125:5:-;;;;;;;;;;-1:-1:-1;5909:125:5;;;;;:::i;:::-;;:::i;4328:94:20:-;;;;;;;;;;-1:-1:-1;4328:94:20;;;;;:::i;:::-;;:::i;3355:206:5:-;;;;;;;;;;-1:-1:-1;3355:206:5;;;;;:::i;:::-;;:::i;1714:103:13:-;;;;;;;;;;;;;:::i;1969:27:20:-;;;;;;;;;;-1:-1:-1;1969:27:20;;;;;;;;4534:100;;;;;;;;;;-1:-1:-1;4534:100:20;;;;;:::i;:::-;;:::i;5361:891:6:-;;;;;;;;;;-1:-1:-1;5361:891:6;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;2877:382:20:-;;;;;;:::i;:::-;;:::i;1063:87:13:-;;;;;;;;;;-1:-1:-1;1136:6:13;;-1:-1:-1;;;;;1136:6:13;1063:87;;6270:104:5;;;;;;;;;;;;;:::i;2405:2507:6:-;;;;;;;;;;-1:-1:-1;2405:2507:6;;;;;:::i;:::-;;:::i;7881:287:5:-;;;;;;;;;;-1:-1:-1;7881:287:5;;;;;:::i;:::-;;:::i;8967:370::-;;;;;;;;;;-1:-1:-1;8967:370:5;;;;;:::i;:::-;;:::i;3458:148:20:-;;;;;;;;;;-1:-1:-1;3458:148:20;;;;;:::i;:::-;;:::i;970:418:6:-;;;;;;;;;;-1:-1:-1;970:418:6;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;3781:368:20:-;;;;;;;;;;-1:-1:-1;3781:368:20;;;;;:::i;:::-;;:::i;1369:105:15:-;;;;;;;;;;-1:-1:-1;1369:105:15;;;;;:::i;:::-;-1:-1:-1;;;;;1450:16:15;1423:7;1450:16;;;:7;:16;;;;;;;1369:105;1934:30:20;;;;;;;;;;;;;;;;8239:164:5;;;;;;;;;;-1:-1:-1;8239:164:5;;;;;:::i;:::-;;:::i;1972:201:13:-;;;;;;;;;;-1:-1:-1;1972:201:13;;;;;:::i;:::-;;:::i;2986:305:5:-;3088:4;-1:-1:-1;;;;;;3125:40:5;;-1:-1:-1;;;3125:40:5;;:105;;-1:-1:-1;;;;;;;3182:48:5;;-1:-1:-1;;;3182:48:5;3125:105;:158;;;-1:-1:-1;;;;;;;;;;963:40:4;;;3247:36:5;3105:178;2986:305;-1:-1:-1;;2986:305:5:o;6101:100::-;6155:13;6188:5;6181:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;6101:100;:::o;7605:204::-;7673:7;7698:16;7706:7;7698;:16::i;:::-;7693:64;;7723:34;;-1:-1:-1;;;7723:34:5;;;;;;;;;;;7693:64;-1:-1:-1;7777:24:5;;;;:15;:24;;;;;;-1:-1:-1;;;;;7777:24:5;;7605:204::o;7167:372::-;7240:13;7256:24;7272:7;7256:15;:24::i;:::-;7240:40;;7301:5;-1:-1:-1;;;;;7295:11:5;:2;-1:-1:-1;;;;;7295:11:5;;7291:48;;;7315:24;;-1:-1:-1;;;7315:24:5;;;;;;;;;;;7291:48;736:10:1;-1:-1:-1;;;;;7356:21:5;;;7352:139;;7383:37;7400:5;736:10:1;8239:164:5;:::i;7383:37::-;7379:112;;7444:35;;-1:-1:-1;;;7444:35:5;;;;;;;;;;;7379:112;7503:28;7512:2;7516:7;7525:5;7503:8;:28::i;:::-;7229:310;7167:372;;:::o;2746:125:20:-;2792:1;2552:9;;2537:11;2521:13;:11;:13::i;:::-;:27;;;;:::i;:::-;:40;;2513:73;;;;-1:-1:-1;;;2513:73:20;;;;;;;:::i;:::-;;;;;;;;;2815:1:::1;2691:11;2684:4;;:18;;;;:::i;:::-;2671:9;:31;;2663:63;;;::::0;-1:-1:-1;;;2663:63:20;;13623:2:21;2663:63:20::1;::::0;::::1;13605:21:21::0;13662:2;13642:18;;;13635:30;-1:-1:-1;;;13681:18:21;;;13674:49;13740:18;;2663:63:20::1;13421:343:21::0;2663:63:20::1;1200:7:14::0;;-1:-1:-1;;;1200:7:14;;;;1454:9:::2;1446:38;;;::::0;-1:-1:-1;;;1446:38:14;;13971:2:21;1446:38:14::2;::::0;::::2;13953:21:21::0;14010:2;13990:18;;;13983:30;-1:-1:-1;;;14029:18:21;;;14022:46;14085:18;;1446:38:14::2;13769:340:21::0;1446:38:14::2;2839:26:20::3;736:10:1::0;2863:1:20::3;2839:9;:26::i;:::-;2593:1:::1;2746:125:::0;:::o;4428:100::-;1136:6:13;;-1:-1:-1;;;;;1136:6:13;736:10:1;1283:23:13;1275:68;;;;-1:-1:-1;;;1275:68:13;;;;;;;:::i;:::-;4500:22:20;;::::1;::::0;:9:::1;::::0;:22:::1;::::0;::::1;::::0;::::1;:::i;2226:312:5:-:0;4993:1:20;2489:12:5;2279:7;2473:13;:28;-1:-1:-1;;2473:46:5;;2226:312::o;1674:624:15:-;1778:1:16;2376:7;;:19;;2368:63;;;;-1:-1:-1;;;2368:63:16;;;;;;;:::i;:::-;1778:1;2509:7;:18;-1:-1:-1;;;;;1763:16:15;::::1;1782:1;1763:16:::0;;;:7:::1;:16;::::0;;;;;1755:71:::1;;;::::0;-1:-1:-1;;;1755:71:15;;15037:2:21;1755:71:15::1;::::0;::::1;15019:21:21::0;15076:2;15056:18;;;15049:30;15115:34;15095:18;;;15088:62;-1:-1:-1;;;15166:18:21;;;15159:36;15212:19;;1755:71:15::1;14835:402:21::0;1755:71:15::1;1839:21;1887:14;;1863:21;:38;;;;:::i;:::-;-1:-1:-1::0;;;;;1982:18:15;::::1;1912:15;1982:18:::0;;;:9:::1;:18;::::0;;;;;;;;1967:12:::1;::::0;1947:7:::1;:16:::0;;;;;;;1839:62;;-1:-1:-1;1912:15:15;;1931:32:::1;::::0;1839:62;1931:32:::1;:::i;:::-;1930:49;;;;:::i;:::-;:70;;;;:::i;:::-;1912:88:::0;-1:-1:-1;2019:12:15;2011:68:::1;;;::::0;-1:-1:-1;;;2011:68:15;;15831:2:21;2011:68:15::1;::::0;::::1;15813:21:21::0;15870:2;15850:18;;;15843:30;15909:34;15889:18;;;15882:62;-1:-1:-1;;;15960:18:21;;;15953:41;16011:19;;2011:68:15::1;15629:407:21::0;2011:68:15::1;-1:-1:-1::0;;;;;2113:18:15;::::1;;::::0;;;:9:::1;:18;::::0;;;;;:28:::1;::::0;2134:7;;2113:28:::1;:::i;:::-;-1:-1:-1::0;;;;;2092:18:15;::::1;;::::0;;;:9:::1;:18;::::0;;;;:49;2169:14:::1;::::0;:24:::1;::::0;2186:7;;2169:24:::1;:::i;:::-;2152:14;:41:::0;2206:35:::1;2224:7:::0;2233;2206:17:::1;:35::i;:::-;2257:33;::::0;;-1:-1:-1;;;;;16241:32:21;;16223:51;;16305:2;16290:18;;16283:34;;;2257:33:15::1;::::0;16196:18:21;2257:33:15::1;;;;;;;-1:-1:-1::0;;1734:1:16;2688:7;:22;-1:-1:-1;1674:624:15:o;8470:170:5:-;8604:28;8614:4;8620:2;8624:7;8604:9;:28::i;3265:187:20:-;1136:6:13;;-1:-1:-1;;;;;1136:6:13;736:10:1;1283:23:13;1275:68;;;;-1:-1:-1;;;1275:68:13;;;;;;;:::i;:::-;3369:9:20::1;;3354:11;3338:13;:11;:13::i;:::-;:27;;;;:::i;:::-;:40;;3330:73;;;;-1:-1:-1::0;;;3330:73:20::1;;;;;;;:::i;:::-;3410:36;736:10:1::0;3434:11:20::1;3410:9;:36::i;:::-;3265:187:::0;:::o;4235:87::-;1136:6:13;;-1:-1:-1;;;;;1136:6:13;736:10:1;1283:23:13;1275:68;;;;-1:-1:-1;;;1275:68:13;;;;;;;:::i;:::-;4296:8:20::1;:20:::0;;-1:-1:-1;;4296:20:20::1;::::0;::::1;;::::0;;;::::1;::::0;;4235:87::o;4640:151::-;1136:6:13;;-1:-1:-1;;;;;1136:6:13;736:10:1;1283:23:13;1275:68;;;;-1:-1:-1;;;1275:68:13;;;;;;;:::i;:::-;1778:1:16::1;2376:7;;:19;;2368:63;;;;-1:-1:-1::0;;;2368:63:16::1;;;;;;;:::i;:::-;1778:1;2509:7;:18:::0;4698:7:20::2;4719;1136:6:13::0;;-1:-1:-1;;;;;1136:6:13;;1063:87;4719:7:20::2;-1:-1:-1::0;;;;;4711:21:20::2;4741;4711:56;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4697:70;;;4782:2;4774:11;;;::::0;::::2;;-1:-1:-1::0;1734:1:16::1;2688:7;:22:::0;4640:151:20:o;8711:185:5:-;8849:39;8866:4;8872:2;8876:7;8849:39;;;;;;;;;;;;:16;:39::i;4155:74:20:-;1136:6:13;;-1:-1:-1;;;;;1136:6:13;736:10:1;1283:23:13;1275:68;;;;-1:-1:-1;;;1275:68:13;;;;;;;:::i;:::-;4211:4:20::1;:12:::0;4155:74::o;3612:163::-;1136:6:13;;-1:-1:-1;;;;;1136:6:13;736:10:1;1283:23:13;1275:68;;;;-1:-1:-1;;;1275:68:13;;;;;;;:::i;:::-;3688:6:20::1;3683:87;3704:10;:17;3700:1;:21;3683:87;;;3737:25;3745:1;3748:10;3759:1;3748:13;;;;;;;;:::i;:::-;;;;;;;3737:7;:25::i;:::-;3723:3:::0;::::1;::::0;::::1;:::i;:::-;;;;3683:87;;1547:468:6::0;1722:15;;1636:23;;1697:22;1722:15;-1:-1:-1;;;;;1789:36:6;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;1789:36:6;;-1:-1:-1;;1789:36:6;;;;;;;;;;;;1752:73;;1845:9;1840:125;1861:14;1856:1;:19;1840:125;;1917:32;1937:8;1946:1;1937:11;;;;;;;;:::i;:::-;;;;;;;1917:19;:32::i;:::-;1901:10;1912:1;1901:13;;;;;;;;:::i;:::-;;;;;;;;;;:48;1877:3;;1840:125;;;-1:-1:-1;1986:10:6;1547:468;-1:-1:-1;;;1547:468:6:o;1863:28:20:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;5909:125:5:-;5973:7;6000:21;6013:7;6000:12;:21::i;:::-;:26;;5909:125;-1:-1:-1;;5909:125:5:o;4328:94:20:-;1136:6:13;;-1:-1:-1;;;;;1136:6:13;736:10:1;1283:23:13;1275:68;;;;-1:-1:-1;;;1275:68:13;;;;;;;:::i;:::-;4394:9:20::1;:22:::0;4328:94::o;3355:206:5:-;3419:7;-1:-1:-1;;;;;3443:19:5;;3439:60;;3471:28;;-1:-1:-1;;;3471:28:5;;;;;;;;;;;3439:60;-1:-1:-1;;;;;;3525:19:5;;;;;:12;:19;;;;;:27;-1:-1:-1;;;;;3525:27:5;;3355:206::o;1714:103:13:-;1136:6;;-1:-1:-1;;;;;1136:6:13;736:10:1;1283:23:13;1275:68;;;;-1:-1:-1;;;1275:68:13;;;;;;;:::i;:::-;1779:30:::1;1806:1;1779:18;:30::i;:::-;1714:103::o:0;4534:100:20:-;1136:6:13;;-1:-1:-1;;;;;1136:6:13;736:10:1;1283:23:13;1275:68;;;;-1:-1:-1;;;1275:68:13;;;;;;;:::i;:::-;4606:22:20;;::::1;::::0;:9:::1;::::0;:22:::1;::::0;::::1;::::0;::::1;:::i;5361:891:6:-:0;5431:16;5485:19;5519:25;5559:22;5584:16;5594:5;5584:9;:16::i;:::-;5559:41;;5615:25;5657:14;-1:-1:-1;;;;;5643:29:6;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;5643:29:6;;5615:57;;5687:31;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;5687:31:6;4993:1:20;5733:471:6;5782:14;5767:11;:29;5733:471;;5834:14;;;;:11;:14;;;;;;;;;5822:26;;;;;;;;;-1:-1:-1;;;;;5822:26:6;;;;-1:-1:-1;;;5822:26:6;;-1:-1:-1;;;;;5822:26:6;;;;;;;;-1:-1:-1;;;5822:26:6;;;;;;;;;;;;;;;;-1:-1:-1;5867:73:6;;5912:8;;5867:73;5962:14;;-1:-1:-1;;;;;5962:28:6;;5958:111;;6035:14;;;-1:-1:-1;5958:111:6;6112:5;-1:-1:-1;;;;;6091:26:6;:17;-1:-1:-1;;;;;6091:26:6;;6087:102;;;6168:1;6142:8;6151:13;;;;;;6142:23;;;;;;;;:::i;:::-;;;;;;:27;;;;;6087:102;5798:3;;5733:471;;;-1:-1:-1;6225:8:6;;5361:891;-1:-1:-1;;;;;;5361:891:6:o;2877:382:20:-;2976:1;2552:9;;2537:11;2521:13;:11;:13::i;:::-;:27;;;;:::i;:::-;:40;;2513:73;;;;-1:-1:-1;;;2513:73:20;;;;;;;:::i;:::-;2999:1:::1;2691:11;2684:4;;:18;;;;:::i;:::-;2671:9;:31;;2663:63;;;::::0;-1:-1:-1;;;2663:63:20;;13623:2:21;2663:63:20::1;::::0;::::1;13605:21:21::0;13662:2;13642:18;;;13635:30;-1:-1:-1;;;13681:18:21;;;13674:49;13740:18;;2663:63:20::1;13421:343:21::0;2663:63:20::1;1778:1:16::2;2376:7;;:19;;2368:63;;;;-1:-1:-1::0;;;2368:63:16::2;;;;;;;:::i;:::-;1778:1;2509:7;:18:::0;3031:8:20::3;::::0;::::3;;3030:9;3022:28;;;::::0;-1:-1:-1;;;3022:28:20;;17012:2:21;3022:28:20::3;::::0;::::3;16994:21:21::0;17051:1;17031:18;;;17024:29;-1:-1:-1;;;17069:18:21;;;17062:36;17115:18;;3022:28:20::3;16810:329:21::0;3022:28:20::3;3065:48;3087:5;;3094:6;;3102:10;3065:21;:48::i;:::-;3057:73;;;::::0;-1:-1:-1;;;3057:73:20;;17346:2:21;3057:73:20::3;::::0;::::3;17328:21:21::0;17385:2;17365:18;;;17358:30;-1:-1:-1;;;17404:18:21;;;17397:42;17456:18;;3057:73:20::3;17144:336:21::0;3057:73:20::3;3153:10;3146:18;::::0;;;:6:::3;:18;::::0;;;;;::::3;;3145:19;3137:53;;;::::0;-1:-1:-1;;;3137:53:20;;17687:2:21;3137:53:20::3;::::0;::::3;17669:21:21::0;17726:2;17706:18;;;17699:30;-1:-1:-1;;;17745:18:21;;;17738:51;17806:18;;3137:53:20::3;17485:345:21::0;3137:53:20::3;3197:24;3207:10;3219:1;3197:9;:24::i;:::-;-1:-1:-1::0;;3235:10:20::3;3228:18;::::0;;;:6:::3;:18;::::0;;;;:25;;-1:-1:-1;;3228:25:20::3;3249:4;3228:25:::0;;::::3;::::0;;;2688:7:16::2;:22:::0;-1:-1:-1;;;;2877:382:20:o;6270:104:5:-;6326:13;6359:7;6352:14;;;;;:::i;2405:2507:6:-;2540:16;2607:4;2598:5;:13;2594:45;;2620:19;;-1:-1:-1;;;2620:19:6;;;;;;;;;;;2594:45;2654:19;2708:13;;4993:1:20;2799:5:6;:23;2795:87;;;4993:1:20;2843:23:6;;2795:87;2962:9;2955:4;:16;2951:73;;;2999:9;2992:16;;2951:73;3038:25;3066:16;3076:5;3066:9;:16::i;:::-;3038:44;;3260:4;3252:5;:12;3248:278;;;3307:12;;;3342:31;;;3338:111;;;3418:11;3398:31;;3338:111;3266:198;3248:278;;;-1:-1:-1;3509:1:6;3248:278;3540:25;3582:17;-1:-1:-1;;;;;3568:32:6;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;3568:32:6;-1:-1:-1;3540:60:6;-1:-1:-1;3619:22:6;3615:78;;3669:8;-1:-1:-1;3662:15:6;;-1:-1:-1;;;3662:15:6;3615:78;3837:31;3871:26;3891:5;3871:19;:26::i;:::-;3837:60;;3912:25;4157:9;:16;;;4152:92;;-1:-1:-1;4214:14:6;;4152:92;4275:5;4258:477;4287:4;4282:1;:9;;:45;;;;;4310:17;4295:11;:32;;4282:45;4258:477;;;4365:14;;;;:11;:14;;;;;;;;;4353:26;;;;;;;;;-1:-1:-1;;;;;4353:26:6;;;;-1:-1:-1;;;4353:26:6;;-1:-1:-1;;;;;4353:26:6;;;;;;;;-1:-1:-1;;;4353:26:6;;;;;;;;;;;;;;;;-1:-1:-1;4398:73:6;;4443:8;;4398:73;4493:14;;-1:-1:-1;;;;;4493:28:6;;4489:111;;4566:14;;;-1:-1:-1;4489:111:6;4643:5;-1:-1:-1;;;;;4622:26:6;:17;-1:-1:-1;;;;;4622:26:6;;4618:102;;;4699:1;4673:8;4682:13;;;;;;4673:23;;;;;;;;:::i;:::-;;;;;;:27;;;;;4618:102;4329:3;;4258:477;;;-1:-1:-1;;;4820:29:6;;;-1:-1:-1;4827:8:6;;-1:-1:-1;;2405:2507:6;;;;;;:::o;7881:287:5:-;-1:-1:-1;;;;;7980:24:5;;736:10:1;7980:24:5;7976:54;;;8013:17;;-1:-1:-1;;;8013:17:5;;;;;;;;;;;7976:54;736:10:1;8043:32:5;;;;:18;:32;;;;;;;;-1:-1:-1;;;;;8043:42:5;;;;;;;;;;;;:53;;-1:-1:-1;;8043:53:5;;;;;;;;;;8112:48;;540:41:21;;;8043:42:5;;736:10:1;8112:48:5;;513:18:21;8112:48:5;;;;;;;7881:287;;:::o;8967:370::-;9134:28;9144:4;9150:2;9154:7;9134:9;:28::i;:::-;-1:-1:-1;;;;;9177:13:5;;1505:19:0;:23;9173:157:5;;9198:56;9229:4;9235:2;9239:7;9248:5;9198:30;:56::i;:::-;9194:136;;9278:40;;-1:-1:-1;;;9278:40:5;;;;;;;;;;;9194:136;8967:370;;;;:::o;3458:148:20:-;3537:11;2552:9;;2537:11;2521:13;:11;:13::i;:::-;:27;;;;:::i;:::-;:40;;2513:73;;;;-1:-1:-1;;;2513:73:20;;;;;;;:::i;:::-;1136:6:13;;-1:-1:-1;;;;;1136:6:13;736:10:1;1283:23:13::1;1275:68;;;;-1:-1:-1::0;;;1275:68:13::1;;;;;;;:::i;:::-;3567:33:20::2;3577:9;3588:11;3567:9;:33::i;970:418:6:-:0;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4993:1:20;1126:25:6;;;:53;;;1166:13;;1155:7;:24;;1126:53;1122:102;;;1203:9;970:418;-1:-1:-1;;970:418:6:o;1122:102::-;-1:-1:-1;1246:20:6;;;;:11;:20;;;;;;;;;1234:32;;;;;;;;;-1:-1:-1;;;;;1234:32:6;;;;-1:-1:-1;;;1234:32:6;;-1:-1:-1;;;;;1234:32:6;;;;;;;;-1:-1:-1;;;1234:32:6;;;;;;;;;;;;;;;;1277:65;;1321:9;970:418;-1:-1:-1;;970:418:6:o;1277:65::-;1359:21;1372:7;1359:12;:21::i;3781:368:20:-;3854:13;3884:17;3892:8;3884:7;:17::i;:::-;3876:77;;;;-1:-1:-1;;;3876:77:20;;18037:2:21;3876:77:20;;;18019:21:21;18076:2;18056:18;;;18049:30;18115:34;18095:18;;;18088:62;-1:-1:-1;;;18166:18:21;;;18159:45;18221:19;;3876:77:20;17835:411:21;3876:77:20;3962:28;3993:10;:8;:10::i;:::-;3962:41;;4048:1;4023:14;4017:28;:32;:126;;;;;;;;;;;;;;;;;4083:14;4099:19;:8;:17;:19::i;:::-;4120:9;4066:64;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;4010:133;3781:368;-1:-1:-1;;;3781:368:20:o;8239:164:5:-;-1:-1:-1;;;;;8360:25:5;;;8336:4;8360:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;;;8239:164::o;1972:201:13:-;1136:6;;-1:-1:-1;;;;;1136:6:13;736:10:1;1283:23:13;1275:68;;;;-1:-1:-1;;;1275:68:13;;;;;;;:::i;:::-;-1:-1:-1;;;;;2061:22:13;::::1;2053:73;;;::::0;-1:-1:-1;;;2053:73:13;;20111:2:21;2053:73:13::1;::::0;::::1;20093:21:21::0;20150:2;20130:18;;;20123:30;20189:34;20169:18;;;20162:62;-1:-1:-1;;;20240:18:21;;;20233:36;20286:19;;2053:73:13::1;19909:402:21::0;2053:73:13::1;2137:28;2156:8;2137:18;:28::i;9592:174:5:-:0;9649:4;9692:7;4993:1:20;9673:26:5;;:53;;;;;9713:13;;9703:7;:23;9673:53;:85;;;;-1:-1:-1;;9731:20:5;;;;:11;:20;;;;;:27;-1:-1:-1;;;9731:27:5;;;;9730:28;;9592:174::o;18814:196::-;18929:24;;;;:15;:24;;;;;;:29;;-1:-1:-1;;;;;;18929:29:5;-1:-1:-1;;;;;18929:29:5;;;;;;;;;18974:28;;18929:24;;18974:28;;;;;;;18814:196;;;:::o;9850:104::-;9919:27;9929:2;9933:8;9919:27;;;;;;;;;;;;:9;:27::i;2471:317:0:-;2586:6;2561:21;:31;;2553:73;;;;-1:-1:-1;;;2553:73:0;;20518:2:21;2553:73:0;;;20500:21:21;20557:2;20537:18;;;20530:30;20596:31;20576:18;;;20569:59;20645:18;;2553:73:0;20316:353:21;2553:73:0;2640:12;2658:9;-1:-1:-1;;;;;2658:14:0;2680:6;2658:33;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;2639:52;;;2710:7;2702:78;;;;-1:-1:-1;;;2702:78:0;;20876:2:21;2702:78:0;;;20858:21:21;20915:2;20895:18;;;20888:30;20954:34;20934:18;;;20927:62;21025:28;21005:18;;;20998:56;21071:19;;2702:78:0;20674:422:21;13762:2130:5;13877:35;13915:21;13928:7;13915:12;:21::i;:::-;13877:59;;13975:4;-1:-1:-1;;;;;13953:26:5;:13;:18;;;-1:-1:-1;;;;;13953:26:5;;13949:67;;13988:28;;-1:-1:-1;;;13988:28:5;;;;;;;;;;;13949:67;14029:22;736:10:1;-1:-1:-1;;;;;14055:20:5;;;;:73;;-1:-1:-1;14092:36:5;14109:4;736:10:1;8239:164:5;:::i;14092:36::-;14055:126;;;-1:-1:-1;736:10:1;14145:20:5;14157:7;14145:11;:20::i;:::-;-1:-1:-1;;;;;14145:36:5;;14055:126;14029:153;;14200:17;14195:66;;14226:35;;-1:-1:-1;;;14226:35:5;;;;;;;;;;;14195:66;-1:-1:-1;;;;;14276:16:5;;14272:52;;14301:23;;-1:-1:-1;;;14301:23:5;;;;;;;;;;;14272:52;14445:35;14462:1;14466:7;14475:4;14445:8;:35::i;:::-;-1:-1:-1;;;;;14776:18:5;;;;;;;:12;:18;;;;;;;;:31;;-1:-1:-1;;14776:31:5;;;-1:-1:-1;;;;;14776:31:5;;;-1:-1:-1;;14776:31:5;;;;;;;14822:16;;;;;;;;;:29;;;;;;;;-1:-1:-1;14822:29:5;;;;;;;;;;;14902:20;;;:11;:20;;;;;;14937:18;;-1:-1:-1;;;;;;14970:49:5;;;;-1:-1:-1;;;15003:15:5;14970:49;;;;;;;;;;15293:11;;15353:24;;;;;15396:13;;14902:20;;15353:24;;15396:13;15392:384;;15606:13;;15591:11;:28;15587:174;;15644:20;;15713:28;;;;-1:-1:-1;;;;;15687:54:5;-1:-1:-1;;;15687:54:5;-1:-1:-1;;;;;;15687:54:5;;;-1:-1:-1;;;;;15644:20:5;;15687:54;;;;15587:174;14751:1036;;;15823:7;15819:2;-1:-1:-1;;;;;15804:27:5;15813:4;-1:-1:-1;;;;;15804:27:5;;;;;;;;;;;13866:2026;;13762:2130;;;:::o;4736:1111::-;-1:-1:-1;;;;;;;;;;;;;;;;;;;;;;;;;4847:7:5;;4993:1:20;4896:23:5;4892:888;;4932:13;;4925:4;:20;4921:859;;;4966:31;5000:17;;;:11;:17;;;;;;;;;4966:51;;;;;;;;;-1:-1:-1;;;;;4966:51:5;;;;-1:-1:-1;;;4966:51:5;;-1:-1:-1;;;;;4966:51:5;;;;;;;;-1:-1:-1;;;4966:51:5;;;;;;;;;;;;;;5036:729;;5086:14;;-1:-1:-1;;;;;5086:28:5;;5082:101;;5150:9;4736:1111;-1:-1:-1;;;4736:1111:5:o;5082:101::-;-1:-1:-1;;;5525:6:5;5570:17;;;;:11;:17;;;;;;;;;5558:29;;;;;;;;;-1:-1:-1;;;;;5558:29:5;;;;;-1:-1:-1;;;5558:29:5;;-1:-1:-1;;;;;5558:29:5;;;;;;;;-1:-1:-1;;;5558:29:5;;;;;;;;;;;;;5618:28;5614:109;;5686:9;4736:1111;-1:-1:-1;;;4736:1111:5:o;5614:109::-;5485:261;;;4947:833;4921:859;5808:31;;-1:-1:-1;;;5808:31:5;;;;;;;;;;;2333:191:13;2426:6;;;-1:-1:-1;;;;;2443:17:13;;;-1:-1:-1;;;;;;2443:17:13;;;;;;;2476:40;;2426:6;;;2443:17;2426:6;;2476:40;;2407:16;;2476:40;2396:128;2333:191;:::o;1046:230:18:-;1261:7;;1198:4;;-1:-1:-1;;;;;1261:7:18;1222:35;1233:5;;1240:6;;1248:8;1222:10;:35::i;:::-;-1:-1:-1;;;;;1222:46:18;;;1046:230;-1:-1:-1;;;;;;1046:230:18:o;19502:667:5:-;19686:72;;-1:-1:-1;;;19686:72:5;;19665:4;;-1:-1:-1;;;;;19686:36:5;;;;;:72;;736:10:1;;19737:4:5;;19743:7;;19752:5;;19686:72;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19686:72:5;;;;;;;;-1:-1:-1;;19686:72:5;;;;;;;;;;;;:::i;:::-;;;19682:480;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;19920:13:5;;19916:235;;19966:40;;-1:-1:-1;;;19966:40:5;;;;;;;;;;;19916:235;20109:6;20103:13;20094:6;20090:2;20086:15;20079:38;19682:480;-1:-1:-1;;;;;;19805:55:5;-1:-1:-1;;;19805:55:5;;-1:-1:-1;19682:480:5;19502:667;;;;;;:::o;4797:103:20:-;4856:13;4885:9;4878:16;;;;;:::i;342:723:19:-;398:13;619:10;615:53;;-1:-1:-1;;646:10:19;;;;;;;;;;;;-1:-1:-1;;;646:10:19;;;;;342:723::o;615:53::-;693:5;678:12;734:78;741:9;;734:78;;767:8;;;;:::i;:::-;;-1:-1:-1;790:10:19;;-1:-1:-1;798:2:19;790:10;;:::i;:::-;;;734:78;;;822:19;854:6;-1:-1:-1;;;;;844:17:19;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;844:17:19;;822:39;;872:154;879:10;;872:154;;906:11;916:1;906:11;;:::i;:::-;;-1:-1:-1;975:10:19;983:2;975:5;:10;:::i;:::-;962:24;;:2;:24;:::i;:::-;949:39;;932:6;939;932:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;932:56:19;;;;;;;;-1:-1:-1;1003:11:19;1012:2;1003:11;;:::i;:::-;;;872:154;;10327:1749:5;10450:20;10473:13;-1:-1:-1;;;;;10501:16:5;;10497:48;;10526:19;;-1:-1:-1;;;10526:19:5;;;;;;;;;;;10497:48;10560:13;10556:44;;10582:18;;-1:-1:-1;;;10582:18:5;;;;;;;;;;;10556:44;-1:-1:-1;;;;;10951:16:5;;;;;;:12;:16;;;;;;;;:44;;-1:-1:-1;;11010:49:5;;-1:-1:-1;;;;;10951:44:5;;;;;;;11010:49;;;;-1:-1:-1;;10951:44:5;;;;;;11010:49;;;;;;;;;;;;;;;;11076:25;;;:11;:25;;;;;;:35;;-1:-1:-1;;;;;;11126:66:5;;;-1:-1:-1;;;11176:15:5;11126:66;;;;;;;;;;;;;11076:25;;11273:23;;;;1505:19:0;:23;11313:631:5;;11353:313;11384:38;;11409:12;;-1:-1:-1;;;;;11384:38:5;;;11401:1;;11384:38;;11401:1;;11384:38;11450:69;11489:1;11493:2;11497:14;;;;;;11513:5;11450:30;:69::i;:::-;11445:174;;11555:40;;-1:-1:-1;;;11555:40:5;;;;;;;;;;;11445:174;11661:3;11646:12;:18;11353:313;;11747:12;11730:13;;:29;11726:43;;11761:8;;;11726:43;11313:631;;;11810:119;11841:40;;11866:14;;;;;-1:-1:-1;;;;;11841:40:5;;;11858:1;;11841:40;;11858:1;;11841:40;11924:3;11909:12;:18;11810:119;;11313:631;-1:-1:-1;11958:13:5;:28;;;12008:60;;12041:2;12045:12;12059:8;12008:60;:::i;822:216:18:-;963:7;990:40;999:22;1005:5;;1012:8;999:5;:22::i;:::-;1023:6;;990:40;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;990:8:18;;-1:-1:-1;;;990:40:18:i;:::-;983:47;822:216;-1:-1:-1;;;;;;822:216:18:o;421:199::-;527:7;580:5;;595:4;602:8;569:42;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;559:53;;;;;;552:60;;421:199;;;;;:::o;628:186::-;730:7;762:44;800:5;762:29;:4;8508:58:3;;22806:66:21;8508:58:3;;;22794:79:21;22889:12;;;22882:28;;;8375:7:3;;22926:12:21;;8508:58:3;;;;;;;;;;;;8498:69;;;;;;8491:76;;8306:269;;;;762:29:18;:37;4582:7:3;4603:17;4622:18;4644:27;4655:4;4661:9;4644:10;:27::i;:::-;4602:69;;;;4682:18;4694:5;4682:11;:18::i;2298:1404::-;2379:7;2388:12;2613:9;:16;2633:2;2613:22;2609:1086;;;2957:4;2942:20;;2936:27;3007:4;2992:20;;2986:27;3065:4;3050:20;;3044:27;2652:9;3036:36;3108:25;3119:4;3036:36;2936:27;2986;3108:10;:25::i;:::-;3101:32;;;;;;;;;2609:1086;3155:9;:16;3175:2;3155:22;3151:544;;;3478:4;3463:20;;3457:27;3529:4;3514:20;;3508:27;3571:23;3582:4;3457:27;3508;3571:10;:23::i;:::-;3564:30;;;;;;;;3151:544;-1:-1:-1;3643:1:3;;-1:-1:-1;3647:35:3;3151:544;2298:1404;;;;;:::o;569:643::-;647:20;638:5;:29;;;;;;;;:::i;:::-;;634:571;;;569:643;:::o;634:571::-;745:29;736:5;:38;;;;;;;;:::i;:::-;;732:473;;;791:34;;-1:-1:-1;;;791:34:3;;23283:2:21;791:34:3;;;23265:21:21;23322:2;23302:18;;;23295:30;23361:26;23341:18;;;23334:54;23405:18;;791:34:3;23081:348:21;732:473:3;856:35;847:5;:44;;;;;;;;:::i;:::-;;843:362;;;908:41;;-1:-1:-1;;;908:41:3;;23636:2:21;908:41:3;;;23618:21:21;23675:2;23655:18;;;23648:30;23714:33;23694:18;;;23687:61;23765:18;;908:41:3;23434:355:21;843:362:3;980:30;971:5;:39;;;;;;;;:::i;:::-;;967:238;;;1027:44;;-1:-1:-1;;;1027:44:3;;23996:2:21;1027:44:3;;;23978:21:21;24035:2;24015:18;;;24008:30;24074:34;24054:18;;;24047:62;-1:-1:-1;;;24125:18:21;;;24118:32;24167:19;;1027:44:3;23794:398:21;967:238:3;1102:30;1093:5;:39;;;;;;;;:::i;:::-;;1089:116;;;1149:44;;-1:-1:-1;;;1149:44:3;;24399:2:21;1149:44:3;;;24381:21:21;24438:2;24418:18;;;24411:30;24477:34;24457:18;;;24450:62;-1:-1:-1;;;24528:18:21;;;24521:32;24570:19;;1149:44:3;24197:398:21;5956:1632:3;6087:7;;7021:66;7008:79;;7004:163;;;-1:-1:-1;7120:1:3;;-1:-1:-1;7124:30:3;7104:51;;7004:163;7181:1;:7;;7186:2;7181:7;;:18;;;;;7192:1;:7;;7197:2;7192:7;;7181:18;7177:102;;;-1:-1:-1;7232:1:3;;-1:-1:-1;7236:30:3;7216:51;;7177:102;7393:24;;;7376:14;7393:24;;;;;;;;;24827:25:21;;;24900:4;24888:17;;24868:18;;;24861:45;;;;24922:18;;;24915:34;;;24965:18;;;24958:34;;;7393:24:3;;24799:19:21;;7393:24:3;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;7393:24:3;;-1:-1:-1;;7393:24:3;;;-1:-1:-1;;;;;;;7432:20:3;;7428:103;;7485:1;7489:29;7469:50;;;;;;;7428:103;7551:6;-1:-1:-1;7559:20:3;;-1:-1:-1;5956:1632:3;;;;;;;;:::o;4998:344::-;5112:7;;-1:-1:-1;;;;;5158:80:3;;5112:7;5265:25;5281:3;5266:18;;;5288:2;5265:25;:::i;:::-;5249:42;;5309:25;5320:4;5326:1;5329;5332;5309:10;:25::i;:::-;5302:32;;;;;;4998:344;;;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:131:21;-1:-1:-1;;;;;;88:32:21;;78:43;;68:71;;135:1;132;125:12;150:245;208:6;261:2;249:9;240:7;236:23;232:32;229:52;;;277:1;274;267:12;229:52;316:9;303:23;335:30;359:5;335:30;:::i;592:258::-;664:1;674:113;688:6;685:1;682:13;674:113;;;764:11;;;758:18;745:11;;;738:39;710:2;703:10;674:113;;;805:6;802:1;799:13;796:48;;;-1:-1:-1;;840:1:21;822:16;;815:27;592:258::o;855:::-;897:3;935:5;929:12;962:6;957:3;950:19;978:63;1034:6;1027:4;1022:3;1018:14;1011:4;1004:5;1000:16;978:63;:::i;:::-;1095:2;1074:15;-1:-1:-1;;1070:29:21;1061:39;;;;1102:4;1057:50;;855:258;-1:-1:-1;;855:258:21:o;1118:220::-;1267:2;1256:9;1249:21;1230:4;1287:45;1328:2;1317:9;1313:18;1305:6;1287:45;:::i;1343:180::-;1402:6;1455:2;1443:9;1434:7;1430:23;1426:32;1423:52;;;1471:1;1468;1461:12;1423:52;-1:-1:-1;1494:23:21;;1343:180;-1:-1:-1;1343:180:21:o;1736:131::-;-1:-1:-1;;;;;1811:31:21;;1801:42;;1791:70;;1857:1;1854;1847:12;1872:315;1940:6;1948;2001:2;1989:9;1980:7;1976:23;1972:32;1969:52;;;2017:1;2014;2007:12;1969:52;2056:9;2043:23;2075:31;2100:5;2075:31;:::i;:::-;2125:5;2177:2;2162:18;;;;2149:32;;-1:-1:-1;;;1872:315:21:o;2374:127::-;2435:10;2430:3;2426:20;2423:1;2416:31;2466:4;2463:1;2456:15;2490:4;2487:1;2480:15;2506:275;2577:2;2571:9;2642:2;2623:13;;-1:-1:-1;;2619:27:21;2607:40;;-1:-1:-1;;;;;2662:34:21;;2698:22;;;2659:62;2656:88;;;2724:18;;:::i;:::-;2760:2;2753:22;2506:275;;-1:-1:-1;2506:275:21:o;2786:407::-;2851:5;-1:-1:-1;;;;;2877:6:21;2874:30;2871:56;;;2907:18;;:::i;:::-;2945:57;2990:2;2969:15;;-1:-1:-1;;2965:29:21;2996:4;2961:40;2945:57;:::i;:::-;2936:66;;3025:6;3018:5;3011:21;3065:3;3056:6;3051:3;3047:16;3044:25;3041:45;;;3082:1;3079;3072:12;3041:45;3131:6;3126:3;3119:4;3112:5;3108:16;3095:43;3185:1;3178:4;3169:6;3162:5;3158:18;3154:29;3147:40;2786:407;;;;;:::o;3198:451::-;3267:6;3320:2;3308:9;3299:7;3295:23;3291:32;3288:52;;;3336:1;3333;3326:12;3288:52;3376:9;3363:23;-1:-1:-1;;;;;3401:6:21;3398:30;3395:50;;;3441:1;3438;3431:12;3395:50;3464:22;;3517:4;3509:13;;3505:27;-1:-1:-1;3495:55:21;;3546:1;3543;3536:12;3495:55;3569:74;3635:7;3630:2;3617:16;3612:2;3608;3604:11;3569:74;:::i;3654:255::-;3721:6;3774:2;3762:9;3753:7;3749:23;3745:32;3742:52;;;3790:1;3787;3780:12;3742:52;3829:9;3816:23;3848:31;3873:5;3848:31;:::i;4166:456::-;4243:6;4251;4259;4312:2;4300:9;4291:7;4287:23;4283:32;4280:52;;;4328:1;4325;4318:12;4280:52;4367:9;4354:23;4386:31;4411:5;4386:31;:::i;:::-;4436:5;-1:-1:-1;4493:2:21;4478:18;;4465:32;4506:33;4465:32;4506:33;:::i;:::-;4166:456;;4558:7;;-1:-1:-1;;;4612:2:21;4597:18;;;;4584:32;;4166:456::o;4627:160::-;4692:20;;4748:13;;4741:21;4731:32;;4721:60;;4777:1;4774;4767:12;4721:60;4627:160;;;:::o;4792:180::-;4848:6;4901:2;4889:9;4880:7;4876:23;4872:32;4869:52;;;4917:1;4914;4907:12;4869:52;4940:26;4956:9;4940:26;:::i;4977:183::-;5037:4;-1:-1:-1;;;;;5062:6:21;5059:30;5056:56;;;5092:18;;:::i;:::-;-1:-1:-1;5137:1:21;5133:14;5149:4;5129:25;;4977:183::o;5165:966::-;5249:6;5280:2;5323;5311:9;5302:7;5298:23;5294:32;5291:52;;;5339:1;5336;5329:12;5291:52;5379:9;5366:23;-1:-1:-1;;;;;5404:6:21;5401:30;5398:50;;;5444:1;5441;5434:12;5398:50;5467:22;;5520:4;5512:13;;5508:27;-1:-1:-1;5498:55:21;;5549:1;5546;5539:12;5498:55;5585:2;5572:16;5608:60;5624:43;5664:2;5624:43;:::i;:::-;5608:60;:::i;:::-;5702:15;;;5784:1;5780:10;;;;5772:19;;5768:28;;;5733:12;;;;5808:19;;;5805:39;;;5840:1;5837;5830:12;5805:39;5864:11;;;;5884:217;5900:6;5895:3;5892:15;5884:217;;;5980:3;5967:17;5997:31;6022:5;5997:31;:::i;:::-;6041:18;;5917:12;;;;6079;;;;5884:217;;;6120:5;5165:966;-1:-1:-1;;;;;;;5165:966:21:o;6136:891::-;6220:6;6251:2;6294;6282:9;6273:7;6269:23;6265:32;6262:52;;;6310:1;6307;6300:12;6262:52;6350:9;6337:23;-1:-1:-1;;;;;6375:6:21;6372:30;6369:50;;;6415:1;6412;6405:12;6369:50;6438:22;;6491:4;6483:13;;6479:27;-1:-1:-1;6469:55:21;;6520:1;6517;6510:12;6469:55;6556:2;6543:16;6579:60;6595:43;6635:2;6595:43;:::i;6579:60::-;6673:15;;;6755:1;6751:10;;;;6743:19;;6739:28;;;6704:12;;;;6779:19;;;6776:39;;;6811:1;6808;6801:12;6776:39;6835:11;;;;6855:142;6871:6;6866:3;6863:15;6855:142;;;6937:17;;6925:30;;6888:12;;;;6975;;;;6855:142;;7315:724;7550:2;7602:21;;;7672:13;;7575:18;;;7694:22;;;7521:4;;7550:2;7773:15;;;;7747:2;7732:18;;;7521:4;7816:197;7830:6;7827:1;7824:13;7816:197;;;7879:52;7927:3;7918:6;7912:13;7116:12;;-1:-1:-1;;;;;7112:38:21;7100:51;;7204:4;7193:16;;;7187:23;-1:-1:-1;;;;;7183:48:21;7167:14;;;7160:72;7295:4;7284:16;;;7278:23;7271:31;7264:39;7248:14;;7241:63;7032:278;7879:52;7988:15;;;;7960:4;7951:14;;;;;7852:1;7845:9;7816:197;;8044:632;8215:2;8267:21;;;8337:13;;8240:18;;;8359:22;;;8186:4;;8215:2;8438:15;;;;8412:2;8397:18;;;8186:4;8481:169;8495:6;8492:1;8489:13;8481:169;;;8556:13;;8544:26;;8625:15;;;;8590:12;;;;8517:1;8510:9;8481:169;;8681:347;8732:8;8742:6;8796:3;8789:4;8781:6;8777:17;8773:27;8763:55;;8814:1;8811;8804:12;8763:55;-1:-1:-1;8837:20:21;;-1:-1:-1;;;;;8869:30:21;;8866:50;;;8912:1;8909;8902:12;8866:50;8949:4;8941:6;8937:17;8925:29;;9001:3;8994:4;8985:6;8977;8973:19;8969:30;8966:39;8963:59;;;9018:1;9015;9008:12;9033:718;9124:6;9132;9140;9148;9201:2;9189:9;9180:7;9176:23;9172:32;9169:52;;;9217:1;9214;9207:12;9169:52;9257:9;9244:23;-1:-1:-1;;;;;9327:2:21;9319:6;9316:14;9313:34;;;9343:1;9340;9333:12;9313:34;9382:58;9432:7;9423:6;9412:9;9408:22;9382:58;:::i;:::-;9459:8;;-1:-1:-1;9356:84:21;-1:-1:-1;9547:2:21;9532:18;;9519:32;;-1:-1:-1;9563:16:21;;;9560:36;;;9592:1;9589;9582:12;9560:36;;9631:60;9683:7;9672:8;9661:9;9657:24;9631:60;:::i;:::-;9033:718;;;;-1:-1:-1;9710:8:21;-1:-1:-1;;;;9033:718:21:o;9756:383::-;9833:6;9841;9849;9902:2;9890:9;9881:7;9877:23;9873:32;9870:52;;;9918:1;9915;9908:12;9870:52;9957:9;9944:23;9976:31;10001:5;9976:31;:::i;:::-;10026:5;10078:2;10063:18;;10050:32;;-1:-1:-1;10129:2:21;10114:18;;;10101:32;;9756:383;-1:-1:-1;;;9756:383:21:o;10144:315::-;10209:6;10217;10270:2;10258:9;10249:7;10245:23;10241:32;10238:52;;;10286:1;10283;10276:12;10238:52;10325:9;10312:23;10344:31;10369:5;10344:31;:::i;:::-;10394:5;-1:-1:-1;10418:35:21;10449:2;10434:18;;10418:35;:::i;:::-;10408:45;;10144:315;;;;;:::o;10464:795::-;10559:6;10567;10575;10583;10636:3;10624:9;10615:7;10611:23;10607:33;10604:53;;;10653:1;10650;10643:12;10604:53;10692:9;10679:23;10711:31;10736:5;10711:31;:::i;:::-;10761:5;-1:-1:-1;10818:2:21;10803:18;;10790:32;10831:33;10790:32;10831:33;:::i;:::-;10883:7;-1:-1:-1;10937:2:21;10922:18;;10909:32;;-1:-1:-1;10992:2:21;10977:18;;10964:32;-1:-1:-1;;;;;11008:30:21;;11005:50;;;11051:1;11048;11041:12;11005:50;11074:22;;11127:4;11119:13;;11115:27;-1:-1:-1;11105:55:21;;11156:1;11153;11146:12;11105:55;11179:74;11245:7;11240:2;11227:16;11222:2;11218;11214:11;11179:74;:::i;:::-;11169:84;;;10464:795;;;;;;;:::o;11264:315::-;11332:6;11340;11393:2;11381:9;11372:7;11368:23;11364:32;11361:52;;;11409:1;11406;11399:12;11361:52;11445:9;11432:23;11422:33;;11505:2;11494:9;11490:18;11477:32;11518:31;11543:5;11518:31;:::i;:::-;11568:5;11558:15;;;11264:315;;;;;:::o;11584:267::-;7116:12;;-1:-1:-1;;;;;7112:38:21;7100:51;;7204:4;7193:16;;;7187:23;-1:-1:-1;;;;;7183:48:21;7167:14;;;7160:72;7295:4;7284:16;;;7278:23;7271:31;7264:39;7248:14;;;7241:63;11782:2;11767:18;;11794:51;7032:278;11856:388;11924:6;11932;11985:2;11973:9;11964:7;11960:23;11956:32;11953:52;;;12001:1;11998;11991:12;11953:52;12040:9;12027:23;12059:31;12084:5;12059:31;:::i;:::-;12109:5;-1:-1:-1;12166:2:21;12151:18;;12138:32;12179:33;12138:32;12179:33;:::i;12249:380::-;12328:1;12324:12;;;;12371;;;12392:61;;12446:4;12438:6;12434:17;12424:27;;12392:61;12499:2;12491:6;12488:14;12468:18;12465:38;12462:161;;;12545:10;12540:3;12536:20;12533:1;12526:31;12580:4;12577:1;12570:15;12608:4;12605:1;12598:15;12462:161;;12249:380;;;:::o;12634:127::-;12695:10;12690:3;12686:20;12683:1;12676:31;12726:4;12723:1;12716:15;12750:4;12747:1;12740:15;12766:128;12806:3;12837:1;12833:6;12830:1;12827:13;12824:39;;;12843:18;;:::i;:::-;-1:-1:-1;12879:9:21;;12766:128::o;12899:344::-;13101:2;13083:21;;;13140:2;13120:18;;;13113:30;-1:-1:-1;;;13174:2:21;13159:18;;13152:50;13234:2;13219:18;;12899:344::o;13248:168::-;13288:7;13354:1;13350;13346:6;13342:14;13339:1;13336:21;13331:1;13324:9;13317:17;13313:45;13310:71;;;13361:18;;:::i;:::-;-1:-1:-1;13401:9:21;;13248:168::o;14114:356::-;14316:2;14298:21;;;14335:18;;;14328:30;14394:34;14389:2;14374:18;;14367:62;14461:2;14446:18;;14114:356::o;14475:355::-;14677:2;14659:21;;;14716:2;14696:18;;;14689:30;14755:33;14750:2;14735:18;;14728:61;14821:2;14806:18;;14475:355::o;15242:127::-;15303:10;15298:3;15294:20;15291:1;15284:31;15334:4;15331:1;15324:15;15358:4;15355:1;15348:15;15374:120;15414:1;15440;15430:35;;15445:18;;:::i;:::-;-1:-1:-1;15479:9:21;;15374:120::o;15499:125::-;15539:4;15567:1;15564;15561:8;15558:34;;;15572:18;;:::i;:::-;-1:-1:-1;15609:9:21;;15499:125::o;16538:127::-;16599:10;16594:3;16590:20;16587:1;16580:31;16630:4;16627:1;16620:15;16654:4;16651:1;16644:15;16670:135;16709:3;-1:-1:-1;;16730:17:21;;16727:43;;;16750:18;;:::i;:::-;-1:-1:-1;16797:1:21;16786:13;;16670:135::o;18377:1527::-;18601:3;18639:6;18633:13;18665:4;18678:51;18722:6;18717:3;18712:2;18704:6;18700:15;18678:51;:::i;:::-;18792:13;;18751:16;;;;18814:55;18792:13;18751:16;18836:15;;;18814:55;:::i;:::-;18958:13;;18891:20;;;18931:1;;19018;19040:18;;;;19093;;;;19120:93;;19198:4;19188:8;19184:19;19172:31;;19120:93;19261:2;19251:8;19248:16;19228:18;19225:40;19222:167;;;-1:-1:-1;;;19288:33:21;;19344:4;19341:1;19334:15;19374:4;19295:3;19362:17;19222:167;19405:18;19432:110;;;;19556:1;19551:328;;;;19398:481;;19432:110;-1:-1:-1;;19467:24:21;;19453:39;;19512:20;;;;-1:-1:-1;19432:110:21;;19551:328;18324:1;18317:14;;;18361:4;18348:18;;19646:1;19660:169;19674:8;19671:1;19668:15;19660:169;;;19756:14;;19741:13;;;19734:37;19799:16;;;;19691:10;;19660:169;;;19664:3;;19860:8;19853:5;19849:20;19842:27;;19398:481;-1:-1:-1;19895:3:21;;18377:1527;-1:-1:-1;;;;;;;;;;;18377:1527:21:o;21101:489::-;-1:-1:-1;;;;;21370:15:21;;;21352:34;;21422:15;;21417:2;21402:18;;21395:43;21469:2;21454:18;;21447:34;;;21517:3;21512:2;21497:18;;21490:31;;;21295:4;;21538:46;;21564:19;;21556:6;21538:46;:::i;21595:249::-;21664:6;21717:2;21705:9;21696:7;21692:23;21688:32;21685:52;;;21733:1;21730;21723:12;21685:52;21765:9;21759:16;21784:30;21808:5;21784:30;:::i;21849:112::-;21881:1;21907;21897:35;;21912:18;;:::i;:::-;-1:-1:-1;21946:9:21;;21849:112::o;21966:593::-;22181:2;22170:9;22163:21;22220:6;22215:2;22204:9;22200:18;22193:34;22278:6;22270;22264:3;22253:9;22249:19;22236:49;22335:1;22329:3;22305:22;;;22301:32;;22294:43;;;;-1:-1:-1;;;;;22485:15:21;;;22478:4;22463:20;;22456:45;22537:15;;;;22532:2;22517:18;;22510:43;22398:2;22377:15;;;-1:-1:-1;;22373:29:21;22358:45;22354:55;;;-1:-1:-1;21966:593:21:o;22949:127::-;23010:10;23005:3;23001:20;22998:1;22991:31;23041:4;23038:1;23031:15;23065:4;23062:1;23055:15

Swarm Source

ipfs://bcd577c4a14cef22f29246cb8af8f63e324ea9784463cc02be707ee7cef72ce3
Loading...
Loading
Loading...
Loading
[ 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.