ETH Price: $3,249.68 (+4.32%)
Gas: 2 Gwei

Token

Baby Shark: Collection No. 2 (BSN2)
 

Overview

Max Total Supply

2,000 BSN2

Holders

309

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
2 BSN2
0x730c5a3f6f36923eaa89eed9910c44fe58ac4ff0
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:
CollectionCore

Compiler Version
v0.8.9+commit.e5eed63a

Optimization Enabled:
Yes with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2022-08-31
*/

// File: VaultCoreInterface.sol



pragma solidity 0.8.9;

abstract contract VaultCoreInterface {
    function getVersion() public pure virtual returns (uint);
    function typeOfContract() public pure virtual returns (bytes32);
    function approveToken(
        uint256 _tokenId,
        address _tokenContractAddress) external virtual;
}
// File: RoyaltyRegistryInterface.sol



pragma solidity 0.8.9;


/**
 * Interface to the RoyaltyRegistry responsible for looking payout addresses
 */
abstract contract RoyaltyRegistryInterface {
    function getAddress(address custodial) external view virtual returns (address);
    function getMediaCustomPercentage(uint256 mediaId, address tokenAddress) external view virtual returns(uint16);
    function getExternalTokenPercentage(uint256 tokenId, address tokenAddress) external view virtual returns(uint16, uint16);
    function typeOfContract() virtual public pure returns (string calldata);
    function VERSION() virtual public pure returns (uint8);
}
// File: ApprovedCreatorRegistryInterface.sol



pragma solidity 0.8.9;


/**
 * Interface to the digital media store external contract that is
 * responsible for storing the common digital media and collection data.
 * This allows for new token contracts to be deployed and continue to reference
 * the digital media and collection data.
 */
abstract contract ApprovedCreatorRegistryInterface {

    function getVersion() virtual public pure returns (uint);
    function typeOfContract() virtual public pure returns (string calldata);
    function isOperatorApprovedForCustodialAccount(
        address _operator,
        address _custodialAddress) virtual public view returns (bool);

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


// OpenZeppelin Contracts (last updated v4.7.0) (utils/Strings.sol)

pragma solidity ^0.8.0;

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

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

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

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

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

    /**
     * @dev Converts an `address` with fixed length of 20 bytes to its not checksummed ASCII `string` hexadecimal representation.
     */
    function toHexString(address addr) internal pure returns (string memory) {
        return toHexString(uint256(uint160(addr)), _ADDRESS_LENGTH);
    }
}

// File: @openzeppelin/contracts/utils/cryptography/ECDSA.sol


// OpenZeppelin Contracts (last updated v4.7.3) (utils/cryptography/ECDSA.sol)

pragma solidity ^0.8.0;


/**
 * @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) {
        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 {
            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: @openzeppelin/contracts/utils/Context.sol


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

pragma solidity ^0.8.0;

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

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

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


// OpenZeppelin Contracts (last updated v4.7.0) (access/Ownable.sol)

pragma solidity ^0.8.0;


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

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

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

    /**
     * @dev Throws if called by any account other than the owner.
     */
    modifier onlyOwner() {
        _checkOwner();
        _;
    }

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

    /**
     * @dev Throws if the sender is not the owner.
     */
    function _checkOwner() internal view virtual {
        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: OBOControl.sol



pragma solidity 0.8.9;



contract OBOControl is Ownable {
    address public oboAdmin;
    uint256 constant public newAddressWaitPeriod = 1 days;
    bool public canAddOBOImmediately = true;

    // List of approved on behalf of users.
    mapping (address => uint256) public approvedOBOs;

    event NewOBOAddressEvent(
        address OBOAddress,
        bool action);

    event NewOBOAdminAddressEvent(
        address oboAdminAddress);

    modifier onlyOBOAdmin() {
        require(owner() == _msgSender() || oboAdmin == _msgSender(), "not oboAdmin");
        _;
    }

    function setOBOAdmin(address _oboAdmin) external onlyOwner {
        oboAdmin = _oboAdmin;
        emit NewOBOAdminAddressEvent(_oboAdmin);
    }

    /**
     * Add a new approvedOBO address. The address can be used after wait period.
     */
    function addApprovedOBO(address _oboAddress) external onlyOBOAdmin {
        require(_oboAddress != address(0), "cant set to 0x");
        require(approvedOBOs[_oboAddress] == 0, "already added");
        approvedOBOs[_oboAddress] = block.timestamp;
        emit NewOBOAddressEvent(_oboAddress, true);
    }

    /**
     * Removes an approvedOBO immediately.
     */
    function removeApprovedOBO(address _oboAddress) external onlyOBOAdmin {
        delete approvedOBOs[_oboAddress];
        emit NewOBOAddressEvent(_oboAddress, false);
    }

    /*
     * Add OBOAddress for immediate use. This is an internal only Fn that is called
     * only when the contract is deployed.
     */
    function addApprovedOBOImmediately(address _oboAddress) internal onlyOwner {
        require(_oboAddress != address(0), "addr(0)");
        // set the date to one in past so that address is active immediately.
        approvedOBOs[_oboAddress] = block.timestamp - newAddressWaitPeriod - 1;
        emit NewOBOAddressEvent(_oboAddress, true);
    }

    function addApprovedOBOAfterDeploy(address _oboAddress) external onlyOBOAdmin {
        require(canAddOBOImmediately == true, "disabled");
        addApprovedOBOImmediately(_oboAddress);
    }

    function blockImmediateOBO() external onlyOBOAdmin {
        canAddOBOImmediately = false;
    }

    /*
     * Helper function to verify is a given address is a valid approvedOBO address.
     */
    function isValidApprovedOBO(address _oboAddress) public view returns (bool) {
        uint256 createdAt = approvedOBOs[_oboAddress];
        if (createdAt == 0) {
            return false;
        }
        return block.timestamp - createdAt > newAddressWaitPeriod;
    }

    /**
    * @dev Modifier to make the obo calls only callable by approved addressess
    */
    modifier isApprovedOBO() {
        require(isValidApprovedOBO(msg.sender), "unauthorized OBO user");
        _;
    }
}
// File: @openzeppelin/contracts/security/Pausable.sol


// OpenZeppelin Contracts (last updated v4.7.0) (security/Pausable.sol)

pragma solidity ^0.8.0;


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

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

    bool private _paused;

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

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

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

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

    /**
     * @dev Throws if the contract is paused.
     */
    function _requireNotPaused() internal view virtual {
        require(!paused(), "Pausable: paused");
    }

    /**
     * @dev Throws if the contract is not paused.
     */
    function _requirePaused() internal view virtual {
        require(paused(), "Pausable: not paused");
    }

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

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

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


// OpenZeppelin Contracts (last updated v4.7.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
                /// @solidity memory-safe-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

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


// OpenZeppelin Contracts (last updated v4.6.0) (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 `IERC721Receiver.onERC721Received.selector`.
     */
    function onERC721Received(
        address operator,
        address from,
        uint256 tokenId,
        bytes calldata data
    ) external returns (bytes4);
}

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


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

pragma solidity ^0.8.0;

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

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


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

pragma solidity ^0.8.0;


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

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


// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/IERC721.sol)

pragma solidity ^0.8.0;


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

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

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

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

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

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

    /**
     * @dev 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 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 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 the account approved for `tokenId` token.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function getApproved(uint256 tokenId) external view returns (address operator);

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

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


// OpenZeppelin Contracts (last updated v4.5.0) (token/ERC721/extensions/IERC721Enumerable.sol)

pragma solidity ^0.8.0;


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

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

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

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


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

pragma solidity ^0.8.0;


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

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

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

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


// OpenZeppelin Contracts (last updated v4.7.0) (token/ERC721/ERC721.sol)

pragma solidity ^0.8.0;








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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev See {IERC721Metadata-tokenURI}.
     */
    function tokenURI(uint256 tokenId) public view virtual override returns (string memory) {
        _requireMinted(tokenId);

        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 overridden in child contracts.
     */
    function _baseURI() internal view virtual returns (string memory) {
        return "";
    }

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

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

        _approve(to, tokenId);
    }

    /**
     * @dev See {IERC721-getApproved}.
     */
    function getApproved(uint256 tokenId) public view virtual override returns (address) {
        _requireMinted(tokenId);

        return _tokenApprovals[tokenId];
    }

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

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

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

        _afterTokenTransfer(address(0), to, tokenId);
    }

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

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

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

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

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

        _afterTokenTransfer(owner, address(0), tokenId);
    }

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

        _beforeTokenTransfer(from, to, tokenId);

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

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

        emit Transfer(from, to, tokenId);

        _afterTokenTransfer(from, to, tokenId);
    }

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

    /**
     * @dev Approve `operator` to operate on all of `owner` tokens
     *
     * Emits an {ApprovalForAll} event.
     */
    function _setApprovalForAll(
        address owner,
        address operator,
        bool approved
    ) internal virtual {
        require(owner != operator, "ERC721: approve to caller");
        _operatorApprovals[owner][operator] = approved;
        emit ApprovalForAll(owner, operator, approved);
    }

    /**
     * @dev Reverts if the `tokenId` has not been minted yet.
     */
    function _requireMinted(uint256 tokenId) internal view virtual {
        require(_exists(tokenId), "ERC721: invalid token ID");
    }

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

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

    /**
     * @dev Hook that is called after any transfer of tokens. This includes
     * minting and burning.
     *
     * Calling conditions:
     *
     * - when `from` and `to` are both non-zero.
     * - `from` and `to` are never both zero.
     *
     * To learn more about hooks, head to xref:ROOT:extending-contracts.adoc#using-hooks[Using Hooks].
     */
    function _afterTokenTransfer(
        address from,
        address to,
        uint256 tokenId
    ) internal virtual {}
}

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


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

pragma solidity ^0.8.0;



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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: CollectionCore.sol



pragma solidity 0.8.9;








contract CollectionCore is ERC721Enumerable, OBOControl, Pausable {
    using ECDSA for bytes32;
    uint8 constant public VERSION = 1;
    uint16 public immutable royaltyPercentage;
    address public immutable creator;
    address public signerAddress;
    bool public enableExternalMinting;
    // by default bool's are false, save gas by not initializing
    bool public isImmutable;
    uint256 public immutable totalMediaSupply;
    string public baseURI;
    ApprovedCreatorRegistryInterface public creatorRegistryStore;

    struct ExternalCreateRequest {
        address owner;
        bytes signature;
        uint256 tokenId;
    }

    struct OBOCreateRequest {
        address owner;
        uint256 tokenId;
    }

    struct ChainSignatureRequest {
        uint256 onchainId;
        address owner;
        address thisContract;
    }

    event NewSignerEvent(
        address signer);

    constructor(string memory _tokenName, string memory _tokenSymbol,
            address _crsAddress, uint256 _totalSupply,
            address _creator, uint16 _royaltyPercentage, string memory _initialBaseURI) ERC721(_tokenName, _tokenSymbol) {
        require(_royaltyPercentage > 0 && _royaltyPercentage <= 10000, "invalid royalty");
        require(_creator != address(0), "creator = 0x0");
        setCreatorRegistryStore(_crsAddress);
        require(_totalSupply > 0, "supply > 0");
        totalMediaSupply = _totalSupply;
        creator = _creator;
        royaltyPercentage = _royaltyPercentage;
        baseURI = _initialBaseURI;
    }

    /*
     * Set signer address on the token contract. Setting signer means we are opening
     * the token contract for external accounts to create tokens. Call this to change
     * the signer immediately.
     */
    function setSignerAddress(address _signerAddress, bool _enableExternalMinting) external
            whenNotPaused isApprovedOBO {
        require(_signerAddress != address(0), "cant be zero");
        signerAddress = _signerAddress;
        enableExternalMinting = _enableExternalMinting;
        emit NewSignerEvent(signerAddress);
    }

    // Set the creator registry address upon construction. Immutable.
    function setCreatorRegistryStore(address _crsAddress) internal {
        require(_crsAddress != address(0), "registry = 0x0");
        ApprovedCreatorRegistryInterface candidateCreatorRegistryStore = ApprovedCreatorRegistryInterface(_crsAddress);
        // require(candidateCreatorRegistryStore.getVersion() == 1, "registry store is not version 1");
        // Simple check to make sure we are adding the registry contract indeed
        // https://fravoll.github.io/solidity-patterns/string_equality_comparison.html
        bytes32 contractType = keccak256(abi.encodePacked(candidateCreatorRegistryStore.typeOfContract()));
        // keccak256(abi.encodePacked("approvedCreatorRegistryReadOnly")) = 0x9732b26dfb8751e6f1f71e8f21b28a237cfe383953dce7db3dfa1777abdb2791
        require(contractType == 0x9732b26dfb8751e6f1f71e8f21b28a237cfe383953dce7db3dfa1777abdb2791,
            "not crtrReadOnlyRegistry");
        creatorRegistryStore = candidateCreatorRegistryStore;
    }

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

    /*
     * Set BaseURI for the entire collectible project. Only owner can set it to hide / reveal
     * baseURI.
     */
    function setBaseURI(string memory _newBaseURI) external onlyOwner whenNotPaused {
        require(isImmutable == false, "cant change");
        baseURI = _newBaseURI;
    }

    function makeImmutable() external onlyOwner {
        isImmutable = true;
    }

    /* External users who have been given a signature can mint token using this function 
     * This Fn works only when unpaused.
     */
    function mintTokens(ExternalCreateRequest[] calldata requests) external whenNotPaused {
        require(enableExternalMinting == true, "minting disabled");
        for (uint32 i=0; i < requests.length; i++) {
            ExternalCreateRequest memory request = requests[i];
            // If a token is burnt _exists will return 0.
            require(_exists(request.tokenId) == false, "token exists");
            require(request.owner == msg.sender, "owner error");
            require(totalSupply() + 1 <= totalMediaSupply, "exceeded supply");
            ChainSignatureRequest memory signatureRequest = ChainSignatureRequest(request.tokenId, request.owner, address(this));
            bytes32 encodedRequest = keccak256(abi.encode(signatureRequest));
            address addressWhoSigned = encodedRequest.recover(request.signature);
            require(addressWhoSigned == signerAddress, "sig error");
            _safeMint(msg.sender, request.tokenId);
        }
    }

    function oboMintTokens(OBOCreateRequest[] calldata requests) external isApprovedOBO {
        for (uint32 i=0; i < requests.length; i++) {
            OBOCreateRequest memory request = requests[i];
            require(_exists(request.tokenId) == false, "token exists");
            require(totalSupply() + 1 <= totalMediaSupply, "exceeded supply");
            _safeMint(request.owner, request.tokenId);
        }
    }

    /**
     * Override the isApprovalForAll to check for a special oboApproval list.  Reason for this
     * is that we can can easily remove obo operators if they every become compromised.
     */
    function isApprovedForAll(address _owner, address _operator) public view override registryInitialized returns (bool) {
        if (creatorRegistryStore.isOperatorApprovedForCustodialAccount(_operator, _owner) == true) {
            return true;
        } else {
            return super.isApprovedForAll(_owner, _operator);
        }
    }

         /**
     * Validates that the Registered store is initialized.
     */
    modifier registryInitialized() {
        require(address(creatorRegistryStore) != address(0), "registry = 0x0");
        _;
    }

    function royaltyInfo(uint256, uint256 _salePrice) external view returns (
            address _creator, uint256 _payout) {
        return (creator, (_salePrice * royaltyPercentage / 10000));
    }

    function pause() external onlyOwner {
        _pause();
    }

    function unpause() external onlyOwner {
        _unpause();
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[{"internalType":"string","name":"_tokenName","type":"string"},{"internalType":"string","name":"_tokenSymbol","type":"string"},{"internalType":"address","name":"_crsAddress","type":"address"},{"internalType":"uint256","name":"_totalSupply","type":"uint256"},{"internalType":"address","name":"_creator","type":"address"},{"internalType":"uint16","name":"_royaltyPercentage","type":"uint16"},{"internalType":"string","name":"_initialBaseURI","type":"string"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"OBOAddress","type":"address"},{"indexed":false,"internalType":"bool","name":"action","type":"bool"}],"name":"NewOBOAddressEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"oboAdminAddress","type":"address"}],"name":"NewOBOAdminAddressEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"signer","type":"address"}],"name":"NewSignerEvent","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Paused","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"anonymous":false,"inputs":[{"indexed":false,"internalType":"address","name":"account","type":"address"}],"name":"Unpaused","type":"event"},{"inputs":[],"name":"VERSION","outputs":[{"internalType":"uint8","name":"","type":"uint8"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_oboAddress","type":"address"}],"name":"addApprovedOBO","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oboAddress","type":"address"}],"name":"addApprovedOBOAfterDeploy","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":"","type":"address"}],"name":"approvedOBOs","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"blockImmediateOBO","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"canAddOBOImmediately","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"creator","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"creatorRegistryStore","outputs":[{"internalType":"contract ApprovedCreatorRegistryInterface","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"enableExternalMinting","outputs":[{"internalType":"bool","name":"","type":"bool"}],"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":"isImmutable","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_oboAddress","type":"address"}],"name":"isValidApprovedOBO","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"makeImmutable","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"bytes","name":"signature","type":"bytes"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"internalType":"struct CollectionCore.ExternalCreateRequest[]","name":"requests","type":"tuple[]"}],"name":"mintTokens","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"newAddressWaitPeriod","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"oboAdmin","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"components":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"internalType":"struct CollectionCore.OBOCreateRequest[]","name":"requests","type":"tuple[]"}],"name":"oboMintTokens","outputs":[],"stateMutability":"nonpayable","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":"pause","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"paused","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_oboAddress","type":"address"}],"name":"removeApprovedOBO","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"","type":"uint256"},{"internalType":"uint256","name":"_salePrice","type":"uint256"}],"name":"royaltyInfo","outputs":[{"internalType":"address","name":"_creator","type":"address"},{"internalType":"uint256","name":"_payout","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"royaltyPercentage","outputs":[{"internalType":"uint16","name":"","type":"uint16"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_newBaseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_oboAdmin","type":"address"}],"name":"setOBOAdmin","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_signerAddress","type":"address"},{"internalType":"bool","name":"_enableExternalMinting","type":"bool"}],"name":"setSignerAddress","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"signerAddress","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"totalMediaSupply","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":"unpause","outputs":[],"stateMutability":"nonpayable","type":"function"}]

60e0604052600b805460ff60a01b1916600160a01b1790553480156200002457600080fd5b50604051620036b3380380620036b3833981016040819052620000479162000548565b86518790879062000060906000906020850190620003ab565b50805162000076906001906020840190620003ab565b505050620000936200008d620001ca60201b60201c565b620001ce565b600d805460ff1916905561ffff821615801590620000b757506127108261ffff1611155b620000fb5760405162461bcd60e51b815260206004820152600f60248201526e696e76616c696420726f79616c747960881b60448201526064015b60405180910390fd5b6001600160a01b038316620001435760405162461bcd60e51b815260206004820152600d60248201526c063726561746f72203d2030783609c1b6044820152606401620000f2565b6200014e8562000220565b600084116200018d5760405162461bcd60e51b815260206004820152600a6024820152690737570706c79203e20360b41b6044820152606401620000f2565b60c08490526001600160a01b03831660a05261ffff82166080528051620001bc90600e906020840190620003ab565b5050505050505050620006bf565b3390565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b6001600160a01b038116620002695760405162461bcd60e51b815260206004820152600e60248201526d07265676973747279203d203078360941b6044820152606401620000f2565b60008190506000816001600160a01b031663c20a03826040518163ffffffff1660e01b815260040160006040518083038186803b158015620002aa57600080fd5b505afa158015620002bf573d6000803e3d6000fd5b505050506040513d6000823e601f3d908101601f19168201604052620002e9919081019062000624565b604051602001620002fb919062000664565b604051602081830303815290604052805190602001209050807f9732b26dfb8751e6f1f71e8f21b28a237cfe383953dce7db3dfa1777abdb279160001b14620003875760405162461bcd60e51b815260206004820152601860248201527f6e6f742063727472526561644f6e6c79526567697374727900000000000000006044820152606401620000f2565b50600f80546001600160a01b0319166001600160a01b039290921691909117905550565b828054620003b99062000682565b90600052602060002090601f016020900481019282620003dd576000855562000428565b82601f10620003f857805160ff191683800117855562000428565b8280016001018555821562000428579182015b82811115620004285782518255916020019190600101906200040b565b50620004369291506200043a565b5090565b5b808211156200043657600081556001016200043b565b634e487b7160e01b600052604160045260246000fd5b60005b83811015620004845781810151838201526020016200046a565b8381111562000494576000848401525b50505050565b600082601f830112620004ac57600080fd5b81516001600160401b0380821115620004c957620004c962000451565b604051601f8301601f19908116603f01168101908282118183101715620004f457620004f462000451565b816040528381528660208588010111156200050e57600080fd5b6200052184602083016020890162000467565b9695505050505050565b80516001600160a01b03811681146200054357600080fd5b919050565b600080600080600080600060e0888a0312156200056457600080fd5b87516001600160401b03808211156200057c57600080fd5b6200058a8b838c016200049a565b985060208a0151915080821115620005a157600080fd5b620005af8b838c016200049a565b9750620005bf60408b016200052b565b965060608a01519550620005d660808b016200052b565b945060a08a0151915061ffff82168214620005f057600080fd5b60c08a0151919350808211156200060657600080fd5b50620006158a828b016200049a565b91505092959891949750929550565b6000602082840312156200063757600080fd5b81516001600160401b038111156200064e57600080fd5b6200065c848285016200049a565b949350505050565b600082516200067881846020870162000467565b9190910192915050565b600181811c908216806200069757607f821691505b60208210811415620006b957634e487b7160e01b600052602260045260246000fd5b50919050565b60805160a05160c051612fa86200070b60003960008181610415015281816109b601526114e90152600081816102c70152610b560152600081816104f90152610b800152612fa86000f3fe608060405234801561001057600080fd5b50600436106102955760003560e01c806370a0823111610167578063b39ba60a116100ce578063d5edf45b11610087578063d5edf45b146105fb578063d7dd397d1461060f578063e985e9c514610622578063f2fde38b14610635578063fb12a87614610648578063ffa1ad741461065b57600080fd5b8063b39ba60a14610588578063b88d4fde1461059b578063bb0aa8ef146105ae578063c87b56dd146105c2578063c95ab462146105d5578063cd161d2e146105e857600080fd5b80638ce87646116101205780638ce876461461052e5780638da5cb5b1461054157806395d89b4114610552578063a22cb4651461055a578063a47a2e771461056d578063a790c0e21461058057600080fd5b806370a08231146104b6578063715018a6146104c95780637ff9f614146104d15780638456cb59146104e4578063875d364e146104ec5780638a71bb2d146104f457600080fd5b80632a55205a1161020b5780634f6ccce7116101c45780634f6ccce71461045257806355f804b3146104655780635b7633d0146104785780635c975abb146104905780636352211e1461049b5780636c0360eb146104ae57600080fd5b80632a55205a146103b85780632f745c59146103ea5780633ad0288e146103fd5780633ef110f1146104105780633f4ba83a1461043757806342842e0e1461043f57600080fd5b80630c9999291161025d5780630c9999291461033e57806313e2263e1461035657806318160ddd1461036a5780631ad32562146103725780631dd8354c1461039257806323b872dd146103a557600080fd5b806301ffc9a71461029a57806302d05d3f146102c257806306fdde0314610301578063081812fc14610316578063095ea7b314610329575b600080fd5b6102ad6102a83660046127a7565b610675565b60405190151581526020015b60405180910390f35b6102e97f000000000000000000000000000000000000000000000000000000000000000081565b6040516001600160a01b0390911681526020016102b9565b6103096106a0565b6040516102b9919061281c565b6102e961032436600461282f565b610732565b61033c610337366004612864565b610759565b005b6103486201518081565b6040519081526020016102b9565b600d546102ad90600160a81b900460ff1681565b600854610348565b61034861038036600461288e565b600c6020526000908152604090205481565b61033c6103a03660046128a9565b610874565b61033c6103b336600461291e565b610b20565b6103cb6103c636600461295a565b610b51565b604080516001600160a01b0390931683526020830191909152016102b9565b6103486103f8366004612864565b610bbc565b61033c61040b36600461298a565b610c52565b6103487f000000000000000000000000000000000000000000000000000000000000000081565b61033c610d5d565b61033c61044d36600461291e565b610d6f565b61034861046036600461282f565b610d8a565b61033c610473366004612a4d565b610e1d565b600d546102e99061010090046001600160a01b031681565b600d5460ff166102ad565b6102e96104a936600461282f565b610e8c565b610309610eec565b6103486104c436600461288e565b610f7a565b61033c611000565b61033c6104df36600461288e565b611012565b61033c6110aa565b61033c6110ba565b61051b7f000000000000000000000000000000000000000000000000000000000000000081565b60405161ffff90911681526020016102b9565b61033c61053c36600461288e565b6110d7565b600a546001600160a01b03166102e9565b61030961112d565b61033c61056836600461298a565b61113c565b61033c61057b36600461288e565b611147565b61033c6111db565b600f546102e9906001600160a01b031681565b61033c6105a9366004612ab6565b611229565b600d546102ad90600160b01b900460ff1681565b6103096105d036600461282f565b611261565b600b546102e9906001600160a01b031681565b61033c6105f636600461288e565b6112c8565b600b546102ad90600160a01b900460ff1681565b61033c61061d366004612b1e565b6113f6565b6102ad610630366004612b81565b611581565b61033c61064336600461288e565b611693565b6102ad61065636600461288e565b611709565b610663600181565b60405160ff90911681526020016102b9565b60006001600160e01b0319821663780e9d6360e01b148061069a575061069a82611746565b92915050565b6060600080546106af90612bb4565b80601f01602080910402602001604051908101604052809291908181526020018280546106db90612bb4565b80156107285780601f106106fd57610100808354040283529160200191610728565b820191906000526020600020905b81548152906001019060200180831161070b57829003601f168201915b5050505050905090565b600061073d82611796565b506000908152600460205260409020546001600160a01b031690565b600061076482610e8c565b9050806001600160a01b0316836001600160a01b031614156107d75760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b03821614806107f357506107f38133611581565b6108655760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c000060648201526084016107ce565b61086f83836117f5565b505050565b61087c611863565b600d54600160a81b900460ff1615156001146108cd5760405162461bcd60e51b815260206004820152601060248201526f1b5a5b9d1a5b99c8191a5cd8589b195960821b60448201526064016107ce565b60005b63ffffffff811682111561086f57600083838363ffffffff168181106108f8576108f8612bef565b905060200281019061090a9190612c05565b61091390612c25565b6040808201516000908152600260205220549091506001600160a01b03161561096d5760405162461bcd60e51b815260206004820152600c60248201526b746f6b656e2065786973747360a01b60448201526064016107ce565b80516001600160a01b031633146109b45760405162461bcd60e51b815260206004820152600b60248201526a37bbb732b91032b93937b960a91b60448201526064016107ce565b7f00000000000000000000000000000000000000000000000000000000000000006109de60085490565b6109e9906001612cb8565b1115610a295760405162461bcd60e51b815260206004820152600f60248201526e657863656564656420737570706c7960881b60448201526064016107ce565b60408051606080820183528383015180835284516001600160a01b03908116602080860191825230868801908152875191820194909452905182169581019590955290511690830152906000906080016040516020818303038152906040528051906020012090506000610aaa8460200151836118a990919063ffffffff16565b600d549091506001600160a01b038083166101009092041614610afb5760405162461bcd60e51b815260206004820152600960248201526839b4b39032b93937b960b91b60448201526064016107ce565b610b093385604001516118cd565b505050508080610b1890612cd0565b9150506108d0565b610b2a33826118e7565b610b465760405162461bcd60e51b81526004016107ce90612cf4565b61086f838383611946565b6000807f0000000000000000000000000000000000000000000000000000000000000000612710610ba661ffff7f00000000000000000000000000000000000000000000000000000000000000001686612d42565b610bb09190612d77565b915091505b9250929050565b6000610bc783610f7a565b8210610c295760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b60648201526084016107ce565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b610c5a611863565b610c6333611709565b610ca75760405162461bcd60e51b81526020600482015260156024820152743ab730baba3437b934bd32b21027a127903ab9b2b960591b60448201526064016107ce565b6001600160a01b038216610cec5760405162461bcd60e51b815260206004820152600c60248201526b63616e74206265207a65726f60a01b60448201526064016107ce565b600d8054610100600160b01b0319166101006001600160a01b03858116820260ff60a81b191692909217600160a81b85151502179283905560405192041681527f892cc3ddabcf4697be271eb3df1f098bec1713e58e7287c001532df08b5ebaab9060200160405180910390a15050565b610d65611aed565b610d6d611b47565b565b61086f83838360405180602001604052806000815250611229565b6000610d9560085490565b8210610df85760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b60648201526084016107ce565b60088281548110610e0b57610e0b612bef565b90600052602060002001549050919050565b610e25611aed565b610e2d611863565b600d54600160b01b900460ff1615610e755760405162461bcd60e51b815260206004820152600b60248201526a63616e74206368616e676560a81b60448201526064016107ce565b8051610e8890600e9060208401906126f8565b5050565b6000818152600260205260408120546001600160a01b03168061069a5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016107ce565b600e8054610ef990612bb4565b80601f0160208091040260200160405190810160405280929190818152602001828054610f2590612bb4565b8015610f725780601f10610f4757610100808354040283529160200191610f72565b820191906000526020600020905b815481529060010190602001808311610f5557829003601f168201915b505050505081565b60006001600160a01b038216610fe45760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016107ce565b506001600160a01b031660009081526003602052604090205490565b611008611aed565b610d6d6000611b99565b600a546001600160a01b03163314806110355750600b546001600160a01b031633145b6110515760405162461bcd60e51b81526004016107ce90612d8b565b6001600160a01b0381166000818152600c602090815260408083208390558051938452908301919091527fe2e2dad866561a9926816384b10b4073c5e0e101b6c911e4936d22438bd63e9b91015b60405180910390a150565b6110b2611aed565b610d6d611beb565b6110c2611aed565b600d805460ff60b01b1916600160b01b179055565b6110df611aed565b600b80546001600160a01b0319166001600160a01b0383169081179091556040519081527ffbd1c2e6a1f767e08b9689ca3ce8ca1e7b60fbb71734bfc34f39f5bcb846cf309060200161109f565b6060600180546106af90612bb4565b610e88338383611c28565b600a546001600160a01b031633148061116a5750600b546001600160a01b031633145b6111865760405162461bcd60e51b81526004016107ce90612d8b565b600b54600160a01b900460ff1615156001146111cf5760405162461bcd60e51b8152602060048201526008602482015267191a5cd8589b195960c21b60448201526064016107ce565b6111d881611cf7565b50565b600a546001600160a01b03163314806111fe5750600b546001600160a01b031633145b61121a5760405162461bcd60e51b81526004016107ce90612d8b565b600b805460ff60a01b19169055565b61123333836118e7565b61124f5760405162461bcd60e51b81526004016107ce90612cf4565b61125b84848484611dae565b50505050565b606061126c82611796565b6000611276611de1565b9050600081511161129657604051806020016040528060008152506112c1565b806112a084611df0565b6040516020016112b1929190612db1565b6040516020818303038152906040525b9392505050565b600a546001600160a01b03163314806112eb5750600b546001600160a01b031633145b6113075760405162461bcd60e51b81526004016107ce90612d8b565b6001600160a01b03811661134e5760405162461bcd60e51b815260206004820152600e60248201526d0c6c2dce840e6cae840e8de4060f60931b60448201526064016107ce565b6001600160a01b0381166000908152600c6020526040902054156113a45760405162461bcd60e51b815260206004820152600d60248201526c185b1c9958591e481859191959609a1b60448201526064016107ce565b6001600160a01b0381166000818152600c602090815260409182902042905581519283526001908301527fe2e2dad866561a9926816384b10b4073c5e0e101b6c911e4936d22438bd63e9b910161109f565b6113ff33611709565b6114435760405162461bcd60e51b81526020600482015260156024820152743ab730baba3437b934bd32b21027a127903ab9b2b960591b60448201526064016107ce565b60005b63ffffffff811682111561086f57600083838363ffffffff1681811061146e5761146e612bef565b9050604002018036038101906114849190612de0565b90506114ab81602001516000908152600260205260409020546001600160a01b0316151590565b156114e75760405162461bcd60e51b815260206004820152600c60248201526b746f6b656e2065786973747360a01b60448201526064016107ce565b7f000000000000000000000000000000000000000000000000000000000000000061151160085490565b61151c906001612cb8565b111561155c5760405162461bcd60e51b815260206004820152600f60248201526e657863656564656420737570706c7960881b60448201526064016107ce565b61156e816000015182602001516118cd565b508061157981612cd0565b915050611446565b600f546000906001600160a01b03166115cd5760405162461bcd60e51b815260206004820152600e60248201526d07265676973747279203d203078360941b60448201526064016107ce565b600f546040516319f5a9f760e21b81526001600160a01b0384811660048301528581166024830152909116906367d6a7dc9060440160206040518083038186803b15801561161a57600080fd5b505afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190612e37565b1515600114156116645750600161069a565b506001600160a01b0382811660009081526005602090815260408083209385168352929052205460ff1661069a565b61169b611aed565b6001600160a01b0381166117005760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016107ce565b6111d881611b99565b6001600160a01b0381166000908152600c6020526040812054806117305750600092915050565b6201518061173e8242612e54565b119392505050565b60006001600160e01b031982166380ac58cd60e01b148061177757506001600160e01b03198216635b5e139f60e01b145b8061069a57506301ffc9a760e01b6001600160e01b031983161461069a565b6000818152600260205260409020546001600160a01b03166111d85760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016107ce565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061182a82610e8c565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600d5460ff1615610d6d5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016107ce565b60008060006118b88585611eee565b915091506118c581611f31565b509392505050565b610e888282604051806020016040528060008152506120ec565b6000806118f383610e8c565b9050806001600160a01b0316846001600160a01b0316148061191a575061191a8185611581565b8061193e5750836001600160a01b031661193384610732565b6001600160a01b0316145b949350505050565b826001600160a01b031661195982610e8c565b6001600160a01b0316146119bd5760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b60648201526084016107ce565b6001600160a01b038216611a1f5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016107ce565b611a2a83838361211f565b611a356000826117f5565b6001600160a01b0383166000908152600360205260408120805460019290611a5e908490612e54565b90915550506001600160a01b0382166000908152600360205260408120805460019290611a8c908490612cb8565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600a546001600160a01b03163314610d6d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107ce565b611b4f6121d7565b600d805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b611bf3611863565b600d805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611b7c3390565b816001600160a01b0316836001600160a01b03161415611c8a5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016107ce565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611cff611aed565b6001600160a01b038116611d3f5760405162461bcd60e51b81526020600482015260076024820152666164647228302960c81b60448201526064016107ce565b6001611d4e6201518042612e54565b611d589190612e54565b6001600160a01b0382166000818152600c60209081526040918290209390935580519182526001928201929092527fe2e2dad866561a9926816384b10b4073c5e0e101b6c911e4936d22438bd63e9b910161109f565b611db9848484611946565b611dc584848484612220565b61125b5760405162461bcd60e51b81526004016107ce90612e6b565b6060600e80546106af90612bb4565b606081611e145750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611e3e5780611e2881612ebd565b9150611e379050600a83612d77565b9150611e18565b60008167ffffffffffffffff811115611e5957611e596129c1565b6040519080825280601f01601f191660200182016040528015611e83576020820181803683370190505b5090505b841561193e57611e98600183612e54565b9150611ea5600a86612ed8565b611eb0906030612cb8565b60f81b818381518110611ec557611ec5612bef565b60200101906001600160f81b031916908160001a905350611ee7600a86612d77565b9450611e87565b600080825160411415611f255760208301516040840151606085015160001a611f198782858561232d565b94509450505050610bb5565b50600090506002610bb5565b6000816004811115611f4557611f45612eec565b1415611f4e5750565b6001816004811115611f6257611f62612eec565b1415611fb05760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016107ce565b6002816004811115611fc457611fc4612eec565b14156120125760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016107ce565b600381600481111561202657612026612eec565b141561207f5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016107ce565b600481600481111561209357612093612eec565b14156111d85760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016107ce565b6120f6838361241a565b6121036000848484612220565b61086f5760405162461bcd60e51b81526004016107ce90612e6b565b6001600160a01b03831661217a5761217581600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b61219d565b816001600160a01b0316836001600160a01b03161461219d5761219d8382612568565b6001600160a01b0382166121b45761086f81612605565b826001600160a01b0316826001600160a01b03161461086f5761086f82826126b4565b600d5460ff16610d6d5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016107ce565b60006001600160a01b0384163b1561232257604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612264903390899088908890600401612f02565b602060405180830381600087803b15801561227e57600080fd5b505af19250505080156122ae575060408051601f3d908101601f191682019092526122ab91810190612f3f565b60015b612308573d8080156122dc576040519150601f19603f3d011682016040523d82523d6000602084013e6122e1565b606091505b5080516123005760405162461bcd60e51b81526004016107ce90612e6b565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061193e565b506001949350505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156123645750600090506003612411565b8460ff16601b1415801561237c57508460ff16601c14155b1561238d5750600090506004612411565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156123e1573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661240a57600060019250925050612411565b9150600090505b94509492505050565b6001600160a01b0382166124705760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016107ce565b6000818152600260205260409020546001600160a01b0316156124d55760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016107ce565b6124e16000838361211f565b6001600160a01b038216600090815260036020526040812080546001929061250a908490612cb8565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000600161257584610f7a565b61257f9190612e54565b6000838152600760205260409020549091508082146125d2576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061261790600190612e54565b6000838152600960205260408120546008805493945090928490811061263f5761263f612bef565b90600052602060002001549050806008838154811061266057612660612bef565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061269857612698612f5c565b6001900381819060005260206000200160009055905550505050565b60006126bf83610f7a565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b82805461270490612bb4565b90600052602060002090601f016020900481019282612726576000855561276c565b82601f1061273f57805160ff191683800117855561276c565b8280016001018555821561276c579182015b8281111561276c578251825591602001919060010190612751565b5061277892915061277c565b5090565b5b80821115612778576000815560010161277d565b6001600160e01b0319811681146111d857600080fd5b6000602082840312156127b957600080fd5b81356112c181612791565b60005b838110156127df5781810151838201526020016127c7565b8381111561125b5750506000910152565b600081518084526128088160208601602086016127c4565b601f01601f19169290920160200192915050565b6020815260006112c160208301846127f0565b60006020828403121561284157600080fd5b5035919050565b80356001600160a01b038116811461285f57600080fd5b919050565b6000806040838503121561287757600080fd5b61288083612848565b946020939093013593505050565b6000602082840312156128a057600080fd5b6112c182612848565b600080602083850312156128bc57600080fd5b823567ffffffffffffffff808211156128d457600080fd5b818501915085601f8301126128e857600080fd5b8135818111156128f757600080fd5b8660208260051b850101111561290c57600080fd5b60209290920196919550909350505050565b60008060006060848603121561293357600080fd5b61293c84612848565b925061294a60208501612848565b9150604084013590509250925092565b6000806040838503121561296d57600080fd5b50508035926020909101359150565b80151581146111d857600080fd5b6000806040838503121561299d57600080fd5b6129a683612848565b915060208301356129b68161297c565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff808411156129f2576129f26129c1565b604051601f8501601f19908116603f01168101908282118183101715612a1a57612a1a6129c1565b81604052809350858152868686011115612a3357600080fd5b858560208301376000602087830101525050509392505050565b600060208284031215612a5f57600080fd5b813567ffffffffffffffff811115612a7657600080fd5b8201601f81018413612a8757600080fd5b61193e848235602084016129d7565b600082601f830112612aa757600080fd5b6112c1838335602085016129d7565b60008060008060808587031215612acc57600080fd5b612ad585612848565b9350612ae360208601612848565b925060408501359150606085013567ffffffffffffffff811115612b0657600080fd5b612b1287828801612a96565b91505092959194509250565b60008060208385031215612b3157600080fd5b823567ffffffffffffffff80821115612b4957600080fd5b818501915085601f830112612b5d57600080fd5b813581811115612b6c57600080fd5b8660208260061b850101111561290c57600080fd5b60008060408385031215612b9457600080fd5b612b9d83612848565b9150612bab60208401612848565b90509250929050565b600181811c90821680612bc857607f821691505b60208210811415612be957634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b60008235605e19833603018112612c1b57600080fd5b9190910192915050565b600060608236031215612c3757600080fd5b6040516060810167ffffffffffffffff8282108183111715612c5b57612c5b6129c1565b81604052612c6885612848565b83526020850135915080821115612c7e57600080fd5b50612c8b36828601612a96565b602083015250604092830135928101929092525090565b634e487b7160e01b600052601160045260246000fd5b60008219821115612ccb57612ccb612ca2565b500190565b600063ffffffff80831681811415612cea57612cea612ca2565b6001019392505050565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b6000816000190483118215151615612d5c57612d5c612ca2565b500290565b634e487b7160e01b600052601260045260246000fd5b600082612d8657612d86612d61565b500490565b6020808252600c908201526b3737ba1037b137a0b236b4b760a11b604082015260600190565b60008351612dc38184602088016127c4565b835190830190612dd78183602088016127c4565b01949350505050565b600060408284031215612df257600080fd5b6040516040810181811067ffffffffffffffff82111715612e1557612e156129c1565b604052612e2183612848565b8152602083013560208201528091505092915050565b600060208284031215612e4957600080fd5b81516112c18161297c565b600082821015612e6657612e66612ca2565b500390565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6000600019821415612ed157612ed1612ca2565b5060010190565b600082612ee757612ee7612d61565b500690565b634e487b7160e01b600052602160045260246000fd5b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612f35908301846127f0565b9695505050505050565b600060208284031215612f5157600080fd5b81516112c181612791565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220ab0e4c6d8cef565e9f008d017cd6654efaa4350407a69f4957b462d3c2b449fd64736f6c6343000809003300000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000085508ce7885b65a57ee070460055f3e4b412051e00000000000000000000000000000000000000000000000000000000000027100000000000000000000000002a0a9e9433ca36df4dfff14b2a5d42003b4e5d2700000000000000000000000000000000000000000000000000000000000001f40000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000001c4261627920536861726b3a20436f6c6c656374696f6e204e6f2e203200000000000000000000000000000000000000000000000000000000000000000000000442534e32000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007697066733a2f2f00000000000000000000000000000000000000000000000000

Deployed Bytecode

0x608060405234801561001057600080fd5b50600436106102955760003560e01c806370a0823111610167578063b39ba60a116100ce578063d5edf45b11610087578063d5edf45b146105fb578063d7dd397d1461060f578063e985e9c514610622578063f2fde38b14610635578063fb12a87614610648578063ffa1ad741461065b57600080fd5b8063b39ba60a14610588578063b88d4fde1461059b578063bb0aa8ef146105ae578063c87b56dd146105c2578063c95ab462146105d5578063cd161d2e146105e857600080fd5b80638ce87646116101205780638ce876461461052e5780638da5cb5b1461054157806395d89b4114610552578063a22cb4651461055a578063a47a2e771461056d578063a790c0e21461058057600080fd5b806370a08231146104b6578063715018a6146104c95780637ff9f614146104d15780638456cb59146104e4578063875d364e146104ec5780638a71bb2d146104f457600080fd5b80632a55205a1161020b5780634f6ccce7116101c45780634f6ccce71461045257806355f804b3146104655780635b7633d0146104785780635c975abb146104905780636352211e1461049b5780636c0360eb146104ae57600080fd5b80632a55205a146103b85780632f745c59146103ea5780633ad0288e146103fd5780633ef110f1146104105780633f4ba83a1461043757806342842e0e1461043f57600080fd5b80630c9999291161025d5780630c9999291461033e57806313e2263e1461035657806318160ddd1461036a5780631ad32562146103725780631dd8354c1461039257806323b872dd146103a557600080fd5b806301ffc9a71461029a57806302d05d3f146102c257806306fdde0314610301578063081812fc14610316578063095ea7b314610329575b600080fd5b6102ad6102a83660046127a7565b610675565b60405190151581526020015b60405180910390f35b6102e97f0000000000000000000000002a0a9e9433ca36df4dfff14b2a5d42003b4e5d2781565b6040516001600160a01b0390911681526020016102b9565b6103096106a0565b6040516102b9919061281c565b6102e961032436600461282f565b610732565b61033c610337366004612864565b610759565b005b6103486201518081565b6040519081526020016102b9565b600d546102ad90600160a81b900460ff1681565b600854610348565b61034861038036600461288e565b600c6020526000908152604090205481565b61033c6103a03660046128a9565b610874565b61033c6103b336600461291e565b610b20565b6103cb6103c636600461295a565b610b51565b604080516001600160a01b0390931683526020830191909152016102b9565b6103486103f8366004612864565b610bbc565b61033c61040b36600461298a565b610c52565b6103487f000000000000000000000000000000000000000000000000000000000000271081565b61033c610d5d565b61033c61044d36600461291e565b610d6f565b61034861046036600461282f565b610d8a565b61033c610473366004612a4d565b610e1d565b600d546102e99061010090046001600160a01b031681565b600d5460ff166102ad565b6102e96104a936600461282f565b610e8c565b610309610eec565b6103486104c436600461288e565b610f7a565b61033c611000565b61033c6104df36600461288e565b611012565b61033c6110aa565b61033c6110ba565b61051b7f00000000000000000000000000000000000000000000000000000000000001f481565b60405161ffff90911681526020016102b9565b61033c61053c36600461288e565b6110d7565b600a546001600160a01b03166102e9565b61030961112d565b61033c61056836600461298a565b61113c565b61033c61057b36600461288e565b611147565b61033c6111db565b600f546102e9906001600160a01b031681565b61033c6105a9366004612ab6565b611229565b600d546102ad90600160b01b900460ff1681565b6103096105d036600461282f565b611261565b600b546102e9906001600160a01b031681565b61033c6105f636600461288e565b6112c8565b600b546102ad90600160a01b900460ff1681565b61033c61061d366004612b1e565b6113f6565b6102ad610630366004612b81565b611581565b61033c61064336600461288e565b611693565b6102ad61065636600461288e565b611709565b610663600181565b60405160ff90911681526020016102b9565b60006001600160e01b0319821663780e9d6360e01b148061069a575061069a82611746565b92915050565b6060600080546106af90612bb4565b80601f01602080910402602001604051908101604052809291908181526020018280546106db90612bb4565b80156107285780601f106106fd57610100808354040283529160200191610728565b820191906000526020600020905b81548152906001019060200180831161070b57829003601f168201915b5050505050905090565b600061073d82611796565b506000908152600460205260409020546001600160a01b031690565b600061076482610e8c565b9050806001600160a01b0316836001600160a01b031614156107d75760405162461bcd60e51b815260206004820152602160248201527f4552433732313a20617070726f76616c20746f2063757272656e74206f776e656044820152603960f91b60648201526084015b60405180910390fd5b336001600160a01b03821614806107f357506107f38133611581565b6108655760405162461bcd60e51b815260206004820152603e60248201527f4552433732313a20617070726f76652063616c6c6572206973206e6f7420746f60448201527f6b656e206f776e6572206e6f7220617070726f76656420666f7220616c6c000060648201526084016107ce565b61086f83836117f5565b505050565b61087c611863565b600d54600160a81b900460ff1615156001146108cd5760405162461bcd60e51b815260206004820152601060248201526f1b5a5b9d1a5b99c8191a5cd8589b195960821b60448201526064016107ce565b60005b63ffffffff811682111561086f57600083838363ffffffff168181106108f8576108f8612bef565b905060200281019061090a9190612c05565b61091390612c25565b6040808201516000908152600260205220549091506001600160a01b03161561096d5760405162461bcd60e51b815260206004820152600c60248201526b746f6b656e2065786973747360a01b60448201526064016107ce565b80516001600160a01b031633146109b45760405162461bcd60e51b815260206004820152600b60248201526a37bbb732b91032b93937b960a91b60448201526064016107ce565b7f00000000000000000000000000000000000000000000000000000000000027106109de60085490565b6109e9906001612cb8565b1115610a295760405162461bcd60e51b815260206004820152600f60248201526e657863656564656420737570706c7960881b60448201526064016107ce565b60408051606080820183528383015180835284516001600160a01b03908116602080860191825230868801908152875191820194909452905182169581019590955290511690830152906000906080016040516020818303038152906040528051906020012090506000610aaa8460200151836118a990919063ffffffff16565b600d549091506001600160a01b038083166101009092041614610afb5760405162461bcd60e51b815260206004820152600960248201526839b4b39032b93937b960b91b60448201526064016107ce565b610b093385604001516118cd565b505050508080610b1890612cd0565b9150506108d0565b610b2a33826118e7565b610b465760405162461bcd60e51b81526004016107ce90612cf4565b61086f838383611946565b6000807f0000000000000000000000002a0a9e9433ca36df4dfff14b2a5d42003b4e5d27612710610ba661ffff7f00000000000000000000000000000000000000000000000000000000000001f41686612d42565b610bb09190612d77565b915091505b9250929050565b6000610bc783610f7a565b8210610c295760405162461bcd60e51b815260206004820152602b60248201527f455243373231456e756d657261626c653a206f776e657220696e646578206f7560448201526a74206f6620626f756e647360a81b60648201526084016107ce565b506001600160a01b03919091166000908152600660209081526040808320938352929052205490565b610c5a611863565b610c6333611709565b610ca75760405162461bcd60e51b81526020600482015260156024820152743ab730baba3437b934bd32b21027a127903ab9b2b960591b60448201526064016107ce565b6001600160a01b038216610cec5760405162461bcd60e51b815260206004820152600c60248201526b63616e74206265207a65726f60a01b60448201526064016107ce565b600d8054610100600160b01b0319166101006001600160a01b03858116820260ff60a81b191692909217600160a81b85151502179283905560405192041681527f892cc3ddabcf4697be271eb3df1f098bec1713e58e7287c001532df08b5ebaab9060200160405180910390a15050565b610d65611aed565b610d6d611b47565b565b61086f83838360405180602001604052806000815250611229565b6000610d9560085490565b8210610df85760405162461bcd60e51b815260206004820152602c60248201527f455243373231456e756d657261626c653a20676c6f62616c20696e646578206f60448201526b7574206f6620626f756e647360a01b60648201526084016107ce565b60088281548110610e0b57610e0b612bef565b90600052602060002001549050919050565b610e25611aed565b610e2d611863565b600d54600160b01b900460ff1615610e755760405162461bcd60e51b815260206004820152600b60248201526a63616e74206368616e676560a81b60448201526064016107ce565b8051610e8890600e9060208401906126f8565b5050565b6000818152600260205260408120546001600160a01b03168061069a5760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016107ce565b600e8054610ef990612bb4565b80601f0160208091040260200160405190810160405280929190818152602001828054610f2590612bb4565b8015610f725780601f10610f4757610100808354040283529160200191610f72565b820191906000526020600020905b815481529060010190602001808311610f5557829003601f168201915b505050505081565b60006001600160a01b038216610fe45760405162461bcd60e51b815260206004820152602960248201527f4552433732313a2061646472657373207a65726f206973206e6f7420612076616044820152683634b21037bbb732b960b91b60648201526084016107ce565b506001600160a01b031660009081526003602052604090205490565b611008611aed565b610d6d6000611b99565b600a546001600160a01b03163314806110355750600b546001600160a01b031633145b6110515760405162461bcd60e51b81526004016107ce90612d8b565b6001600160a01b0381166000818152600c602090815260408083208390558051938452908301919091527fe2e2dad866561a9926816384b10b4073c5e0e101b6c911e4936d22438bd63e9b91015b60405180910390a150565b6110b2611aed565b610d6d611beb565b6110c2611aed565b600d805460ff60b01b1916600160b01b179055565b6110df611aed565b600b80546001600160a01b0319166001600160a01b0383169081179091556040519081527ffbd1c2e6a1f767e08b9689ca3ce8ca1e7b60fbb71734bfc34f39f5bcb846cf309060200161109f565b6060600180546106af90612bb4565b610e88338383611c28565b600a546001600160a01b031633148061116a5750600b546001600160a01b031633145b6111865760405162461bcd60e51b81526004016107ce90612d8b565b600b54600160a01b900460ff1615156001146111cf5760405162461bcd60e51b8152602060048201526008602482015267191a5cd8589b195960c21b60448201526064016107ce565b6111d881611cf7565b50565b600a546001600160a01b03163314806111fe5750600b546001600160a01b031633145b61121a5760405162461bcd60e51b81526004016107ce90612d8b565b600b805460ff60a01b19169055565b61123333836118e7565b61124f5760405162461bcd60e51b81526004016107ce90612cf4565b61125b84848484611dae565b50505050565b606061126c82611796565b6000611276611de1565b9050600081511161129657604051806020016040528060008152506112c1565b806112a084611df0565b6040516020016112b1929190612db1565b6040516020818303038152906040525b9392505050565b600a546001600160a01b03163314806112eb5750600b546001600160a01b031633145b6113075760405162461bcd60e51b81526004016107ce90612d8b565b6001600160a01b03811661134e5760405162461bcd60e51b815260206004820152600e60248201526d0c6c2dce840e6cae840e8de4060f60931b60448201526064016107ce565b6001600160a01b0381166000908152600c6020526040902054156113a45760405162461bcd60e51b815260206004820152600d60248201526c185b1c9958591e481859191959609a1b60448201526064016107ce565b6001600160a01b0381166000818152600c602090815260409182902042905581519283526001908301527fe2e2dad866561a9926816384b10b4073c5e0e101b6c911e4936d22438bd63e9b910161109f565b6113ff33611709565b6114435760405162461bcd60e51b81526020600482015260156024820152743ab730baba3437b934bd32b21027a127903ab9b2b960591b60448201526064016107ce565b60005b63ffffffff811682111561086f57600083838363ffffffff1681811061146e5761146e612bef565b9050604002018036038101906114849190612de0565b90506114ab81602001516000908152600260205260409020546001600160a01b0316151590565b156114e75760405162461bcd60e51b815260206004820152600c60248201526b746f6b656e2065786973747360a01b60448201526064016107ce565b7f000000000000000000000000000000000000000000000000000000000000271061151160085490565b61151c906001612cb8565b111561155c5760405162461bcd60e51b815260206004820152600f60248201526e657863656564656420737570706c7960881b60448201526064016107ce565b61156e816000015182602001516118cd565b508061157981612cd0565b915050611446565b600f546000906001600160a01b03166115cd5760405162461bcd60e51b815260206004820152600e60248201526d07265676973747279203d203078360941b60448201526064016107ce565b600f546040516319f5a9f760e21b81526001600160a01b0384811660048301528581166024830152909116906367d6a7dc9060440160206040518083038186803b15801561161a57600080fd5b505afa15801561162e573d6000803e3d6000fd5b505050506040513d601f19601f820116820180604052508101906116529190612e37565b1515600114156116645750600161069a565b506001600160a01b0382811660009081526005602090815260408083209385168352929052205460ff1661069a565b61169b611aed565b6001600160a01b0381166117005760405162461bcd60e51b815260206004820152602660248201527f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160448201526564647265737360d01b60648201526084016107ce565b6111d881611b99565b6001600160a01b0381166000908152600c6020526040812054806117305750600092915050565b6201518061173e8242612e54565b119392505050565b60006001600160e01b031982166380ac58cd60e01b148061177757506001600160e01b03198216635b5e139f60e01b145b8061069a57506301ffc9a760e01b6001600160e01b031983161461069a565b6000818152600260205260409020546001600160a01b03166111d85760405162461bcd60e51b8152602060048201526018602482015277115490cdcc8c4e881a5b9d985b1a59081d1bdad95b88125160421b60448201526064016107ce565b600081815260046020526040902080546001600160a01b0319166001600160a01b038416908117909155819061182a82610e8c565b6001600160a01b03167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600d5460ff1615610d6d5760405162461bcd60e51b815260206004820152601060248201526f14185d5cd8589b194e881c185d5cd95960821b60448201526064016107ce565b60008060006118b88585611eee565b915091506118c581611f31565b509392505050565b610e888282604051806020016040528060008152506120ec565b6000806118f383610e8c565b9050806001600160a01b0316846001600160a01b0316148061191a575061191a8185611581565b8061193e5750836001600160a01b031661193384610732565b6001600160a01b0316145b949350505050565b826001600160a01b031661195982610e8c565b6001600160a01b0316146119bd5760405162461bcd60e51b815260206004820152602560248201527f4552433732313a207472616e736665722066726f6d20696e636f72726563742060448201526437bbb732b960d91b60648201526084016107ce565b6001600160a01b038216611a1f5760405162461bcd60e51b8152602060048201526024808201527f4552433732313a207472616e7366657220746f20746865207a65726f206164646044820152637265737360e01b60648201526084016107ce565b611a2a83838361211f565b611a356000826117f5565b6001600160a01b0383166000908152600360205260408120805460019290611a5e908490612e54565b90915550506001600160a01b0382166000908152600360205260408120805460019290611a8c908490612cb8565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b0386811691821790925591518493918716917fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef91a4505050565b600a546001600160a01b03163314610d6d5760405162461bcd60e51b815260206004820181905260248201527f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e657260448201526064016107ce565b611b4f6121d7565b600d805460ff191690557f5db9ee0a495bf2e6ff9c91a7834c1ba4fdd244a5e8aa4e537bd38aeae4b073aa335b6040516001600160a01b03909116815260200160405180910390a1565b600a80546001600160a01b038381166001600160a01b0319831681179093556040519116919082907f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e090600090a35050565b611bf3611863565b600d805460ff191660011790557f62e78cea01bee320cd4e420270b5ea74000d11b0c9f74754ebdbfc544b05a258611b7c3390565b816001600160a01b0316836001600160a01b03161415611c8a5760405162461bcd60e51b815260206004820152601960248201527f4552433732313a20617070726f766520746f2063616c6c65720000000000000060448201526064016107ce565b6001600160a01b03838116600081815260056020908152604080832094871680845294825291829020805460ff191686151590811790915591519182527f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31910160405180910390a3505050565b611cff611aed565b6001600160a01b038116611d3f5760405162461bcd60e51b81526020600482015260076024820152666164647228302960c81b60448201526064016107ce565b6001611d4e6201518042612e54565b611d589190612e54565b6001600160a01b0382166000818152600c60209081526040918290209390935580519182526001928201929092527fe2e2dad866561a9926816384b10b4073c5e0e101b6c911e4936d22438bd63e9b910161109f565b611db9848484611946565b611dc584848484612220565b61125b5760405162461bcd60e51b81526004016107ce90612e6b565b6060600e80546106af90612bb4565b606081611e145750506040805180820190915260018152600360fc1b602082015290565b8160005b8115611e3e5780611e2881612ebd565b9150611e379050600a83612d77565b9150611e18565b60008167ffffffffffffffff811115611e5957611e596129c1565b6040519080825280601f01601f191660200182016040528015611e83576020820181803683370190505b5090505b841561193e57611e98600183612e54565b9150611ea5600a86612ed8565b611eb0906030612cb8565b60f81b818381518110611ec557611ec5612bef565b60200101906001600160f81b031916908160001a905350611ee7600a86612d77565b9450611e87565b600080825160411415611f255760208301516040840151606085015160001a611f198782858561232d565b94509450505050610bb5565b50600090506002610bb5565b6000816004811115611f4557611f45612eec565b1415611f4e5750565b6001816004811115611f6257611f62612eec565b1415611fb05760405162461bcd60e51b815260206004820152601860248201527f45434453413a20696e76616c6964207369676e6174757265000000000000000060448201526064016107ce565b6002816004811115611fc457611fc4612eec565b14156120125760405162461bcd60e51b815260206004820152601f60248201527f45434453413a20696e76616c6964207369676e6174757265206c656e6774680060448201526064016107ce565b600381600481111561202657612026612eec565b141561207f5760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202773272076616c604482015261756560f01b60648201526084016107ce565b600481600481111561209357612093612eec565b14156111d85760405162461bcd60e51b815260206004820152602260248201527f45434453413a20696e76616c6964207369676e6174757265202776272076616c604482015261756560f01b60648201526084016107ce565b6120f6838361241a565b6121036000848484612220565b61086f5760405162461bcd60e51b81526004016107ce90612e6b565b6001600160a01b03831661217a5761217581600880546000838152600960205260408120829055600182018355919091527ff3f7a9fe364faab93b216da50a3214154f22a0a2b415b23a84c8169e8b636ee30155565b61219d565b816001600160a01b0316836001600160a01b03161461219d5761219d8382612568565b6001600160a01b0382166121b45761086f81612605565b826001600160a01b0316826001600160a01b03161461086f5761086f82826126b4565b600d5460ff16610d6d5760405162461bcd60e51b815260206004820152601460248201527314185d5cd8589b194e881b9bdd081c185d5cd95960621b60448201526064016107ce565b60006001600160a01b0384163b1561232257604051630a85bd0160e11b81526001600160a01b0385169063150b7a0290612264903390899088908890600401612f02565b602060405180830381600087803b15801561227e57600080fd5b505af19250505080156122ae575060408051601f3d908101601f191682019092526122ab91810190612f3f565b60015b612308573d8080156122dc576040519150601f19603f3d011682016040523d82523d6000602084013e6122e1565b606091505b5080516123005760405162461bcd60e51b81526004016107ce90612e6b565b805181602001fd5b6001600160e01b031916630a85bd0160e11b14905061193e565b506001949350505050565b6000807f7fffffffffffffffffffffffffffffff5d576e7357a4501ddfe92f46681b20a08311156123645750600090506003612411565b8460ff16601b1415801561237c57508460ff16601c14155b1561238d5750600090506004612411565b6040805160008082526020820180845289905260ff881692820192909252606081018690526080810185905260019060a0016020604051602081039080840390855afa1580156123e1573d6000803e3d6000fd5b5050604051601f1901519150506001600160a01b03811661240a57600060019250925050612411565b9150600090505b94509492505050565b6001600160a01b0382166124705760405162461bcd60e51b815260206004820181905260248201527f4552433732313a206d696e7420746f20746865207a65726f206164647265737360448201526064016107ce565b6000818152600260205260409020546001600160a01b0316156124d55760405162461bcd60e51b815260206004820152601c60248201527f4552433732313a20746f6b656e20616c7265616479206d696e7465640000000060448201526064016107ce565b6124e16000838361211f565b6001600160a01b038216600090815260036020526040812080546001929061250a908490612cb8565b909155505060008181526002602052604080822080546001600160a01b0319166001600160a01b03861690811790915590518392907fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef908290a45050565b6000600161257584610f7a565b61257f9190612e54565b6000838152600760205260409020549091508082146125d2576001600160a01b03841660009081526006602090815260408083208584528252808320548484528184208190558352600790915290208190555b5060009182526007602090815260408084208490556001600160a01b039094168352600681528383209183525290812055565b60085460009061261790600190612e54565b6000838152600960205260408120546008805493945090928490811061263f5761263f612bef565b90600052602060002001549050806008838154811061266057612660612bef565b600091825260208083209091019290925582815260099091526040808220849055858252812055600880548061269857612698612f5c565b6001900381819060005260206000200160009055905550505050565b60006126bf83610f7a565b6001600160a01b039093166000908152600660209081526040808320868452825280832085905593825260079052919091209190915550565b82805461270490612bb4565b90600052602060002090601f016020900481019282612726576000855561276c565b82601f1061273f57805160ff191683800117855561276c565b8280016001018555821561276c579182015b8281111561276c578251825591602001919060010190612751565b5061277892915061277c565b5090565b5b80821115612778576000815560010161277d565b6001600160e01b0319811681146111d857600080fd5b6000602082840312156127b957600080fd5b81356112c181612791565b60005b838110156127df5781810151838201526020016127c7565b8381111561125b5750506000910152565b600081518084526128088160208601602086016127c4565b601f01601f19169290920160200192915050565b6020815260006112c160208301846127f0565b60006020828403121561284157600080fd5b5035919050565b80356001600160a01b038116811461285f57600080fd5b919050565b6000806040838503121561287757600080fd5b61288083612848565b946020939093013593505050565b6000602082840312156128a057600080fd5b6112c182612848565b600080602083850312156128bc57600080fd5b823567ffffffffffffffff808211156128d457600080fd5b818501915085601f8301126128e857600080fd5b8135818111156128f757600080fd5b8660208260051b850101111561290c57600080fd5b60209290920196919550909350505050565b60008060006060848603121561293357600080fd5b61293c84612848565b925061294a60208501612848565b9150604084013590509250925092565b6000806040838503121561296d57600080fd5b50508035926020909101359150565b80151581146111d857600080fd5b6000806040838503121561299d57600080fd5b6129a683612848565b915060208301356129b68161297c565b809150509250929050565b634e487b7160e01b600052604160045260246000fd5b600067ffffffffffffffff808411156129f2576129f26129c1565b604051601f8501601f19908116603f01168101908282118183101715612a1a57612a1a6129c1565b81604052809350858152868686011115612a3357600080fd5b858560208301376000602087830101525050509392505050565b600060208284031215612a5f57600080fd5b813567ffffffffffffffff811115612a7657600080fd5b8201601f81018413612a8757600080fd5b61193e848235602084016129d7565b600082601f830112612aa757600080fd5b6112c1838335602085016129d7565b60008060008060808587031215612acc57600080fd5b612ad585612848565b9350612ae360208601612848565b925060408501359150606085013567ffffffffffffffff811115612b0657600080fd5b612b1287828801612a96565b91505092959194509250565b60008060208385031215612b3157600080fd5b823567ffffffffffffffff80821115612b4957600080fd5b818501915085601f830112612b5d57600080fd5b813581811115612b6c57600080fd5b8660208260061b850101111561290c57600080fd5b60008060408385031215612b9457600080fd5b612b9d83612848565b9150612bab60208401612848565b90509250929050565b600181811c90821680612bc857607f821691505b60208210811415612be957634e487b7160e01b600052602260045260246000fd5b50919050565b634e487b7160e01b600052603260045260246000fd5b60008235605e19833603018112612c1b57600080fd5b9190910192915050565b600060608236031215612c3757600080fd5b6040516060810167ffffffffffffffff8282108183111715612c5b57612c5b6129c1565b81604052612c6885612848565b83526020850135915080821115612c7e57600080fd5b50612c8b36828601612a96565b602083015250604092830135928101929092525090565b634e487b7160e01b600052601160045260246000fd5b60008219821115612ccb57612ccb612ca2565b500190565b600063ffffffff80831681811415612cea57612cea612ca2565b6001019392505050565b6020808252602e908201527f4552433732313a2063616c6c6572206973206e6f7420746f6b656e206f776e6560408201526d1c881b9bdc88185c1c1c9bdd995960921b606082015260800190565b6000816000190483118215151615612d5c57612d5c612ca2565b500290565b634e487b7160e01b600052601260045260246000fd5b600082612d8657612d86612d61565b500490565b6020808252600c908201526b3737ba1037b137a0b236b4b760a11b604082015260600190565b60008351612dc38184602088016127c4565b835190830190612dd78183602088016127c4565b01949350505050565b600060408284031215612df257600080fd5b6040516040810181811067ffffffffffffffff82111715612e1557612e156129c1565b604052612e2183612848565b8152602083013560208201528091505092915050565b600060208284031215612e4957600080fd5b81516112c18161297c565b600082821015612e6657612e66612ca2565b500390565b60208082526032908201527f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560408201527131b2b4bb32b91034b6b83632b6b2b73a32b960711b606082015260800190565b6000600019821415612ed157612ed1612ca2565b5060010190565b600082612ee757612ee7612d61565b500690565b634e487b7160e01b600052602160045260246000fd5b6001600160a01b0385811682528416602082015260408101839052608060608201819052600090612f35908301846127f0565b9695505050505050565b600060208284031215612f5157600080fd5b81516112c181612791565b634e487b7160e01b600052603160045260246000fdfea2646970667358221220ab0e4c6d8cef565e9f008d017cd6654efaa4350407a69f4957b462d3c2b449fd64736f6c63430008090033

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

00000000000000000000000000000000000000000000000000000000000000e0000000000000000000000000000000000000000000000000000000000000012000000000000000000000000085508ce7885b65a57ee070460055f3e4b412051e00000000000000000000000000000000000000000000000000000000000027100000000000000000000000002a0a9e9433ca36df4dfff14b2a5d42003b4e5d2700000000000000000000000000000000000000000000000000000000000001f40000000000000000000000000000000000000000000000000000000000000160000000000000000000000000000000000000000000000000000000000000001c4261627920536861726b3a20436f6c6c656374696f6e204e6f2e203200000000000000000000000000000000000000000000000000000000000000000000000442534e32000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000007697066733a2f2f00000000000000000000000000000000000000000000000000

-----Decoded View---------------
Arg [0] : _tokenName (string): Baby Shark: Collection No. 2
Arg [1] : _tokenSymbol (string): BSN2
Arg [2] : _crsAddress (address): 0x85508Ce7885B65a57Ee070460055f3e4b412051e
Arg [3] : _totalSupply (uint256): 10000
Arg [4] : _creator (address): 0x2A0a9E9433CA36Df4dfFF14b2a5D42003b4e5D27
Arg [5] : _royaltyPercentage (uint16): 500
Arg [6] : _initialBaseURI (string): ipfs://

-----Encoded View---------------
13 Constructor Arguments found :
Arg [0] : 00000000000000000000000000000000000000000000000000000000000000e0
Arg [1] : 0000000000000000000000000000000000000000000000000000000000000120
Arg [2] : 00000000000000000000000085508ce7885b65a57ee070460055f3e4b412051e
Arg [3] : 0000000000000000000000000000000000000000000000000000000000002710
Arg [4] : 0000000000000000000000002a0a9e9433ca36df4dfff14b2a5d42003b4e5d27
Arg [5] : 00000000000000000000000000000000000000000000000000000000000001f4
Arg [6] : 0000000000000000000000000000000000000000000000000000000000000160
Arg [7] : 000000000000000000000000000000000000000000000000000000000000001c
Arg [8] : 4261627920536861726b3a20436f6c6c656374696f6e204e6f2e203200000000
Arg [9] : 0000000000000000000000000000000000000000000000000000000000000004
Arg [10] : 42534e3200000000000000000000000000000000000000000000000000000000
Arg [11] : 0000000000000000000000000000000000000000000000000000000000000007
Arg [12] : 697066733a2f2f00000000000000000000000000000000000000000000000000


Deployed Bytecode Sourcemap

62485:6452:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56262:224;;;;;;:::i;:::-;;:::i;:::-;;;565:14:1;;558:22;540:41;;528:2;513:18;56262:224:0;;;;;;;;62676:32;;;;;;;;-1:-1:-1;;;;;756:32:1;;;738:51;;726:2;711:18;62676:32:0;592:203:1;42996:100:0;;;:::i;:::-;;;;;;;:::i;44509:171::-;;;;;;:::i;:::-;;:::i;44026:417::-;;;;;;:::i;:::-;;:::i;:::-;;16935:53;;16982:6;16935:53;;;;;2319:25:1;;;2307:2;2292:18;16935:53:0;2173:177:1;62750:33:0;;;;;-1:-1:-1;;;62750:33:0;;;;;;56902:113;56990:10;:17;56902:113;;17088:48;;;;;;:::i;:::-;;;;;;;;;;;;;;66381:987;;;;;;:::i;:::-;;:::i;45209:336::-;;;;;;:::i;:::-;;:::i;68589:199::-;;;;;;:::i;:::-;;:::i;:::-;;;;-1:-1:-1;;;;;3985:32:1;;;3967:51;;4049:2;4034:18;;4027:34;;;;3940:18;68589:199:0;3793:274:1;56570:256:0;;;;;;:::i;:::-;;:::i;64311:344::-;;;;;;:::i;:::-;;:::i;62886:41::-;;;;;68867:67;;;:::i;45616:185::-;;;;;;:::i;:::-;;:::i;57092:233::-;;;;;;:::i;:::-;;:::i;65967:175::-;;;;;;:::i;:::-;;:::i;62715:28::-;;;;;;;;-1:-1:-1;;;;;62715:28:0;;;21360:86;21431:7;;;;21360:86;;42707:222;;;;;;:::i;:::-;;:::i;62934:21::-;;;:::i;42438:207::-;;;;;;:::i;:::-;;:::i;15989:103::-;;;:::i;18080:175::-;;;;;;:::i;:::-;;:::i;68796:63::-;;;:::i;66150:81::-;;;:::i;62628:41::-;;;;;;;;5914:6:1;5902:19;;;5884:38;;5872:2;5857:18;62628:41:0;5740:188:1;17442:148:0;;;;;;:::i;:::-;;:::i;15341:87::-;15414:6;;-1:-1:-1;;;;;15414:6:0;15341:87;;43165:104;;;:::i;44752:155::-;;;;;;:::i;:::-;;:::i;18769:195::-;;;;;;:::i;:::-;;:::i;18972:98::-;;;:::i;62962:60::-;;;;;-1:-1:-1;;;;;62962:60:0;;;45872:323;;;;;;:::i;:::-;;:::i;62856:23::-;;;;;-1:-1:-1;;;62856:23:0;;;;;;43340:281;;;;;;:::i;:::-;;:::i;16905:23::-;;;;;-1:-1:-1;;;;;16905:23:0;;;17698:312;;;;;;:::i;:::-;;:::i;16995:39::-;;;;;-1:-1:-1;;;16995:39:0;;;;;;67376:426;;;;;;:::i;:::-;;:::i;68013:345::-;;;;;;:::i;:::-;;:::i;16247:201::-;;;;;;:::i;:::-;;:::i;19180:277::-;;;;;;:::i;:::-;;:::i;62588:33::-;;62620:1;62588:33;;;;;8041:4:1;8029:17;;;8011:36;;7999:2;7984:18;62588:33:0;7869:184:1;56262:224:0;56364:4;-1:-1:-1;;;;;;56388:50:0;;-1:-1:-1;;;56388:50:0;;:90;;;56442:36;56466:11;56442:23;:36::i;:::-;56381:97;56262:224;-1:-1:-1;;56262:224:0:o;42996:100::-;43050:13;43083:5;43076:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;42996:100;:::o;44509:171::-;44585:7;44605:23;44620:7;44605:14;:23::i;:::-;-1:-1:-1;44648:24:0;;;;:15;:24;;;;;;-1:-1:-1;;;;;44648:24:0;;44509:171::o;44026:417::-;44107:13;44123:23;44138:7;44123:14;:23::i;:::-;44107:39;;44171:5;-1:-1:-1;;;;;44165:11:0;:2;-1:-1:-1;;;;;44165:11:0;;;44157:57;;;;-1:-1:-1;;;44157:57:0;;8645:2:1;44157:57:0;;;8627:21:1;8684:2;8664:18;;;8657:30;8723:34;8703:18;;;8696:62;-1:-1:-1;;;8774:18:1;;;8767:31;8815:19;;44157:57:0;;;;;;;;;13972:10;-1:-1:-1;;;;;44249:21:0;;;;:62;;-1:-1:-1;44274:37:0;44291:5;13972:10;68013:345;:::i;44274:37::-;44227:174;;;;-1:-1:-1;;;44227:174:0;;9047:2:1;44227:174:0;;;9029:21:1;9086:2;9066:18;;;9059:30;9125:34;9105:18;;;9098:62;9196:32;9176:18;;;9169:60;9246:19;;44227:174:0;8845:426:1;44227:174:0;44414:21;44423:2;44427:7;44414:8;:21::i;:::-;44096:347;44026:417;;:::o;66381:987::-;20965:19;:17;:19::i;:::-;66486:21:::1;::::0;-1:-1:-1;;;66486:21:0;::::1;;;:29;;66511:4;66486:29;66478:58;;;::::0;-1:-1:-1;;;66478:58:0;;9478:2:1;66478:58:0::1;::::0;::::1;9460:21:1::0;9517:2;9497:18;;;9490:30;-1:-1:-1;;;9536:18:1;;;9529:46;9592:18;;66478:58:0::1;9276:340:1::0;66478:58:0::1;66552:8;66547:814;66564:19;::::0;::::1;::::0;-1:-1:-1;66547:814:0::1;;;66605:36;66644:8;;66653:1;66644:11;;;;;;;;;:::i;:::-;;;;;;;;;;;;:::i;:::-;66605:50;;;:::i;:::-;66745:15;::::0;;::::1;::::0;47767:4;47791:16;;;:7;:16;;;;66605:50;;-1:-1:-1;;;;;;47791:16:0;:30;66729:58:::1;;;::::0;-1:-1:-1;;;66729:58:0;;11065:2:1;66729:58:0::1;::::0;::::1;11047:21:1::0;11104:2;11084:18;;;11077:30;-1:-1:-1;;;11123:18:1;;;11116:42;11175:18;;66729:58:0::1;10863:336:1::0;66729:58:0::1;66810:13:::0;;-1:-1:-1;;;;;66810:27:0::1;66827:10;66810:27;66802:51;;;::::0;-1:-1:-1;;;66802:51:0;;11406:2:1;66802:51:0::1;::::0;::::1;11388:21:1::0;11445:2;11425:18;;;11418:30;-1:-1:-1;;;11464:18:1;;;11457:41;11515:18;;66802:51:0::1;11204:335:1::0;66802:51:0::1;66897:16;66876:13;56990:10:::0;:17;;56902:113;66876:13:::1;:17;::::0;66892:1:::1;66876:17;:::i;:::-;:37;;66868:65;;;::::0;-1:-1:-1;;;66868:65:0;;12011:2:1;66868:65:0::1;::::0;::::1;11993:21:1::0;12050:2;12030:18;;;12023:30;-1:-1:-1;;;12069:18:1;;;12062:45;12124:18;;66868:65:0::1;11809:339:1::0;66868:65:0::1;66996:68;::::0;;::::1;::::0;;::::1;::::0;;67018:15;;::::1;::::0;66996:68;;;67035:13;;-1:-1:-1;;;;;66996:68:0;;::::1;;::::0;;::::1;::::0;;;67058:4:::1;66996:68:::0;;;;;;67114:28;;;;::::1;12377:32:1::0;;;;12438:24;;12538:21;;12516:20;;;12509:51;;;;12602:24;;12598:33;12576:20;;;12569:63;66996:68:0;-1:-1:-1;;12350:18:1;;67114:28:0::1;;;;;;;;;;;;67104:39;;;;;;67079:64;;67158:24;67185:41;67208:7;:17;;;67185:14;:22;;:41;;;;:::i;:::-;67269:13;::::0;67158:68;;-1:-1:-1;;;;;;67249:33:0;;::::1;67269:13;::::0;;::::1;;67249:33;67241:55;;;::::0;-1:-1:-1;;;67241:55:0;;12845:2:1;67241:55:0::1;::::0;::::1;12827:21:1::0;12884:1;12864:18;;;12857:29;-1:-1:-1;;;12902:18:1;;;12895:39;12951:18;;67241:55:0::1;12643:332:1::0;67241:55:0::1;67311:38;67321:10;67333:7;:15;;;67311:9;:38::i;:::-;66590:771;;;;66585:3;;;;;:::i;:::-;;;;66547:814;;45209:336:::0;45404:41;13972:10;45437:7;45404:18;:41::i;:::-;45396:100;;;;-1:-1:-1;;;45396:100:0;;;;;;;:::i;:::-;45509:28;45519:4;45525:2;45529:7;45509:9;:28::i;68589:199::-;68676:16;;68730:7;68773:5;68740:30;;68753:17;68740:30;:10;:30;:::i;:::-;:38;;;;:::i;:::-;68722:58;;;;68589:199;;;;;;:::o;56570:256::-;56667:7;56703:23;56720:5;56703:16;:23::i;:::-;56695:5;:31;56687:87;;;;-1:-1:-1;;;56687:87:0;;14233:2:1;56687:87:0;;;14215:21:1;14272:2;14252:18;;;14245:30;14311:34;14291:18;;;14284:62;-1:-1:-1;;;14362:18:1;;;14355:41;14413:19;;56687:87:0;14031:407:1;56687:87:0;-1:-1:-1;;;;;;56792:19:0;;;;;;;;:12;:19;;;;;;;;:26;;;;;;;;;56570:256::o;64311:344::-;20965:19;:17;:19::i;:::-;19606:30:::1;19625:10;19606:18;:30::i;:::-;19598:64;;;::::0;-1:-1:-1;;;19598:64:0;;14645:2:1;19598:64:0::1;::::0;::::1;14627:21:1::0;14684:2;14664:18;;;14657:30;-1:-1:-1;;;14703:18:1;;;14696:51;14764:18;;19598:64:0::1;14443:345:1::0;19598:64:0::1;-1:-1:-1::0;;;;;64459:28:0;::::2;64451:53;;;::::0;-1:-1:-1;;;64451:53:0;;14995:2:1;64451:53:0::2;::::0;::::2;14977:21:1::0;15034:2;15014:18;;;15007:30;-1:-1:-1;;;15053:18:1;;;15046:42;15105:18;;64451:53:0::2;14793:336:1::0;64451:53:0::2;64515:13;:30:::0;;-1:-1:-1;;;;;;64556:46:0;64515:30:::2;-1:-1:-1::0;;;;;64515:30:0;;::::2;::::0;::::2;-1:-1:-1::0;;;;64556:46:0;;;;;-1:-1:-1;;;64556:46:0;::::2;;;;::::0;;;;64618:29:::2;::::0;64633:13;::::2;;738:51:1::0;;64618:29:0::2;::::0;726:2:1;711:18;64618:29:0::2;;;;;;;64311:344:::0;;:::o;68867:67::-;15227:13;:11;:13::i;:::-;68916:10:::1;:8;:10::i;:::-;68867:67::o:0;45616:185::-;45754:39;45771:4;45777:2;45781:7;45754:39;;;;;;;;;;;;:16;:39::i;57092:233::-;57167:7;57203:30;56990:10;:17;;56902:113;57203:30;57195:5;:38;57187:95;;;;-1:-1:-1;;;57187:95:0;;15336:2:1;57187:95:0;;;15318:21:1;15375:2;15355:18;;;15348:30;15414:34;15394:18;;;15387:62;-1:-1:-1;;;15465:18:1;;;15458:42;15517:19;;57187:95:0;15134:408:1;57187:95:0;57300:10;57311:5;57300:17;;;;;;;;:::i;:::-;;;;;;;;;57293:24;;57092:233;;;:::o;65967:175::-;15227:13;:11;:13::i;:::-;20965:19:::1;:17;:19::i;:::-;66066:11:::2;::::0;-1:-1:-1;;;66066:11:0;::::2;;;:20;66058:44;;;::::0;-1:-1:-1;;;66058:44:0;;15749:2:1;66058:44:0::2;::::0;::::2;15731:21:1::0;15788:2;15768:18;;;15761:30;-1:-1:-1;;;15807:18:1;;;15800:41;15858:18;;66058:44:0::2;15547:335:1::0;66058:44:0::2;66113:21:::0;;::::2;::::0;:7:::2;::::0;:21:::2;::::0;::::2;::::0;::::2;:::i;:::-;;65967:175:::0;:::o;42707:222::-;42779:7;42815:16;;;:7;:16;;;;;;-1:-1:-1;;;;;42815:16:0;42850:19;42842:56;;;;-1:-1:-1;;;42842:56:0;;16089:2:1;42842:56:0;;;16071:21:1;16128:2;16108:18;;;16101:30;-1:-1:-1;;;16147:18:1;;;16140:54;16211:18;;42842:56:0;15887:348:1;62934:21:0;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;42438:207::-;42510:7;-1:-1:-1;;;;;42538:19:0;;42530:73;;;;-1:-1:-1;;;42530:73:0;;16442:2:1;42530:73:0;;;16424:21:1;16481:2;16461:18;;;16454:30;16520:34;16500:18;;;16493:62;-1:-1:-1;;;16571:18:1;;;16564:39;16620:19;;42530:73:0;16240:405:1;42530:73:0;-1:-1:-1;;;;;;42621:16:0;;;;;:9;:16;;;;;;;42438:207::o;15989:103::-;15227:13;:11;:13::i;:::-;16054:30:::1;16081:1;16054:18;:30::i;18080:175::-:0;15414:6;;-1:-1:-1;;;;;15414:6:0;13972:10;17346:23;;:51;;-1:-1:-1;17373:8:0;;-1:-1:-1;;;;;17373:8:0;13972:10;17373:24;17346:51;17338:76;;;;-1:-1:-1;;;17338:76:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;18168:25:0;::::1;;::::0;;;:12:::1;:25;::::0;;;;;;;18161:32;;;18209:38;;17159:51:1;;;17226:18;;;17219:50;;;;18209:38:0::1;::::0;17132:18:1;18209:38:0::1;;;;;;;;18080:175:::0;:::o;68796:63::-;15227:13;:11;:13::i;:::-;68843:8:::1;:6;:8::i;66150:81::-:0;15227:13;:11;:13::i;:::-;66205:11:::1;:18:::0;;-1:-1:-1;;;;66205:18:0::1;-1:-1:-1::0;;;66205:18:0::1;::::0;;66150:81::o;17442:148::-;15227:13;:11;:13::i;:::-;17512:8:::1;:20:::0;;-1:-1:-1;;;;;;17512:20:0::1;-1:-1:-1::0;;;;;17512:20:0;::::1;::::0;;::::1;::::0;;;17548:34:::1;::::0;738:51:1;;;17548:34:0::1;::::0;726:2:1;711:18;17548:34:0::1;592:203:1::0;43165:104:0;43221:13;43254:7;43247:14;;;;;:::i;44752:155::-;44847:52;13972:10;44880:8;44890;44847:18;:52::i;18769:195::-;15414:6;;-1:-1:-1;;;;;15414:6:0;13972:10;17346:23;;:51;;-1:-1:-1;17373:8:0;;-1:-1:-1;;;;;17373:8:0;13972:10;17373:24;17346:51;17338:76;;;;-1:-1:-1;;;17338:76:0;;;;;;;:::i;:::-;18866:20:::1;::::0;-1:-1:-1;;;18866:20:0;::::1;;;:28;;18890:4;18866:28;18858:49;;;::::0;-1:-1:-1;;;18858:49:0;;17482:2:1;18858:49:0::1;::::0;::::1;17464:21:1::0;17521:1;17501:18;;;17494:29;-1:-1:-1;;;17539:18:1;;;17532:38;17587:18;;18858:49:0::1;17280:331:1::0;18858:49:0::1;18918:38;18944:11;18918:25;:38::i;:::-;18769:195:::0;:::o;18972:98::-;15414:6;;-1:-1:-1;;;;;15414:6:0;13972:10;17346:23;;:51;;-1:-1:-1;17373:8:0;;-1:-1:-1;;;;;17373:8:0;13972:10;17373:24;17346:51;17338:76;;;;-1:-1:-1;;;17338:76:0;;;;;;;:::i;:::-;19034:20:::1;:28:::0;;-1:-1:-1;;;;19034:28:0::1;::::0;;18972:98::o;45872:323::-;46046:41;13972:10;46079:7;46046:18;:41::i;:::-;46038:100;;;;-1:-1:-1;;;46038:100:0;;;;;;;:::i;:::-;46149:38;46163:4;46169:2;46173:7;46182:4;46149:13;:38::i;:::-;45872:323;;;;:::o;43340:281::-;43413:13;43439:23;43454:7;43439:14;:23::i;:::-;43475:21;43499:10;:8;:10::i;:::-;43475:34;;43551:1;43533:7;43527:21;:25;:86;;;;;;;;;;;;;;;;;43579:7;43588:18;:7;:16;:18::i;:::-;43562:45;;;;;;;;;:::i;:::-;;;;;;;;;;;;;43527:86;43520:93;43340:281;-1:-1:-1;;;43340:281:0:o;17698:312::-;15414:6;;-1:-1:-1;;;;;15414:6:0;13972:10;17346:23;;:51;;-1:-1:-1;17373:8:0;;-1:-1:-1;;;;;17373:8:0;13972:10;17373:24;17346:51;17338:76;;;;-1:-1:-1;;;17338:76:0;;;;;;;:::i;:::-;-1:-1:-1;;;;;17784:25:0;::::1;17776:52;;;::::0;-1:-1:-1;;;17776:52:0;;18293:2:1;17776:52:0::1;::::0;::::1;18275:21:1::0;18332:2;18312:18;;;18305:30;-1:-1:-1;;;18351:18:1;;;18344:44;18405:18;;17776:52:0::1;18091:338:1::0;17776:52:0::1;-1:-1:-1::0;;;;;17847:25:0;::::1;;::::0;;;:12:::1;:25;::::0;;;;;:30;17839:56:::1;;;::::0;-1:-1:-1;;;17839:56:0;;18636:2:1;17839:56:0::1;::::0;::::1;18618:21:1::0;18675:2;18655:18;;;18648:30;-1:-1:-1;;;18694:18:1;;;18687:43;18747:18;;17839:56:0::1;18434:337:1::0;17839:56:0::1;-1:-1:-1::0;;;;;17906:25:0;::::1;;::::0;;;:12:::1;:25;::::0;;;;;;;;17934:15:::1;17906:43:::0;;17965:37;;17159:51:1;;;17997:4:0::1;17226:18:1::0;;;17219:50;17965:37:0::1;::::0;17132:18:1;17965:37:0::1;16991:284:1::0;67376:426:0;19606:30;19625:10;19606:18;:30::i;:::-;19598:64;;;;-1:-1:-1;;;19598:64:0;;14645:2:1;19598:64:0;;;14627:21:1;14684:2;14664:18;;;14657:30;-1:-1:-1;;;14703:18:1;;;14696:51;14764:18;;19598:64:0;14443:345:1;19598:64:0;67476:8:::1;67471:324;67488:19;::::0;::::1;::::0;-1:-1:-1;67471:324:0::1;;;67529:31;67563:8;;67572:1;67563:11;;;;;;;;;:::i;:::-;;;;;;67529:45;;;;;;;;;;:::i;:::-;;;67597:24;67605:7;:15;;;47767:4:::0;47791:16;;;:7;:16;;;;;;-1:-1:-1;;;;;47791:16:0;:30;;;47702:127;67597:24:::1;:33;67589:58;;;::::0;-1:-1:-1;;;67589:58:0;;11065:2:1;67589:58:0::1;::::0;::::1;11047:21:1::0;11104:2;11084:18;;;11077:30;-1:-1:-1;;;11123:18:1;;;11116:42;11175:18;;67589:58:0::1;10863:336:1::0;67589:58:0::1;67691:16;67670:13;56990:10:::0;:17;;56902:113;67670:13:::1;:17;::::0;67686:1:::1;67670:17;:::i;:::-;:37;;67662:65;;;::::0;-1:-1:-1;;;67662:65:0;;12011:2:1;67662:65:0::1;::::0;::::1;11993:21:1::0;12050:2;12030:18;;;12023:30;-1:-1:-1;;;12069:18:1;;;12062:45;12124:18;;67662:65:0::1;11809:339:1::0;67662:65:0::1;67742:41;67752:7;:13;;;67767:7;:15;;;67742:9;:41::i;:::-;-1:-1:-1::0;67509:3:0;::::1;::::0;::::1;:::i;:::-;;;;67471:324;;68013:345:::0;68507:20;;68124:4;;-1:-1:-1;;;;;68507:20:0;68491:70;;;;-1:-1:-1;;;68491:70:0;;19502:2:1;68491:70:0;;;19484:21:1;19541:2;19521:18;;;19514:30;-1:-1:-1;;;19560:18:1;;;19553:44;19614:18;;68491:70:0;19300:338:1;68491:70:0;68145:20:::1;::::0;:77:::1;::::0;-1:-1:-1;;;68145:77:0;;-1:-1:-1;;;;;19873:15:1;;;68145:77:0::1;::::0;::::1;19855:34:1::0;19925:15;;;19905:18;;;19898:43;68145:20:0;;::::1;::::0;:58:::1;::::0;19790:18:1;;68145:77:0::1;;;;;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;::::0;::::1;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;:85;;68226:4;68145:85;68141:210;;;-1:-1:-1::0;68254:4:0::1;68247:11;;68141:210;-1:-1:-1::0;;;;;;45099:25:0;;;45075:4;45099:25;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;68291:48:::1;;16247:201:::0;15227:13;:11;:13::i;:::-;-1:-1:-1;;;;;16336:22:0;::::1;16328:73;;;::::0;-1:-1:-1;;;16328:73:0;;20404:2:1;16328:73:0::1;::::0;::::1;20386:21:1::0;20443:2;20423:18;;;20416:30;20482:34;20462:18;;;20455:62;-1:-1:-1;;;20533:18:1;;;20526:36;20579:19;;16328:73:0::1;20202:402:1::0;16328:73:0::1;16412:28;16431:8;16412:18;:28::i;19180:277::-:0;-1:-1:-1;;;;;19287:25:0;;19250:4;19287:25;;;:12;:25;;;;;;19327:14;19323:59;;-1:-1:-1;19365:5:0;;19180:277;-1:-1:-1;;19180:277:0:o;19323:59::-;16982:6;19399:27;19417:9;19399:15;:27;:::i;:::-;:50;;19180:277;-1:-1:-1;;;19180:277:0:o;42069:305::-;42171:4;-1:-1:-1;;;;;;42208:40:0;;-1:-1:-1;;;42208:40:0;;:105;;-1:-1:-1;;;;;;;42265:48:0;;-1:-1:-1;;;42265:48:0;42208:105;:158;;;-1:-1:-1;;;;;;;;;;33840:40:0;;;42330:36;33731:157;52484:135;47767:4;47791:16;;;:7;:16;;;;;;-1:-1:-1;;;;;47791:16:0;52558:53;;;;-1:-1:-1;;;52558:53:0;;16089:2:1;52558:53:0;;;16071:21:1;16128:2;16108:18;;;16101:30;-1:-1:-1;;;16147:18:1;;;16140:54;16211:18;;52558:53:0;15887:348:1;51763:174:0;51838:24;;;;:15;:24;;;;;:29;;-1:-1:-1;;;;;;51838:29:0;-1:-1:-1;;;;;51838:29:0;;;;;;;;:24;;51892:23;51838:24;51892:14;:23::i;:::-;-1:-1:-1;;;;;51883:46:0;;;;;;;;;;;51763:174;;:::o;21519:108::-;21431:7;;;;21589:9;21581:38;;;;-1:-1:-1;;;21581:38:0;;20941:2:1;21581:38:0;;;20923:21:1;20980:2;20960:18;;;20953:30;-1:-1:-1;;;20999:18:1;;;20992:46;21055:18;;21581:38:0;20739:340:1;8096:231:0;8174:7;8195:17;8214:18;8236:27;8247:4;8253:9;8236:10;:27::i;:::-;8194:69;;;;8274:18;8286:5;8274:11;:18::i;:::-;-1:-1:-1;8310:9:0;8096:231;-1:-1:-1;;;8096:231:0:o;48602:110::-;48678:26;48688:2;48692:7;48678:26;;;;;;;;;;;;:9;:26::i;47996:264::-;48089:4;48106:13;48122:23;48137:7;48122:14;:23::i;:::-;48106:39;;48175:5;-1:-1:-1;;;;;48164:16:0;:7;-1:-1:-1;;;;;48164:16:0;;:52;;;;48184:32;48201:5;48208:7;48184:16;:32::i;:::-;48164:87;;;;48244:7;-1:-1:-1;;;;;48220:31:0;:20;48232:7;48220:11;:20::i;:::-;-1:-1:-1;;;;;48220:31:0;;48164:87;48156:96;47996:264;-1:-1:-1;;;;47996:264:0:o;51019:625::-;51178:4;-1:-1:-1;;;;;51151:31:0;:23;51166:7;51151:14;:23::i;:::-;-1:-1:-1;;;;;51151:31:0;;51143:81;;;;-1:-1:-1;;;51143:81:0;;21286:2:1;51143:81:0;;;21268:21:1;21325:2;21305:18;;;21298:30;21364:34;21344:18;;;21337:62;-1:-1:-1;;;21415:18:1;;;21408:35;21460:19;;51143:81:0;21084:401:1;51143:81:0;-1:-1:-1;;;;;51243:16:0;;51235:65;;;;-1:-1:-1;;;51235:65:0;;21692:2:1;51235:65:0;;;21674:21:1;21731:2;21711:18;;;21704:30;21770:34;21750:18;;;21743:62;-1:-1:-1;;;21821:18:1;;;21814:34;21865:19;;51235:65:0;21490:400:1;51235:65:0;51313:39;51334:4;51340:2;51344:7;51313:20;:39::i;:::-;51417:29;51434:1;51438:7;51417:8;:29::i;:::-;-1:-1:-1;;;;;51459:15:0;;;;;;:9;:15;;;;;:20;;51478:1;;51459:15;:20;;51478:1;;51459:20;:::i;:::-;;;;-1:-1:-1;;;;;;;51490:13:0;;;;;;:9;:13;;;;;:18;;51507:1;;51490:13;:18;;51507:1;;51490:18;:::i;:::-;;;;-1:-1:-1;;51519:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;51519:21:0;-1:-1:-1;;;;;51519:21:0;;;;;;;;;51558:27;;51519:16;;51558:27;;;;;;;44096:347;44026:417;;:::o;15506:132::-;15414:6;;-1:-1:-1;;;;;15414:6:0;13972:10;15570:23;15562:68;;;;-1:-1:-1;;;15562:68:0;;22097:2:1;15562:68:0;;;22079:21:1;;;22116:18;;;22109:30;22175:34;22155:18;;;22148:62;22227:18;;15562:68:0;21895:356:1;22215:120:0;21224:16;:14;:16::i;:::-;22274:7:::1;:15:::0;;-1:-1:-1;;22274:15:0::1;::::0;;22305:22:::1;13972:10:::0;22314:12:::1;22305:22;::::0;-1:-1:-1;;;;;756:32:1;;;738:51;;726:2;711:18;22305:22:0::1;;;;;;;22215:120::o:0;16608:191::-;16701:6;;;-1:-1:-1;;;;;16718:17:0;;;-1:-1:-1;;;;;;16718:17:0;;;;;;;16751:40;;16701:6;;;16718:17;16701:6;;16751:40;;16682:16;;16751:40;16671:128;16608:191;:::o;21956:118::-;20965:19;:17;:19::i;:::-;22016:7:::1;:14:::0;;-1:-1:-1;;22016:14:0::1;22026:4;22016:14;::::0;;22046:20:::1;22053:12;13972:10:::0;;13892:98;52080:315;52235:8;-1:-1:-1;;;;;52226:17:0;:5;-1:-1:-1;;;;;52226:17:0;;;52218:55;;;;-1:-1:-1;;;52218:55:0;;22458:2:1;52218:55:0;;;22440:21:1;22497:2;22477:18;;;22470:30;22536:27;22516:18;;;22509:55;22581:18;;52218:55:0;22256:349:1;52218:55:0;-1:-1:-1;;;;;52284:25:0;;;;;;;:18;:25;;;;;;;;:35;;;;;;;;;;;;;:46;;-1:-1:-1;;52284:46:0;;;;;;;;;;52346:41;;540::1;;;52346::0;;513:18:1;52346:41:0;;;;;;;52080:315;;;:::o;18409:352::-;15227:13;:11;:13::i;:::-;-1:-1:-1;;;;;18503:25:0;::::1;18495:45;;;::::0;-1:-1:-1;;;18495:45:0;;22812:2:1;18495:45:0::1;::::0;::::1;22794:21:1::0;22851:1;22831:18;;;22824:29;-1:-1:-1;;;22869:18:1;;;22862:37;22916:18;;18495:45:0::1;22610:330:1::0;18495:45:0::1;18699:1;18658:38;16982:6;18658:15;:38;:::i;:::-;:42;;;;:::i;:::-;-1:-1:-1::0;;;;;18630:25:0;::::1;;::::0;;;:12:::1;:25;::::0;;;;;;;;:70;;;;18716:37;;17159:51:1;;;18748:4:0::1;17226:18:1::0;;;17219:50;;;;18716:37:0::1;::::0;17132:18:1;18716:37:0::1;16991:284:1::0;47076:313:0;47232:28;47242:4;47248:2;47252:7;47232:9;:28::i;:::-;47279:47;47302:4;47308:2;47312:7;47321:4;47279:22;:47::i;:::-;47271:110;;;;-1:-1:-1;;;47271:110:0;;;;;;;:::i;65730:100::-;65782:13;65815:7;65808:14;;;;;:::i;2173:723::-;2229:13;2450:10;2446:53;;-1:-1:-1;;2477:10:0;;;;;;;;;;;;-1:-1:-1;;;2477:10:0;;;;;2173:723::o;2446:53::-;2524:5;2509:12;2565:78;2572:9;;2565:78;;2598:8;;;;:::i;:::-;;-1:-1:-1;2621:10:0;;-1:-1:-1;2629:2:0;2621:10;;:::i;:::-;;;2565:78;;;2653:19;2685:6;2675:17;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;2675:17:0;;2653:39;;2703:154;2710:10;;2703:154;;2737:11;2747:1;2737:11;;:::i;:::-;;-1:-1:-1;2806:10:0;2814:2;2806:5;:10;:::i;:::-;2793:24;;:2;:24;:::i;:::-;2780:39;;2763:6;2770;2763:14;;;;;;;;:::i;:::-;;;;:56;-1:-1:-1;;;;;2763:56:0;;;;;;;;-1:-1:-1;2834:11:0;2843:2;2834:11;;:::i;:::-;;;2703:154;;6547:747;6628:7;6637:12;6666:9;:16;6686:2;6666:22;6662:625;;;7010:4;6995:20;;6989:27;7060:4;7045:20;;7039:27;7118:4;7103:20;;7097:27;6705:9;7089:36;7161:25;7172:4;7089:36;6989:27;7039;7161:10;:25::i;:::-;7154:32;;;;;;;;;6662:625;-1:-1:-1;7235:1:0;;-1:-1:-1;7239:35:0;7219:56;;4818:643;4896:20;4887:5;:29;;;;;;;;:::i;:::-;;4883:571;;;4818:643;:::o;4883:571::-;4994:29;4985:5;:38;;;;;;;;:::i;:::-;;4981:473;;;5040:34;;-1:-1:-1;;;5040:34:0;;23955:2:1;5040:34:0;;;23937:21:1;23994:2;23974:18;;;23967:30;24033:26;24013:18;;;24006:54;24077:18;;5040:34:0;23753:348:1;4981:473:0;5105:35;5096:5;:44;;;;;;;;:::i;:::-;;5092:362;;;5157:41;;-1:-1:-1;;;5157:41:0;;24308:2:1;5157:41:0;;;24290:21:1;24347:2;24327:18;;;24320:30;24386:33;24366:18;;;24359:61;24437:18;;5157:41:0;24106:355:1;5092:362:0;5229:30;5220:5;:39;;;;;;;;:::i;:::-;;5216:238;;;5276:44;;-1:-1:-1;;;5276:44:0;;24668:2:1;5276:44:0;;;24650:21:1;24707:2;24687:18;;;24680:30;24746:34;24726:18;;;24719:62;-1:-1:-1;;;24797:18:1;;;24790:32;24839:19;;5276:44:0;24466:398:1;5216:238:0;5351:30;5342:5;:39;;;;;;;;:::i;:::-;;5338:116;;;5398:44;;-1:-1:-1;;;5398:44:0;;25071:2:1;5398:44:0;;;25053:21:1;25110:2;25090:18;;;25083:30;25149:34;25129:18;;;25122:62;-1:-1:-1;;;25200:18:1;;;25193:32;25242:19;;5398:44:0;24869:398:1;48939:319:0;49068:18;49074:2;49078:7;49068:5;:18::i;:::-;49119:53;49150:1;49154:2;49158:7;49167:4;49119:22;:53::i;:::-;49097:153;;;;-1:-1:-1;;;49097:153:0;;;;;;;:::i;57938:589::-;-1:-1:-1;;;;;58144:18:0;;58140:187;;58179:40;58211:7;59354:10;:17;;59327:24;;;;:15;:24;;;;;:44;;;59382:24;;;;;;;;;;;;59250:164;58179:40;58140:187;;;58249:2;-1:-1:-1;;;;;58241:10:0;:4;-1:-1:-1;;;;;58241:10:0;;58237:90;;58268:47;58301:4;58307:7;58268:32;:47::i;:::-;-1:-1:-1;;;;;58341:16:0;;58337:183;;58374:45;58411:7;58374:36;:45::i;58337:183::-;58447:4;-1:-1:-1;;;;;58441:10:0;:2;-1:-1:-1;;;;;58441:10:0;;58437:83;;58468:40;58496:2;58500:7;58468:27;:40::i;21704:108::-;21431:7;;;;21763:41;;;;-1:-1:-1;;;21763:41:0;;25474:2:1;21763:41:0;;;25456:21:1;25513:2;25493:18;;;25486:30;-1:-1:-1;;;25532:18:1;;;25525:50;25592:18;;21763:41:0;25272:344:1;53183:853:0;53337:4;-1:-1:-1;;;;;53358:13:0;;23870:19;:23;53354:675;;53394:71;;-1:-1:-1;;;53394:71:0;;-1:-1:-1;;;;;53394:36:0;;;;;:71;;13972:10;;53445:4;;53451:7;;53460:4;;53394:71;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;53394:71:0;;;;;;;;-1:-1:-1;;53394:71:0;;;;;;;;;;;;:::i;:::-;;;53390:584;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;53635:13:0;;53631:328;;53678:60;;-1:-1:-1;;;53678:60:0;;;;;;;:::i;53631:328::-;53909:6;53903:13;53894:6;53890:2;53886:15;53879:38;53390:584;-1:-1:-1;;;;;;53516:51:0;-1:-1:-1;;;53516:51:0;;-1:-1:-1;53509:58:0;;53354:675;-1:-1:-1;54013:4:0;53183:853;;;;;;:::o;9548:1632::-;9679:7;;10613:66;10600:79;;10596:163;;;-1:-1:-1;10712:1:0;;-1:-1:-1;10716:30:0;10696:51;;10596:163;10773:1;:7;;10778:2;10773:7;;:18;;;;;10784:1;:7;;10789:2;10784:7;;10773:18;10769:102;;;-1:-1:-1;10824:1:0;;-1:-1:-1;10828:30:0;10808:51;;10769:102;10985:24;;;10968:14;10985:24;;;;;;;;;26596:25:1;;;26669:4;26657:17;;26637:18;;;26630:45;;;;26691:18;;;26684:34;;;26734:18;;;26727:34;;;10985:24:0;;26568:19:1;;10985:24:0;;;;;;;;;;;;;;;;;;;;;;;;;;;-1:-1:-1;;10985:24:0;;-1:-1:-1;;10985:24:0;;;-1:-1:-1;;;;;;;11024:20:0;;11020:103;;11077:1;11081:29;11061:50;;;;;;;11020:103;11143:6;-1:-1:-1;11151:20:0;;-1:-1:-1;9548:1632:0;;;;;;;;:::o;49594:439::-;-1:-1:-1;;;;;49674:16:0;;49666:61;;;;-1:-1:-1;;;49666:61:0;;26974:2:1;49666:61:0;;;26956:21:1;;;26993:18;;;26986:30;27052:34;27032:18;;;27025:62;27104:18;;49666:61:0;26772:356:1;49666:61:0;47767:4;47791:16;;;:7;:16;;;;;;-1:-1:-1;;;;;47791:16:0;:30;49738:58;;;;-1:-1:-1;;;49738:58:0;;27335:2:1;49738:58:0;;;27317:21:1;27374:2;27354:18;;;27347:30;27413;27393:18;;;27386:58;27461:18;;49738:58:0;27133:352:1;49738:58:0;49809:45;49838:1;49842:2;49846:7;49809:20;:45::i;:::-;-1:-1:-1;;;;;49867:13:0;;;;;;:9;:13;;;;;:18;;49884:1;;49867:13;:18;;49884:1;;49867:18;:::i;:::-;;;;-1:-1:-1;;49896:16:0;;;;:7;:16;;;;;;:21;;-1:-1:-1;;;;;;49896:21:0;-1:-1:-1;;;;;49896:21:0;;;;;;;;49935:33;;49896:16;;;49935:33;;49896:16;;49935:33;66113:21:::2;65967:175:::0;:::o;60041:988::-;60307:22;60357:1;60332:22;60349:4;60332:16;:22::i;:::-;:26;;;;:::i;:::-;60369:18;60390:26;;;:17;:26;;;;;;60307:51;;-1:-1:-1;60523:28:0;;;60519:328;;-1:-1:-1;;;;;60590:18:0;;60568:19;60590:18;;;:12;:18;;;;;;;;:34;;;;;;;;;60641:30;;;;;;:44;;;60758:30;;:17;:30;;;;;:43;;;60519:328;-1:-1:-1;60943:26:0;;;;:17;:26;;;;;;;;60936:33;;;-1:-1:-1;;;;;60987:18:0;;;;;:12;:18;;;;;:34;;;;;;;60980:41;60041:988::o;61324:1079::-;61602:10;:17;61577:22;;61602:21;;61622:1;;61602:21;:::i;:::-;61634:18;61655:24;;;:15;:24;;;;;;62028:10;:26;;61577:46;;-1:-1:-1;61655:24:0;;61577:46;;62028:26;;;;;;:::i;:::-;;;;;;;;;62006:48;;62092:11;62067:10;62078;62067:22;;;;;;;;:::i;:::-;;;;;;;;;;;;:36;;;;62172:28;;;:15;:28;;;;;;;:41;;;62344:24;;;;;62337:31;62379:10;:16;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;61395:1008;;;61324:1079;:::o;58828:221::-;58913:14;58930:20;58947:2;58930:16;:20::i;:::-;-1:-1:-1;;;;;58961:16:0;;;;;;;:12;:16;;;;;;;;:24;;;;;;;;:34;;;59006:26;;;:17;:26;;;;;;:35;;;;-1:-1:-1;58828:221:0:o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;14:131:1;-1:-1:-1;;;;;;88:32:1;;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;800:258::-;872:1;882:113;896:6;893:1;890:13;882:113;;;972:11;;;966:18;953:11;;;946:39;918:2;911:10;882:113;;;1013:6;1010:1;1007:13;1004:48;;;-1:-1:-1;;1048:1:1;1030:16;;1023:27;800:258::o;1063:::-;1105:3;1143:5;1137:12;1170:6;1165:3;1158:19;1186:63;1242:6;1235:4;1230:3;1226:14;1219:4;1212:5;1208:16;1186:63;:::i;:::-;1303:2;1282:15;-1:-1:-1;;1278:29:1;1269:39;;;;1310:4;1265:50;;1063:258;-1:-1:-1;;1063:258:1:o;1326:220::-;1475:2;1464:9;1457:21;1438:4;1495:45;1536:2;1525:9;1521:18;1513:6;1495:45;:::i;1551:180::-;1610:6;1663:2;1651:9;1642:7;1638:23;1634:32;1631:52;;;1679:1;1676;1669:12;1631:52;-1:-1:-1;1702:23:1;;1551:180;-1:-1:-1;1551:180:1:o;1736:173::-;1804:20;;-1:-1:-1;;;;;1853:31:1;;1843:42;;1833:70;;1899:1;1896;1889:12;1833:70;1736:173;;;:::o;1914:254::-;1982:6;1990;2043:2;2031:9;2022:7;2018:23;2014:32;2011:52;;;2059:1;2056;2049:12;2011:52;2082:29;2101:9;2082:29;:::i;:::-;2072:39;2158:2;2143:18;;;;2130:32;;-1:-1:-1;;;1914:254:1:o;2355:186::-;2414:6;2467:2;2455:9;2446:7;2442:23;2438:32;2435:52;;;2483:1;2480;2473:12;2435:52;2506:29;2525:9;2506:29;:::i;2546:656::-;2673:6;2681;2734:2;2722:9;2713:7;2709:23;2705:32;2702:52;;;2750:1;2747;2740:12;2702:52;2790:9;2777:23;2819:18;2860:2;2852:6;2849:14;2846:34;;;2876:1;2873;2866:12;2846:34;2914:6;2903:9;2899:22;2889:32;;2959:7;2952:4;2948:2;2944:13;2940:27;2930:55;;2981:1;2978;2971:12;2930:55;3021:2;3008:16;3047:2;3039:6;3036:14;3033:34;;;3063:1;3060;3053:12;3033:34;3116:7;3111:2;3101:6;3098:1;3094:14;3090:2;3086:23;3082:32;3079:45;3076:65;;;3137:1;3134;3127:12;3076:65;3168:2;3160:11;;;;;3190:6;;-1:-1:-1;2546:656:1;;-1:-1:-1;;;;2546:656:1:o;3207:328::-;3284:6;3292;3300;3353:2;3341:9;3332:7;3328:23;3324:32;3321:52;;;3369:1;3366;3359:12;3321:52;3392:29;3411:9;3392:29;:::i;:::-;3382:39;;3440:38;3474:2;3463:9;3459:18;3440:38;:::i;:::-;3430:48;;3525:2;3514:9;3510:18;3497:32;3487:42;;3207:328;;;;;:::o;3540:248::-;3608:6;3616;3669:2;3657:9;3648:7;3644:23;3640:32;3637:52;;;3685:1;3682;3675:12;3637:52;-1:-1:-1;;3708:23:1;;;3778:2;3763:18;;;3750:32;;-1:-1:-1;3540:248:1:o;4072:118::-;4158:5;4151:13;4144:21;4137:5;4134:32;4124:60;;4180:1;4177;4170:12;4195:315;4260:6;4268;4321:2;4309:9;4300:7;4296:23;4292:32;4289:52;;;4337:1;4334;4327:12;4289:52;4360:29;4379:9;4360:29;:::i;:::-;4350:39;;4439:2;4428:9;4424:18;4411:32;4452:28;4474:5;4452:28;:::i;:::-;4499:5;4489:15;;;4195:315;;;;;:::o;4515:127::-;4576:10;4571:3;4567:20;4564:1;4557:31;4607:4;4604:1;4597:15;4631:4;4628:1;4621:15;4647:632;4712:5;4742:18;4783:2;4775:6;4772:14;4769:40;;;4789:18;;:::i;:::-;4864:2;4858:9;4832:2;4918:15;;-1:-1:-1;;4914:24:1;;;4940:2;4910:33;4906:42;4894:55;;;4964:18;;;4984:22;;;4961:46;4958:72;;;5010:18;;:::i;:::-;5050:10;5046:2;5039:22;5079:6;5070:15;;5109:6;5101;5094:22;5149:3;5140:6;5135:3;5131:16;5128:25;5125:45;;;5166:1;5163;5156:12;5125:45;5216:6;5211:3;5204:4;5196:6;5192:17;5179:44;5271:1;5264:4;5255:6;5247;5243:19;5239:30;5232:41;;;;4647:632;;;;;:::o;5284:451::-;5353:6;5406:2;5394:9;5385:7;5381:23;5377:32;5374:52;;;5422:1;5419;5412:12;5374:52;5462:9;5449:23;5495:18;5487:6;5484:30;5481:50;;;5527:1;5524;5517:12;5481:50;5550:22;;5603:4;5595:13;;5591:27;-1:-1:-1;5581:55:1;;5632:1;5629;5622:12;5581:55;5655:74;5721:7;5716:2;5703:16;5698:2;5694;5690:11;5655:74;:::i;6180:221::-;6222:5;6275:3;6268:4;6260:6;6256:17;6252:27;6242:55;;6293:1;6290;6283:12;6242:55;6315:80;6391:3;6382:6;6369:20;6362:4;6354:6;6350:17;6315:80;:::i;6406:537::-;6501:6;6509;6517;6525;6578:3;6566:9;6557:7;6553:23;6549:33;6546:53;;;6595:1;6592;6585:12;6546:53;6618:29;6637:9;6618:29;:::i;:::-;6608:39;;6666:38;6700:2;6689:9;6685:18;6666:38;:::i;:::-;6656:48;;6751:2;6740:9;6736:18;6723:32;6713:42;;6806:2;6795:9;6791:18;6778:32;6833:18;6825:6;6822:30;6819:50;;;6865:1;6862;6855:12;6819:50;6888:49;6929:7;6920:6;6909:9;6905:22;6888:49;:::i;:::-;6878:59;;;6406:537;;;;;;;:::o;6948:651::-;7070:6;7078;7131:2;7119:9;7110:7;7106:23;7102:32;7099:52;;;7147:1;7144;7137:12;7099:52;7187:9;7174:23;7216:18;7257:2;7249:6;7246:14;7243:34;;;7273:1;7270;7263:12;7243:34;7311:6;7300:9;7296:22;7286:32;;7356:7;7349:4;7345:2;7341:13;7337:27;7327:55;;7378:1;7375;7368:12;7327:55;7418:2;7405:16;7444:2;7436:6;7433:14;7430:34;;;7460:1;7457;7450:12;7430:34;7513:7;7508:2;7498:6;7495:1;7491:14;7487:2;7483:23;7479:32;7476:45;7473:65;;;7534:1;7531;7524:12;7604:260;7672:6;7680;7733:2;7721:9;7712:7;7708:23;7704:32;7701:52;;;7749:1;7746;7739:12;7701:52;7772:29;7791:9;7772:29;:::i;:::-;7762:39;;7820:38;7854:2;7843:9;7839:18;7820:38;:::i;:::-;7810:48;;7604:260;;;;;:::o;8058:380::-;8137:1;8133:12;;;;8180;;;8201:61;;8255:4;8247:6;8243:17;8233:27;;8201:61;8308:2;8300:6;8297:14;8277:18;8274:38;8271:161;;;8354:10;8349:3;8345:20;8342:1;8335:31;8389:4;8386:1;8379:15;8417:4;8414:1;8407:15;8271:161;;8058:380;;;:::o;9621:127::-;9682:10;9677:3;9673:20;9670:1;9663:31;9713:4;9710:1;9703:15;9737:4;9734:1;9727:15;9753:338;9860:4;9918:11;9905:25;10012:2;10008:7;9997:8;9981:14;9977:29;9973:43;9953:18;9949:68;9939:96;;10031:1;10028;10021:12;9939:96;10052:33;;;;;9753:338;-1:-1:-1;;9753:338:1:o;10096:762::-;10226:9;10285:4;10277:5;10261:14;10257:26;10253:37;10250:57;;;10303:1;10300;10293:12;10250:57;10336:2;10330:9;10378:4;10370:6;10366:17;10402:18;10470:6;10458:10;10455:22;10450:2;10438:10;10435:18;10432:46;10429:72;;;10481:18;;:::i;:::-;10521:10;10517:2;10510:22;10556:25;10575:5;10556:25;:::i;:::-;10548:6;10541:41;10629:2;10622:5;10618:14;10605:28;10591:42;;10656:2;10648:6;10645:14;10642:34;;;10672:1;10669;10662:12;10642:34;;10709:52;10746:14;10737:6;10730:5;10726:18;10709:52;:::i;:::-;10704:2;10692:15;;10685:77;-1:-1:-1;10819:2:1;10808:14;;;10795:28;10778:15;;;10771:53;;;;-1:-1:-1;10696:6:1;10096:762::o;11544:127::-;11605:10;11600:3;11596:20;11593:1;11586:31;11636:4;11633:1;11626:15;11660:4;11657:1;11650:15;11676:128;11716:3;11747:1;11743:6;11740:1;11737:13;11734:39;;;11753:18;;:::i;:::-;-1:-1:-1;11789:9:1;;11676:128::o;12980:201::-;13018:3;13046:10;13091:2;13084:5;13080:14;13118:2;13109:7;13106:15;13103:41;;;13124:18;;:::i;:::-;13173:1;13160:15;;12980:201;-1:-1:-1;;;12980:201:1:o;13186:410::-;13388:2;13370:21;;;13427:2;13407:18;;;13400:30;13466:34;13461:2;13446:18;;13439:62;-1:-1:-1;;;13532:2:1;13517:18;;13510:44;13586:3;13571:19;;13186:410::o;13601:168::-;13641:7;13707:1;13703;13699:6;13695:14;13692:1;13689:21;13684:1;13677:9;13670:17;13666:45;13663:71;;;13714:18;;:::i;:::-;-1:-1:-1;13754:9:1;;13601:168::o;13774:127::-;13835:10;13830:3;13826:20;13823:1;13816:31;13866:4;13863:1;13856:15;13890:4;13887:1;13880:15;13906:120;13946:1;13972;13962:35;;13977:18;;:::i;:::-;-1:-1:-1;14011:9:1;;13906:120::o;16650:336::-;16852:2;16834:21;;;16891:2;16871:18;;;16864:30;-1:-1:-1;;;16925:2:1;16910:18;;16903:42;16977:2;16962:18;;16650:336::o;17616:470::-;17795:3;17833:6;17827:13;17849:53;17895:6;17890:3;17883:4;17875:6;17871:17;17849:53;:::i;:::-;17965:13;;17924:16;;;;17987:57;17965:13;17924:16;18021:4;18009:17;;17987:57;:::i;:::-;18060:20;;17616:470;-1:-1:-1;;;;17616:470:1:o;18776:519::-;18869:6;18922:2;18910:9;18901:7;18897:23;18893:32;18890:52;;;18938:1;18935;18928:12;18890:52;18971:2;18965:9;19013:2;19005:6;19001:15;19082:6;19070:10;19067:22;19046:18;19034:10;19031:34;19028:62;19025:88;;;19093:18;;:::i;:::-;19129:2;19122:22;19168:29;19187:9;19168:29;:::i;:::-;19160:6;19153:45;19259:2;19248:9;19244:18;19231:32;19226:2;19218:6;19214:15;19207:57;19283:6;19273:16;;;18776:519;;;;:::o;19952:245::-;20019:6;20072:2;20060:9;20051:7;20047:23;20043:32;20040:52;;;20088:1;20085;20078:12;20040:52;20120:9;20114:16;20139:28;20161:5;20139:28;:::i;20609:125::-;20649:4;20677:1;20674;20671:8;20668:34;;;20682:18;;:::i;:::-;-1:-1:-1;20719:9:1;;20609:125::o;22945:414::-;23147:2;23129:21;;;23186:2;23166:18;;;23159:30;23225:34;23220:2;23205:18;;23198:62;-1:-1:-1;;;23291:2:1;23276:18;;23269:48;23349:3;23334:19;;22945:414::o;23364:135::-;23403:3;-1:-1:-1;;23424:17:1;;23421:43;;;23444:18;;:::i;:::-;-1:-1:-1;23491:1:1;23480:13;;23364:135::o;23504:112::-;23536:1;23562;23552:35;;23567:18;;:::i;:::-;-1:-1:-1;23601:9:1;;23504:112::o;23621:127::-;23682:10;23677:3;23673:20;23670:1;23663:31;23713:4;23710:1;23703:15;23737:4;23734:1;23727:15;25621:489;-1:-1:-1;;;;;25890:15:1;;;25872:34;;25942:15;;25937:2;25922:18;;25915:43;25989:2;25974:18;;25967:34;;;26037:3;26032:2;26017:18;;26010:31;;;25815:4;;26058:46;;26084:19;;26076:6;26058:46;:::i;:::-;26050:54;25621:489;-1:-1:-1;;;;;;25621:489:1:o;26115:249::-;26184:6;26237:2;26225:9;26216:7;26212:23;26208:32;26205:52;;;26253:1;26250;26243:12;26205:52;26285:9;26279:16;26304:30;26328:5;26304:30;:::i;27490:127::-;27551:10;27546:3;27542:20;27539:1;27532:31;27582:4;27579:1;27572:15;27606:4;27603:1;27596:15

Swarm Source

ipfs://ab0e4c6d8cef565e9f008d017cd6654efaa4350407a69f4957b462d3c2b449fd
Loading...
Loading
Loading...
Loading
[ Download: CSV Export  ]
[ Download: CSV Export  ]

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