ETH Price: $3,038.55 (+0.49%)
Gas: 2 Gwei

Token

Ciphersquares (CSQR)
 

Overview

Max Total Supply

225 CSQR

Holders

89

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Filtered by Token Holder
delso.eth
Balance
1 CSQR
0x641C2fEF13fb417dB01EF955a54904a6400F8b07
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:
Ciphersquares

Compiler Version
v0.8.4+commit.c7e474f2

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, MIT license

Contract Source Code (Solidity Multiple files format)

File 2 of 16: Ciphersquares.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC20.sol";
import "./ERC721.sol";
import "./Ownable.sol";

contract Ciphersquares is ERC721, Ownable {
    using SafeMath for uint256;

    string public CIPHERSQUARES_PROVENANCE = "";

    // Maximum amount of NFTs in existance.
    uint256 public constant MAX_NFT_SUPPLY = 3623;

    uint256 public startingIndexBlock;

    uint256 public startingIndex;

    uint256 public REVEAL_TIMESTAMP;

    address payable private constant _tFirst =
        payable(0x31ED6272EE42493E0D898a595D15e9FB55196F32);
    address payable private constant _tSecond =
        payable(0xBE97e949A89a45F7c141A4d686864dA501cD0664);

    bool public saleIsActive = false;

    constructor() ERC721("Ciphersquares", "CSQR") {}

    function exists(uint256 tokenId) public view returns (bool) {
        return _exists(tokenId);
    }

    function tokensOfOwner(address _owner)
        external
        view
        returns (uint256[] memory)
    {
        uint256 tokenCount = balanceOf(_owner);
        if (tokenCount == 0) {
            // Return an empty array
            return new uint256[](0);
        } else {
            uint256[] memory result = new uint256[](tokenCount);
            for (uint256 index; index < tokenCount; index++) {
                result[index] = tokenOfOwnerByIndex(_owner, index);
            }
            return result;
        }
    }

    function getNFTPrice() public view returns (uint256) {
        uint256 cipherSupply = totalSupply();

        if (cipherSupply >= MAX_NFT_SUPPLY) {
            return 0;
        } else if (cipherSupply >= 3613) {
            return 3.5 ether;
        } else if (cipherSupply >= 3463) {
            return 1.9 ether;
        } else if (cipherSupply >= 3213) {
            return 1.2 ether;
        } else if (cipherSupply >= 2813) {
            return 0.7 ether;
        } else if (cipherSupply >= 2163) {
            return 0.3 ether;
        } else if (cipherSupply >= 1263) {
            return 0.17 ether;
        } else if (cipherSupply >= 663) {
            return 0.09 ether;
        } else if (cipherSupply >= 213) {
            return 0.04 ether;
        } else {
            return 0.01 ether;
        }
    }

    /**
     * @dev Changes the base URI if we want to move things in the future (Callable by owner only)
     */
    function setBaseURI(string memory baseURI) external onlyOwner {
        _setBaseURI(baseURI);
    }

    function setProvenance(string memory _provenance) external onlyOwner {
        CIPHERSQUARES_PROVENANCE = _provenance;
    }

    /**
     * @dev Mints yourself NFTs.
     */
    function mintNFTs(uint256 count) external payable {
        require(saleIsActive, "Sale must be active to mint");
        require(totalSupply() < MAX_NFT_SUPPLY, "Sale has already ended");
        require(count > 0, "numberOfNfts cannot be 0");
        require(count <= 20, "You may not buy more than 20 NFTs at once");
        require(
            SafeMath.add(totalSupply(), count) <= MAX_NFT_SUPPLY,
            "Exceeds MAX_NFT_SUPPLY"
        );
        require(
            SafeMath.mul(getNFTPrice(), count) == msg.value,
            "Ether value sent is not correct"
        );

        for (uint256 i = 0; i < count; i++) {
            uint256 mintIndex = totalSupply();
            if (mintIndex < MAX_NFT_SUPPLY) {
                _safeMint(msg.sender, mintIndex);
            }
        }

        // If we haven't set the starting index and this is either 1) the last saleable token or 2) the first token to be sold after
        // the end of pre-sale, set the starting index block
        if (
            startingIndexBlock == 0 &&
            (totalSupply() == MAX_NFT_SUPPLY ||
                block.timestamp >= REVEAL_TIMESTAMP)
        ) {
            startingIndexBlock = block.number;
        }
    }

    /**
     * @dev send eth to treasuryFirst and treasurySecond.
     */
    function withdraw() external onlyOwner {
        uint256 total = address(this).balance;
        uint256 amount = total.div(4);
        _tFirst.transfer(amount);
        _tSecond.transfer(total.sub(amount));
    }

    function startSale() external onlyOwner {
        saleIsActive = true;
        if (REVEAL_TIMESTAMP == 0) {
            REVEAL_TIMESTAMP = block.timestamp + (86400 * 28);
        }
    }

    function pauseSale() external onlyOwner {
        saleIsActive = false;
    }

    /**
     * Set the reveal timestamp index for the collection
     */
    function setRevealTimestamp(uint256 revealTimeStamp) external onlyOwner {
        REVEAL_TIMESTAMP = revealTimeStamp;
    }

    /**
     * Set the starting index for the collection
     */
    function setStartingIndex() external {
        require(startingIndex == 0, "Starting index is already set");
        require(startingIndexBlock != 0, "Starting index block must be set");

        startingIndex = uint256(blockhash(startingIndexBlock)) % MAX_NFT_SUPPLY;
        // Just a sanity case in the worst case if this function is called late (EVM only stores last 256 block hashes)
        if (block.number.sub(startingIndexBlock) > 255) {
            startingIndex =
                uint256(blockhash(block.number - 1)) %
                MAX_NFT_SUPPLY;
        }
        // Prevent default sequence
        if (startingIndex == 0) {
            startingIndex = startingIndex.add(1);
        }
    }

    /**
     * Set the starting index block for the collection, essentially unblocking
     * setting starting index
     */
    function emergencySetStartingIndexBlock() external onlyOwner {
        require(startingIndex == 0, "Starting index is already set");

        startingIndexBlock = block.number;
    }
}

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

pragma solidity ^0.8.0;

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

        uint256 size;
        // solhint-disable-next-line no-inline-assembly
        assembly { size := extcodesize(account) }
        return size > 0;
    }

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

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

    /**
     * @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);
        require(isContract(target));

        // solhint-disable-next-line avoid-low-level-calls
        (bool success, bytes memory returndata) = target.call{ value: value }(data);
        return _verifyCallResult(success, returndata, errorMessage);
    }

    function _verifyCallResult(bool success, bytes memory returndata, string memory errorMessage) private pure returns(bytes memory) {
        if (success) {
            return returndata;
        } else {
            // Look for revert reason and bubble it up if present
            if (returndata.length > 0) {
                // The easiest way to bubble the revert reason is using memory via assembly

                // solhint-disable-next-line no-inline-assembly
                assembly {
                    let returndata_size := mload(returndata)
                    revert(add(32, returndata), returndata_size)
                }
            } else {
                revert(errorMessage);
            }
        }
    }
}

File 3 of 16: Context.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

    function _msgData() internal view virtual returns (bytes calldata) {
        this; // silence state mutability warning without generating bytecode - see https://github.com/ethereum/solidity/issues/2691
        return msg.data;
    }
}

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

pragma solidity ^0.8.0;

import "./EnumerableSet.sol";

/**
 * @dev Library for managing an enumerable variant of Solidity's
 * https://solidity.readthedocs.io/en/latest/types.html#mapping-types[`mapping`]
 * type.
 *
 * Maps have the following properties:
 *
 * - Entries are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Entries are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableMap for EnumerableMap.UintToAddressMap;
 *
 *     // Declare a set state variable
 *     EnumerableMap.UintToAddressMap private myMap;
 * }
 * ```
 *
 * As of v3.0.0, only maps of type `uint256 -> address` (`UintToAddressMap`) are
 * supported.
 */
library EnumerableMap {
    using EnumerableSet for EnumerableSet.Bytes32Set;

    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Map type with
    // bytes32 keys and values.
    // The Map implementation uses private functions, and user-facing
    // implementations (such as Uint256ToAddressMap) are just wrappers around
    // the underlying Map.
    // This means that we can only create new EnumerableMaps for types that fit
    // in bytes32.

    struct Map {
        // Storage of keys
        EnumerableSet.Bytes32Set _keys;

        mapping (bytes32 => bytes32) _values;
    }

    /**
     * @dev Adds a key-value pair to a map, or updates the value for an existing
     * key. O(1).
     *
     * Returns true if the key was added to the map, that is if it was not
     * already present.
     */
    function _set(Map storage map, bytes32 key, bytes32 value) private returns (bool) {
        map._values[key] = value;
        return map._keys.add(key);
    }

    /**
     * @dev Removes a key-value pair from a map. O(1).
     *
     * Returns true if the key was removed from the map, that is if it was present.
     */
    function _remove(Map storage map, bytes32 key) private returns (bool) {
        delete map._values[key];
        return map._keys.remove(key);
    }

    /**
     * @dev Returns true if the key is in the map. O(1).
     */
    function _contains(Map storage map, bytes32 key) private view returns (bool) {
        return map._keys.contains(key);
    }

    /**
     * @dev Returns the number of key-value pairs in the map. O(1).
     */
    function _length(Map storage map) private view returns (uint256) {
        return map._keys.length();
    }

   /**
    * @dev Returns the key-value pair stored at position `index` in the map. O(1).
    *
    * Note that there are no guarantees on the ordering of entries inside the
    * array, and it may change when more entries are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function _at(Map storage map, uint256 index) private view returns (bytes32, bytes32) {
        bytes32 key = map._keys.at(index);
        return (key, map._values[key]);
    }

    /**
     * @dev Tries to returns the value associated with `key`.  O(1).
     * Does not revert if `key` is not in the map.
     */
    function _tryGet(Map storage map, bytes32 key) private view returns (bool, bytes32) {
        bytes32 value = map._values[key];
        if (value == bytes32(0)) {
            return (_contains(map, key), bytes32(0));
        } else {
            return (true, value);
        }
    }

    /**
     * @dev Returns the value associated with `key`.  O(1).
     *
     * Requirements:
     *
     * - `key` must be in the map.
     */
    function _get(Map storage map, bytes32 key) private view returns (bytes32) {
        bytes32 value = map._values[key];
        require(value != 0 || _contains(map, key), "EnumerableMap: nonexistent key");
        return value;
    }

    /**
     * @dev Same as {_get}, with a custom error message when `key` is not in the map.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {_tryGet}.
     */
    function _get(Map storage map, bytes32 key, string memory errorMessage) private view returns (bytes32) {
        bytes32 value = map._values[key];
        require(value != 0 || _contains(map, key), errorMessage);
        return value;
    }

    // UintToAddressMap

    struct UintToAddressMap {
        Map _inner;
    }

    /**
     * @dev Adds a key-value pair to a map, or updates the value for an existing
     * key. O(1).
     *
     * Returns true if the key was added to the map, that is if it was not
     * already present.
     */
    function set(UintToAddressMap storage map, uint256 key, address value) internal returns (bool) {
        return _set(map._inner, bytes32(key), bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the key was removed from the map, that is if it was present.
     */
    function remove(UintToAddressMap storage map, uint256 key) internal returns (bool) {
        return _remove(map._inner, bytes32(key));
    }

    /**
     * @dev Returns true if the key is in the map. O(1).
     */
    function contains(UintToAddressMap storage map, uint256 key) internal view returns (bool) {
        return _contains(map._inner, bytes32(key));
    }

    /**
     * @dev Returns the number of elements in the map. O(1).
     */
    function length(UintToAddressMap storage map) internal view returns (uint256) {
        return _length(map._inner);
    }

   /**
    * @dev Returns the element stored at position `index` in the set. O(1).
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(UintToAddressMap storage map, uint256 index) internal view returns (uint256, address) {
        (bytes32 key, bytes32 value) = _at(map._inner, index);
        return (uint256(key), address(uint160(uint256(value))));
    }

    /**
     * @dev Tries to returns the value associated with `key`.  O(1).
     * Does not revert if `key` is not in the map.
     *
     * _Available since v3.4._
     */
    function tryGet(UintToAddressMap storage map, uint256 key) internal view returns (bool, address) {
        (bool success, bytes32 value) = _tryGet(map._inner, bytes32(key));
        return (success, address(uint160(uint256(value))));
    }

    /**
     * @dev Returns the value associated with `key`.  O(1).
     *
     * Requirements:
     *
     * - `key` must be in the map.
     */
    function get(UintToAddressMap storage map, uint256 key) internal view returns (address) {
        return address(uint160(uint256(_get(map._inner, bytes32(key)))));
    }

    /**
     * @dev Same as {get}, with a custom error message when `key` is not in the map.
     *
     * CAUTION: This function is deprecated because it requires allocating memory for the error
     * message unnecessarily. For custom revert reasons use {tryGet}.
     */
    function get(UintToAddressMap storage map, uint256 key, string memory errorMessage) internal view returns (address) {
        return address(uint160(uint256(_get(map._inner, bytes32(key), errorMessage))));
    }
}

File 5 of 16: EnumerableSet.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Library for managing
 * https://en.wikipedia.org/wiki/Set_(abstract_data_type)[sets] of primitive
 * types.
 *
 * Sets have the following properties:
 *
 * - Elements are added, removed, and checked for existence in constant time
 * (O(1)).
 * - Elements are enumerated in O(n). No guarantees are made on the ordering.
 *
 * ```
 * contract Example {
 *     // Add the library methods
 *     using EnumerableSet for EnumerableSet.AddressSet;
 *
 *     // Declare a set state variable
 *     EnumerableSet.AddressSet private mySet;
 * }
 * ```
 *
 * As of v3.3.0, sets of type `bytes32` (`Bytes32Set`), `address` (`AddressSet`)
 * and `uint256` (`UintSet`) are supported.
 */
library EnumerableSet {
    // To implement this library for multiple types with as little code
    // repetition as possible, we write it in terms of a generic Set type with
    // bytes32 values.
    // The Set implementation uses private functions, and user-facing
    // implementations (such as AddressSet) are just wrappers around the
    // underlying Set.
    // This means that we can only create new EnumerableSets for types that fit
    // in bytes32.

    struct Set {
        // Storage of set values
        bytes32[] _values;

        // Position of the value in the `values` array, plus 1 because index 0
        // means a value is not in the set.
        mapping (bytes32 => uint256) _indexes;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function _add(Set storage set, bytes32 value) private returns (bool) {
        if (!_contains(set, value)) {
            set._values.push(value);
            // The value is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            set._indexes[value] = set._values.length;
            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function _remove(Set storage set, bytes32 value) private returns (bool) {
        // We read and store the value's index to prevent multiple reads from the same storage slot
        uint256 valueIndex = set._indexes[value];

        if (valueIndex != 0) { // Equivalent to contains(set, value)
            // To delete an element from the _values array in O(1), we swap the element to delete with the last one in
            // the array, and then remove the last element (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = valueIndex - 1;
            uint256 lastIndex = set._values.length - 1;

            // When the value to delete is the last one, the swap operation is unnecessary. However, since this occurs
            // so rarely, we still do the swap anyway to avoid the gas cost of adding an 'if' statement.

            bytes32 lastvalue = set._values[lastIndex];

            // Move the last value to the index where the value to delete is
            set._values[toDeleteIndex] = lastvalue;
            // Update the index for the moved value
            set._indexes[lastvalue] = valueIndex; // Replace lastvalue's index to valueIndex

            // Delete the slot where the moved value was stored
            set._values.pop();

            // Delete the index for the deleted slot
            delete set._indexes[value];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function _contains(Set storage set, bytes32 value) private view returns (bool) {
        return set._indexes[value] != 0;
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function _length(Set storage set) private view returns (uint256) {
        return set._values.length;
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function _at(Set storage set, uint256 index) private view returns (bytes32) {
        require(set._values.length > index, "EnumerableSet: index out of bounds");
        return set._values[index];
    }

    // Bytes32Set

    struct Bytes32Set {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _add(set._inner, value);
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(Bytes32Set storage set, bytes32 value) internal returns (bool) {
        return _remove(set._inner, value);
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(Bytes32Set storage set, bytes32 value) internal view returns (bool) {
        return _contains(set._inner, value);
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(Bytes32Set storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(Bytes32Set storage set, uint256 index) internal view returns (bytes32) {
        return _at(set._inner, index);
    }

    // AddressSet

    struct AddressSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(AddressSet storage set, address value) internal returns (bool) {
        return _add(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(AddressSet storage set, address value) internal returns (bool) {
        return _remove(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(AddressSet storage set, address value) internal view returns (bool) {
        return _contains(set._inner, bytes32(uint256(uint160(value))));
    }

    /**
     * @dev Returns the number of values in the set. O(1).
     */
    function length(AddressSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(AddressSet storage set, uint256 index) internal view returns (address) {
        return address(uint160(uint256(_at(set._inner, index))));
    }


    // UintSet

    struct UintSet {
        Set _inner;
    }

    /**
     * @dev Add a value to a set. O(1).
     *
     * Returns true if the value was added to the set, that is if it was not
     * already present.
     */
    function add(UintSet storage set, uint256 value) internal returns (bool) {
        return _add(set._inner, bytes32(value));
    }

    /**
     * @dev Removes a value from a set. O(1).
     *
     * Returns true if the value was removed from the set, that is if it was
     * present.
     */
    function remove(UintSet storage set, uint256 value) internal returns (bool) {
        return _remove(set._inner, bytes32(value));
    }

    /**
     * @dev Returns true if the value is in the set. O(1).
     */
    function contains(UintSet storage set, uint256 value) internal view returns (bool) {
        return _contains(set._inner, bytes32(value));
    }

    /**
     * @dev Returns the number of values on the set. O(1).
     */
    function length(UintSet storage set) internal view returns (uint256) {
        return _length(set._inner);
    }

   /**
    * @dev Returns the value stored at position `index` in the set. O(1).
    *
    * Note that there are no guarantees on the ordering of values inside the
    * array, and it may change when more values are added or removed.
    *
    * Requirements:
    *
    * - `index` must be strictly less than {length}.
    */
    function at(UintSet storage set, uint256 index) internal view returns (uint256) {
        return uint256(_at(set._inner, index));
    }
}

File 6 of 16: ERC165.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

    /**
     * @dev Mapping of interface ids to whether or not it's supported.
     */
    mapping(bytes4 => bool) private _supportedInterfaces;

    constructor () {
        // Derived contracts need only register support for their own interfaces,
        // we register support for ERC165 itself here
        _registerInterface(_INTERFACE_ID_ERC165);
    }

    /**
     * @dev See {IERC165-supportsInterface}.
     *
     * Time complexity O(1), guaranteed to always use less than 30 000 gas.
     */
    function supportsInterface(bytes4 interfaceId) public view virtual override returns (bool) {
        return _supportedInterfaces[interfaceId];
    }

    /**
     * @dev Registers the contract as an implementer of the interface defined by
     * `interfaceId`. Support of the actual ERC165 interface is automatic and
     * registering its interface id is not required.
     *
     * See {IERC165-supportsInterface}.
     *
     * Requirements:
     *
     * - `interfaceId` cannot be the ERC165 invalid interface (`0xffffffff`).
     */
    function _registerInterface(bytes4 interfaceId) internal virtual {
        require(interfaceId != 0xffffffff, "ERC165: invalid interface id");
        _supportedInterfaces[interfaceId] = true;
    }
}

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

pragma solidity ^0.8.0;

import "./IERC721Receiver.sol";
import "./IERC721Metadata.sol";
import "./IERC721Enumerable.sol";
import "./Address.sol";
import "./Strings.sol";
import "./EnumerableSet.sol";
import "./EnumerableMap.sol";
import "./SafeMath.sol";
import "./Context.sol";
import "./ERC165.sol";

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

    // Equals to `bytes4(keccak256("onERC721Received(address,address,uint256,bytes)"))`
    // which can be also obtained as `IERC721Receiver(0).onERC721Received.selector`
    bytes4 private constant _ERC721_RECEIVED = 0x150b7a02;

    // Mapping from holder address to their (enumerable) set of owned tokens
    mapping (address => EnumerableSet.UintSet) private _holderTokens;

    // Enumerable mapping from token ids to their owners
    EnumerableMap.UintToAddressMap private _tokenOwners;

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

    // Token name
    string private _name;

    // Token symbol
    string private _symbol;

    // Optional mapping for token URIs
    mapping (uint256 => string) private _tokenURIs;

    // Base URI
    string private _baseURI;

    /*
     *     bytes4(keccak256('balanceOf(address)')) == 0x70a08231
     *     bytes4(keccak256('ownerOf(uint256)')) == 0x6352211e
     *     bytes4(keccak256('approve(address,uint256)')) == 0x095ea7b3
     *     bytes4(keccak256('getApproved(uint256)')) == 0x081812fc
     *     bytes4(keccak256('setApprovalForAll(address,bool)')) == 0xa22cb465
     *     bytes4(keccak256('isApprovedForAll(address,address)')) == 0xe985e9c5
     *     bytes4(keccak256('transferFrom(address,address,uint256)')) == 0x23b872dd
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256)')) == 0x42842e0e
     *     bytes4(keccak256('safeTransferFrom(address,address,uint256,bytes)')) == 0xb88d4fde
     *
     *     => 0x70a08231 ^ 0x6352211e ^ 0x095ea7b3 ^ 0x081812fc ^
     *        0xa22cb465 ^ 0xe985e9c5 ^ 0x23b872dd ^ 0x42842e0e ^ 0xb88d4fde == 0x80ac58cd
     */
    bytes4 private constant _INTERFACE_ID_ERC721 = 0x80ac58cd;

    /*
     *     bytes4(keccak256('name()')) == 0x06fdde03
     *     bytes4(keccak256('symbol()')) == 0x95d89b41
     *     bytes4(keccak256('tokenURI(uint256)')) == 0xc87b56dd
     *
     *     => 0x06fdde03 ^ 0x95d89b41 ^ 0xc87b56dd == 0x5b5e139f
     */
    bytes4 private constant _INTERFACE_ID_ERC721_METADATA = 0x5b5e139f;

    /*
     *     bytes4(keccak256('totalSupply()')) == 0x18160ddd
     *     bytes4(keccak256('tokenOfOwnerByIndex(address,uint256)')) == 0x2f745c59
     *     bytes4(keccak256('tokenByIndex(uint256)')) == 0x4f6ccce7
     *
     *     => 0x18160ddd ^ 0x2f745c59 ^ 0x4f6ccce7 == 0x780e9d63
     */
    bytes4 private constant _INTERFACE_ID_ERC721_ENUMERABLE = 0x780e9d63;

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

        // register the supported interfaces to conform to ERC721 via ERC165
        _registerInterface(_INTERFACE_ID_ERC721);
        _registerInterface(_INTERFACE_ID_ERC721_METADATA);
        _registerInterface(_INTERFACE_ID_ERC721_ENUMERABLE);
    }

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

    /**
     * @dev See {IERC721-ownerOf}.
     */
    function ownerOf(uint256 tokenId) public view virtual override returns (address) {
        return _tokenOwners.get(tokenId, "ERC721: owner query for nonexistent token");
    }

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

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

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

        string memory _tokenURI = _tokenURIs[tokenId];
        string memory base = baseURI();

        // If there is no base URI, return the token URI.
        if (bytes(base).length == 0) {
            return _tokenURI;
        }
        // If both are set, concatenate the baseURI and tokenURI (via abi.encodePacked).
        if (bytes(_tokenURI).length > 0) {
            return string(abi.encodePacked(base, _tokenURI));
        }
        // If there is a baseURI but no tokenURI, concatenate the tokenID to the baseURI.
        return string(abi.encodePacked(base, tokenId.toString()));
    }

    /**
    * @dev Returns the base URI set via {_setBaseURI}. This will be
    * automatically added as a prefix in {tokenURI} to each token's URI, or
    * to the token ID if no specific URI is set for that token ID.
    */
    function baseURI() public view virtual returns (string memory) {
        return _baseURI;
    }

    /**
     * @dev See {IERC721Enumerable-tokenOfOwnerByIndex}.
     */
    function tokenOfOwnerByIndex(address owner, uint256 index) public view virtual override returns (uint256) {
        return _holderTokens[owner].at(index);
    }

    /**
     * @dev See {IERC721Enumerable-totalSupply}.
     */
    function totalSupply() public view virtual override returns (uint256) {
        // _tokenOwners are indexed by tokenIds, so .length() returns the number of tokenIds
        return _tokenOwners.length();
    }

    /**
     * @dev See {IERC721Enumerable-tokenByIndex}.
     */
    function tokenByIndex(uint256 index) public view virtual override returns (uint256) {
        (uint256 tokenId, ) = _tokenOwners.at(index);
        return tokenId;
    }

    /**
     * @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 || ERC721.isApprovedForAll(owner, _msgSender()),
            "ERC721: approve caller is not owner nor approved for all"
        );

        _approve(to, tokenId);
    }

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

        return _tokenApprovals[tokenId];
    }

    /**
     * @dev See {IERC721-setApprovalForAll}.
     */
    function setApprovalForAll(address operator, bool approved) public virtual override {
        require(operator != _msgSender(), "ERC721: approve to caller");

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

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

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

        _transfer(from, to, tokenId);
    }

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

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

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

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

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

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

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

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

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

        _holderTokens[to].add(tokenId);

        _tokenOwners.set(tokenId, to);

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

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

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

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

        // Clear metadata (if any)
        if (bytes(_tokenURIs[tokenId]).length != 0) {
            delete _tokenURIs[tokenId];
        }

        _holderTokens[owner].remove(tokenId);

        _tokenOwners.remove(tokenId);

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

    /**
     * @dev Transfers `tokenId` from `from` to `to`.
     *  As opposed to {transferFrom}, this imposes no restrictions on msg.sender.
     *
     * Requirements:
     *
     * - `to` cannot be the zero address.
     * - `tokenId` token must be owned by `from`.
     *
     * Emits a {Transfer} event.
     */
    function _transfer(address from, address to, uint256 tokenId) internal virtual {
        require(ERC721.ownerOf(tokenId) == from, "ERC721: transfer of token that is not own"); // internal 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);

        _holderTokens[from].remove(tokenId);
        _holderTokens[to].add(tokenId);

        _tokenOwners.set(tokenId, to);

        emit Transfer(from, to, tokenId);
    }

    /**
     * @dev Sets `_tokenURI` as the tokenURI of `tokenId`.
     *
     * Requirements:
     *
     * - `tokenId` must exist.
     */
    function _setTokenURI(uint256 tokenId, string memory _tokenURI) internal virtual {
        require(_exists(tokenId), "ERC721Metadata: URI set of nonexistent token");
        _tokenURIs[tokenId] = _tokenURI;
    }

    /**
     * @dev Internal function to set the base URI for all token IDs. It is
     * automatically added as a prefix to the value returned in {tokenURI},
     * or to the token ID if {tokenURI} is empty.
     */
    function _setBaseURI(string memory baseURI_) internal virtual {
        _baseURI = baseURI_;
    }

    /**
     * @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()) {
            return true;
        }
        bytes memory returndata = to.functionCall(abi.encodeWithSelector(
            IERC721Receiver(to).onERC721Received.selector,
            _msgSender(),
            from,
            tokenId,
            _data
        ), "ERC721: transfer to non ERC721Receiver implementer");
        bytes4 retval = abi.decode(returndata, (bytes4));
        return (retval == _ERC721_RECEIVED);
    }

    function _approve(address to, uint256 tokenId) private {
        _tokenApprovals[tokenId] = to;
        emit Approval(ERC721.ownerOf(tokenId), to, tokenId); // internal owner
    }

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

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

pragma solidity ^0.8.0;

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

File 9 of 16: IERC20.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

/**
 * @dev Interface of the ERC20 standard as defined in the EIP.
 */
interface IERC20 {
    function balanceOf(address account) external view returns (uint256);
    function transfer(address recipient, uint256 amount) external returns (bool);
    function transferFrom(address sender, address recipient, uint256 amount) external returns (bool);
}

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

pragma solidity ^0.8.0;

import "./IERC165.sol";

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

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

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

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

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

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

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

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

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

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

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

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

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

pragma solidity ^0.8.0;

import "./IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional enumeration extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Enumerable is IERC721 {

    /**
     * @dev Returns the total amount of tokens stored by the contract.
     */
    function totalSupply() external view returns (uint256);

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

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

File 12 of 16: IERC721Metadata.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

import "./IERC721.sol";

/**
 * @title ERC-721 Non-Fungible Token Standard, optional metadata extension
 * @dev See https://eips.ethereum.org/EIPS/eip-721
 */
interface IERC721Metadata is IERC721 {

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

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

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

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

pragma solidity ^0.8.0;

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

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

pragma solidity ^0.8.0;

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

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () {
        address msgSender = _msgSender();
        _owner = msgSender;
        emit OwnershipTransferred(address(0), msgSender);
    }

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

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

    /**
     * @dev Leaves the contract without owner. It will not be possible to call
     * `onlyOwner` functions anymore. Can only be called by the current owner.
     *
     * NOTE: Renouncing ownership will leave the contract without an owner,
     * thereby removing any functionality that is only available to the owner.
     */
    function renounceOwnership() public virtual onlyOwner {
        emit OwnershipTransferred(_owner, address(0));
        _owner = 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");
        emit OwnershipTransferred(_owner, newOwner);
        _owner = newOwner;
    }
}

File 15 of 16: SafeMath.sol
// SPDX-License-Identifier: MIT

pragma solidity ^0.8.0;

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

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is no longer needed starting with Solidity 0.8. The compiler
 * now has built in overflow checking.
 */
library SafeMath {
    /**
     * @dev Returns the addition of two unsigned integers, reverting on
     * overflow.
     *
     * Counterpart to Solidity's `+` operator.
     *
     * Requirements:
     *
     * - Addition cannot overflow.
     */
    function add(uint256 a, uint256 b) internal pure returns (uint256) {
        return a + b;
    }

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

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

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

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

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

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

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

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

pragma solidity ^0.8.0;

/**
 * @dev String operations.
 */
library Strings {
    /**
     * @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);
    }
}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"CIPHERSQUARES_PROVENANCE","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"MAX_NFT_SUPPLY","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"REVEAL_TIMESTAMP","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"approve","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"}],"name":"balanceOf","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"baseURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"emergencySetStartingIndexBlock","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"exists","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":[],"name":"getNFTPrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"count","type":"uint256"}],"name":"mintNFTs","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[],"name":"name","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"owner","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"ownerOf","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"pauseSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"saleIsActive","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","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":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_provenance","type":"string"}],"name":"setProvenance","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"uint256","name":"revealTimeStamp","type":"uint256"}],"name":"setRevealTimestamp","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"setStartingIndex","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startSale","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startingIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"startingIndexBlock","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"uint256","name":"index","type":"uint256"}],"name":"tokenOfOwnerByIndex","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"tokenURI","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_owner","type":"address"}],"name":"tokensOfOwner","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":"withdraw","outputs":[],"stateMutability":"nonpayable","type":"function"}]

608060405260405180602001604052806000815250600c90805190602001906200002b929190620002ec565b506000601060006101000a81548160ff0219169083151502179055503480156200005457600080fd5b506040518060400160405280600d81526020017f43697068657273717561726573000000000000000000000000000000000000008152506040518060400160405280600481526020017f4353515200000000000000000000000000000000000000000000000000000000815250620000d96301ffc9a760e01b6200020c60201b60201c565b8160079080519060200190620000f1929190620002ec565b5080600890805190602001906200010a929190620002ec565b50620001236380ac58cd60e01b6200020c60201b60201c565b6200013b635b5e139f60e01b6200020c60201b60201c565b6200015363780e9d6360e01b6200020c60201b60201c565b5050600062000167620002e460201b60201c565b905080600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a35062000484565b63ffffffff60e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141562000278576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200026f90620003c3565b60405180910390fd5b6001600080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600033905090565b828054620002fa90620003f6565b90600052602060002090601f0160209004810192826200031e57600085556200036a565b82601f106200033957805160ff19168380011785556200036a565b828001600101855582156200036a579182015b82811115620003695782518255916020019190600101906200034c565b5b5090506200037991906200037d565b5090565b5b80821115620003985760008160009055506001016200037e565b5090565b6000620003ab601c83620003e5565b9150620003b8826200045b565b602082019050919050565b60006020820190508181036000830152620003de816200039c565b9050919050565b600082825260208201905092915050565b600060028204905060018216806200040f57607f821691505b602082108114156200042657620004256200042c565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4552433136353a20696e76616c696420696e7465726661636520696400000000600082015250565b6149ce80620004946000396000f3fe6080604052600436106102255760003560e01c806370a0823111610123578063b88d4fde116100ab578063e98665501161006f578063e9866550146107e8578063eb8d2444146107ff578063f2fde38b1461082a578063fb107a4f14610853578063ffe630b51461087e57610225565b8063b88d4fde146106ef578063c87b56dd14610718578063cb774d4714610755578063e36d649814610780578063e985e9c5146107ab57610225565b80638da5cb5b116100f25780638da5cb5b1461062e57806395d89b4114610659578063a22cb46514610684578063b5077f44146106ad578063b66a0e5d146106d857610225565b806370a0823114610586578063715018a6146105c35780637d17fcbe146105da5780638462151c146105f157610225565b80633b4b1381116101b157806355367ba91161017557806355367ba9146104b357806355f804b3146104ca5780636352211e146104f3578063660ba124146105305780636c0360eb1461055b57610225565b80633b4b1381146103dd5780633ccfd60b146103f957806342842e0e146104105780634f558e79146104395780634f6ccce71461047657610225565b8063095ea7b3116101f8578063095ea7b3146102f857806318160ddd1461032157806318e20a381461034c57806323b872dd146103775780632f745c59146103a057610225565b8063018a2c371461022a57806301ffc9a71461025357806306fdde0314610290578063081812fc146102bb575b600080fd5b34801561023657600080fd5b50610251600480360381019061024c9190613585565b6108a7565b005b34801561025f57600080fd5b5061027a600480360381019061027591906134f2565b61092d565b6040516102879190613b40565b60405180910390f35b34801561029c57600080fd5b506102a5610994565b6040516102b29190613b5b565b60405180910390f35b3480156102c757600080fd5b506102e260048036038101906102dd9190613585565b610a26565b6040516102ef9190613ab7565b60405180910390f35b34801561030457600080fd5b5061031f600480360381019061031a91906134b6565b610aab565b005b34801561032d57600080fd5b50610336610bc3565b6040516103439190613e7d565b60405180910390f35b34801561035857600080fd5b50610361610bd4565b60405161036e9190613e7d565b60405180910390f35b34801561038357600080fd5b5061039e600480360381019061039991906133b0565b610bda565b005b3480156103ac57600080fd5b506103c760048036038101906103c291906134b6565b610c3a565b6040516103d49190613e7d565b60405180910390f35b6103f760048036038101906103f29190613585565b610c95565b005b34801561040557600080fd5b5061040e610ed5565b005b34801561041c57600080fd5b50610437600480360381019061043291906133b0565b61103a565b005b34801561044557600080fd5b50610460600480360381019061045b9190613585565b61105a565b60405161046d9190613b40565b60405180910390f35b34801561048257600080fd5b5061049d60048036038101906104989190613585565b61106c565b6040516104aa9190613e7d565b60405180910390f35b3480156104bf57600080fd5b506104c861108f565b005b3480156104d657600080fd5b506104f160048036038101906104ec9190613544565b611128565b005b3480156104ff57600080fd5b5061051a60048036038101906105159190613585565b6111b0565b6040516105279190613ab7565b60405180910390f35b34801561053c57600080fd5b506105456111e7565b6040516105529190613b5b565b60405180910390f35b34801561056757600080fd5b50610570611275565b60405161057d9190613b5b565b60405180910390f35b34801561059257600080fd5b506105ad60048036038101906105a8919061334b565b611307565b6040516105ba9190613e7d565b60405180910390f35b3480156105cf57600080fd5b506105d86113c6565b005b3480156105e657600080fd5b506105ef611503565b005b3480156105fd57600080fd5b506106186004803603810190610613919061334b565b6115cd565b6040516106259190613b1e565b60405180910390f35b34801561063a57600080fd5b50610643611749565b6040516106509190613ab7565b60405180910390f35b34801561066557600080fd5b5061066e611773565b60405161067b9190613b5b565b60405180910390f35b34801561069057600080fd5b506106ab60048036038101906106a6919061347a565b611805565b005b3480156106b957600080fd5b506106c2611986565b6040516106cf9190613e7d565b60405180910390f35b3480156106e457600080fd5b506106ed61198c565b005b3480156106fb57600080fd5b50610716600480360381019061071191906133ff565b611a46565b005b34801561072457600080fd5b5061073f600480360381019061073a9190613585565b611aa8565b60405161074c9190613b5b565b60405180910390f35b34801561076157600080fd5b5061076a611c1b565b6040516107779190613e7d565b60405180910390f35b34801561078c57600080fd5b50610795611c21565b6040516107a29190613e7d565b60405180910390f35b3480156107b757600080fd5b506107d260048036038101906107cd9190613374565b611c27565b6040516107df9190613b40565b60405180910390f35b3480156107f457600080fd5b506107fd611cbb565b005b34801561080b57600080fd5b50610814611dcc565b6040516108219190613b40565b60405180910390f35b34801561083657600080fd5b50610851600480360381019061084c919061334b565b611ddf565b005b34801561085f57600080fd5b50610868611f8b565b6040516108759190613e7d565b60405180910390f35b34801561088a57600080fd5b506108a560048036038101906108a09190613544565b612088565b005b6108af61211e565b73ffffffffffffffffffffffffffffffffffffffff166108cd611749565b73ffffffffffffffffffffffffffffffffffffffff1614610923576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091a90613d7d565b60405180910390fd5b80600f8190555050565b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b6060600780546109a390614171565b80601f01602080910402602001604051908101604052809291908181526020018280546109cf90614171565b8015610a1c5780601f106109f157610100808354040283529160200191610a1c565b820191906000526020600020905b8154815290600101906020018083116109ff57829003601f168201915b5050505050905090565b6000610a3182612126565b610a70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6790613d5d565b60405180910390fd5b6005600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610ab6826111b0565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610b27576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1e90613ddd565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610b4661211e565b73ffffffffffffffffffffffffffffffffffffffff161480610b755750610b7481610b6f61211e565b611c27565b5b610bb4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bab90613cdd565b60405180910390fd5b610bbe8383612143565b505050565b6000610bcf60026121fc565b905090565b600f5481565b610beb610be561211e565b82612211565b610c2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2190613e5d565b60405180910390fd5b610c358383836122ef565b505050565b6000610c8d82600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061250690919063ffffffff16565b905092915050565b601060009054906101000a900460ff16610ce4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cdb90613c7d565b60405180910390fd5b610e27610cef610bc3565b10610d2f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d2690613dfd565b60405180910390fd5b60008111610d72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6990613e1d565b60405180910390fd5b6014811115610db6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dad90613cfd565b60405180910390fd5b610e27610dca610dc4610bc3565b83612520565b1115610e0b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0290613bfd565b60405180910390fd5b34610e1d610e17611f8b565b83612536565b14610e5d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5490613c5d565b60405180910390fd5b60005b81811015610e9d576000610e72610bc3565b9050610e27811015610e8957610e88338261254c565b5b508080610e95906141d4565b915050610e60565b506000600d54148015610ec55750610e27610eb6610bc3565b1480610ec45750600f544210155b5b15610ed25743600d819055505b50565b610edd61211e565b73ffffffffffffffffffffffffffffffffffffffff16610efb611749565b73ffffffffffffffffffffffffffffffffffffffff1614610f51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f4890613d7d565b60405180910390fd5b60004790506000610f6c60048361256a90919063ffffffff16565b90507331ed6272ee42493e0d898a595d15e9fb55196f3273ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610fc8573d6000803e3d6000fd5b5073be97e949a89a45f7c141a4d686864da501cd066473ffffffffffffffffffffffffffffffffffffffff166108fc61100a838561258090919063ffffffff16565b9081150290604051600060405180830381858888f19350505050158015611035573d6000803e3d6000fd5b505050565b61105583838360405180602001604052806000815250611a46565b505050565b600061106582612126565b9050919050565b60008061108383600261259690919063ffffffff16565b50905080915050919050565b61109761211e565b73ffffffffffffffffffffffffffffffffffffffff166110b5611749565b73ffffffffffffffffffffffffffffffffffffffff161461110b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110290613d7d565b60405180910390fd5b6000601060006101000a81548160ff021916908315150217905550565b61113061211e565b73ffffffffffffffffffffffffffffffffffffffff1661114e611749565b73ffffffffffffffffffffffffffffffffffffffff16146111a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119b90613d7d565b60405180910390fd5b6111ad816125c2565b50565b60006111e0826040518060600160405280602981526020016149706029913960026125dc9092919063ffffffff16565b9050919050565b600c80546111f490614171565b80601f016020809104026020016040519081016040528092919081815260200182805461122090614171565b801561126d5780601f106112425761010080835404028352916020019161126d565b820191906000526020600020905b81548152906001019060200180831161125057829003601f168201915b505050505081565b6060600a805461128490614171565b80601f01602080910402602001604051908101604052809291908181526020018280546112b090614171565b80156112fd5780601f106112d2576101008083540402835291602001916112fd565b820191906000526020600020905b8154815290600101906020018083116112e057829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611378576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161136f90613d1d565b60405180910390fd5b6113bf600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206125fb565b9050919050565b6113ce61211e565b73ffffffffffffffffffffffffffffffffffffffff166113ec611749565b73ffffffffffffffffffffffffffffffffffffffff1614611442576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161143990613d7d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b61150b61211e565b73ffffffffffffffffffffffffffffffffffffffff16611529611749565b73ffffffffffffffffffffffffffffffffffffffff161461157f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161157690613d7d565b60405180910390fd5b6000600e54146115c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115bb90613cbd565b60405180910390fd5b43600d81905550565b606060006115da83611307565b9050600081141561165d57600067ffffffffffffffff811115611626577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156116545781602001602082028036833780820191505090505b50915050611744565b60008167ffffffffffffffff81111561169f577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156116cd5781602001602082028036833780820191505090505b50905060005b8281101561173d576116e58582610c3a565b82828151811061171e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010181815250508080611735906141d4565b9150506116d3565b5080925050505b919050565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606008805461178290614171565b80601f01602080910402602001604051908101604052809291908181526020018280546117ae90614171565b80156117fb5780601f106117d0576101008083540402835291602001916117fb565b820191906000526020600020905b8154815290600101906020018083116117de57829003601f168201915b5050505050905090565b61180d61211e565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561187b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161187290613c3d565b60405180910390fd5b806006600061188861211e565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff1661193561211e565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161197a9190613b40565b60405180910390a35050565b610e2781565b61199461211e565b73ffffffffffffffffffffffffffffffffffffffff166119b2611749565b73ffffffffffffffffffffffffffffffffffffffff1614611a08576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119ff90613d7d565b60405180910390fd5b6001601060006101000a81548160ff0219169083151502179055506000600f541415611a44576224ea0042611a3d9190613fa6565b600f819055505b565b611a57611a5161211e565b83612211565b611a96576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8d90613e5d565b60405180910390fd5b611aa284848484612610565b50505050565b6060611ab382612126565b611af2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ae990613dbd565b60405180910390fd5b6000600960008481526020019081526020016000208054611b1290614171565b80601f0160208091040260200160405190810160405280929190818152602001828054611b3e90614171565b8015611b8b5780601f10611b6057610100808354040283529160200191611b8b565b820191906000526020600020905b815481529060010190602001808311611b6e57829003601f168201915b505050505090506000611b9c611275565b9050600081511415611bb2578192505050611c16565b600082511115611be7578082604051602001611bcf929190613a93565b60405160208183030381529060405292505050611c16565b80611bf18561266c565b604051602001611c02929190613a93565b604051602081830303815290604052925050505b919050565b600e5481565b600d5481565b6000600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000600e5414611d00576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cf790613cbd565b60405180910390fd5b6000600d541415611d46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d3d90613e3d565b60405180910390fd5b610e27600d544060001c611d5a919061421d565b600e8190555060ff611d77600d544361258090919063ffffffff16565b1115611da257610e27600143611d8d9190614087565b4060001c611d9b919061421d565b600e819055505b6000600e541415611dca57611dc36001600e5461252090919063ffffffff16565b600e819055505b565b601060009054906101000a900460ff1681565b611de761211e565b73ffffffffffffffffffffffffffffffffffffffff16611e05611749565b73ffffffffffffffffffffffffffffffffffffffff1614611e5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e5290613d7d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611ecb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ec290613bbd565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080611f96610bc3565b9050610e278110611fab576000915050612085565b610e1d8110611fc5576730927f74c9de0000915050612085565b610d878110611fdf57671a5e27eef13e0000915050612085565b610c8d8110611ff9576710a741a462780000915050612085565b610afd8110612013576709b6e64a8ec60000915050612085565b610873811061202d57670429d069189e0000915050612085565b6104ef81106120475767025bf6196bd10000915050612085565b61029781106120615767013fbe85edc90000915050612085565b60d5811061207957668e1bc9bf040000915050612085565b662386f26fc100009150505b90565b61209061211e565b73ffffffffffffffffffffffffffffffffffffffff166120ae611749565b73ffffffffffffffffffffffffffffffffffffffff1614612104576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120fb90613d7d565b60405180910390fd5b80600c908051906020019061211a92919061316f565b5050565b600033905090565b600061213c82600261281990919063ffffffff16565b9050919050565b816005600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166121b6836111b0565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061220a82600001612833565b9050919050565b600061221c82612126565b61225b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161225290613c9d565b60405180910390fd5b6000612266836111b0565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806122d557508373ffffffffffffffffffffffffffffffffffffffff166122bd84610a26565b73ffffffffffffffffffffffffffffffffffffffff16145b806122e657506122e58185611c27565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661230f826111b0565b73ffffffffffffffffffffffffffffffffffffffff1614612365576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161235c90613d9d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156123d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123cc90613c1d565b60405180910390fd5b6123e0838383612848565b6123eb600082612143565b61243c81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061284d90919063ffffffff16565b5061248e81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061286790919063ffffffff16565b506124a5818360026128819092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b600061251583600001836128b6565b60001c905092915050565b6000818361252e9190613fa6565b905092915050565b60008183612544919061402d565b905092915050565b612566828260405180602001604052806000815250612950565b5050565b600081836125789190613ffc565b905092915050565b6000818361258e9190614087565b905092915050565b6000806000806125a986600001866129ab565b915091508160001c8160001c9350935050509250929050565b80600a90805190602001906125d892919061316f565b5050565b60006125ef846000018460001b846129eb565b60001c90509392505050565b600061260982600001612a6c565b9050919050565b61261b8484846122ef565b61262784848484612a7d565b612666576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161265d90613b9d565b60405180910390fd5b50505050565b606060008214156126b4576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612814565b600082905060005b600082146126e65780806126cf906141d4565b915050600a826126df9190613ffc565b91506126bc565b60008167ffffffffffffffff811115612728577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f19166020018201604052801561275a5781602001600182028036833780820191505090505b5090505b6000851461280d576001826127739190614087565b9150600a85612782919061421d565b603061278e9190613fa6565b60f81b8183815181106127ca577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856128069190613ffc565b945061275e565b8093505050505b919050565b600061282b836000018360001b612be1565b905092915050565b600061284182600001612c01565b9050919050565b505050565b600061285f836000018360001b612c16565b905092915050565b6000612879836000018360001b612d94565b905092915050565b60006128ad846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b612e04565b90509392505050565b600081836000018054905011612901576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128f890613b7d565b60405180910390fd5b82600001828154811061293d577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b61295a8383612e3f565b6129676000848484612a7d565b6129a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161299d90613b9d565b60405180910390fd5b505050565b60008060006129c68486600001612fcd90919063ffffffff16565b9050808560020160008381526020019081526020016000205492509250509250929050565b6000808460020160008581526020019081526020016000205490506000801b81141580612a1e5750612a1d8585612be1565b5b8390612a60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a579190613b5b565b60405180910390fd5b50809150509392505050565b600081600001805490509050919050565b6000612a9e8473ffffffffffffffffffffffffffffffffffffffff16612fe4565b612aab5760019050612bd9565b6000612b7263150b7a0260e01b612ac061211e565b888787604051602401612ad69493929190613ad2565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405180606001604052806032815260200161493e603291398773ffffffffffffffffffffffffffffffffffffffff16612ff79092919063ffffffff16565b9050600081806020019051810190612b8a919061351b565b905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614925050505b949350505050565b6000612bf9828460000161300f90919063ffffffff16565b905092915050565b6000612c0f82600001612a6c565b9050919050565b60008083600101600084815260200190815260200160002054905060008114612d88576000600182612c489190614087565b9050600060018660000180549050612c609190614087565b90506000866000018281548110612ca0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110612cea577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200181905550838760010160008381526020019081526020016000208190555086600001805480612d4c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050612d8e565b60009150505b92915050565b6000612da08383613026565b612df9578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612dfe565b600090505b92915050565b60008184600201600085815260200190815260200160002081905550612e36838560000161304990919063ffffffff16565b90509392505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612eaf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ea690613d3d565b60405180910390fd5b612eb881612126565b15612ef8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612eef90613bdd565b60405180910390fd5b612f0460008383612848565b612f5581600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061286790919063ffffffff16565b50612f6c818360026128819092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b6000612fdc83600001836128b6565b905092915050565b600080823b905060008111915050919050565b60606130068484600085613060565b90509392505050565b600061301e8360000183613026565b905092915050565b600080836001016000848152602001908152602001600020541415905092915050565b60006130588360000183612d94565b905092915050565b60608247101561306f57600080fd5b61307885612fe4565b61308157600080fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516130aa9190613a7c565b60006040518083038185875af1925050503d80600081146130e7576040519150601f19603f3d011682016040523d82523d6000602084013e6130ec565b606091505b50915091506130fc828286613108565b92505050949350505050565b6060831561311857829050613168565b60008351111561312b5782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161315f9190613b5b565b60405180910390fd5b9392505050565b82805461317b90614171565b90600052602060002090601f01602090048101928261319d57600085556131e4565b82601f106131b657805160ff19168380011785556131e4565b828001600101855582156131e4579182015b828111156131e35782518255916020019190600101906131c8565b5b5090506131f191906131f5565b5090565b5b8082111561320e5760008160009055506001016131f6565b5090565b600061322561322084613ebd565b613e98565b90508281526020810184848401111561323d57600080fd5b61324884828561412f565b509392505050565b600061326361325e84613eee565b613e98565b90508281526020810184848401111561327b57600080fd5b61328684828561412f565b509392505050565b60008135905061329d816148e1565b92915050565b6000813590506132b2816148f8565b92915050565b6000813590506132c78161490f565b92915050565b6000815190506132dc8161490f565b92915050565b600082601f8301126132f357600080fd5b8135613303848260208601613212565b91505092915050565b600082601f83011261331d57600080fd5b813561332d848260208601613250565b91505092915050565b60008135905061334581614926565b92915050565b60006020828403121561335d57600080fd5b600061336b8482850161328e565b91505092915050565b6000806040838503121561338757600080fd5b60006133958582860161328e565b92505060206133a68582860161328e565b9150509250929050565b6000806000606084860312156133c557600080fd5b60006133d38682870161328e565b93505060206133e48682870161328e565b92505060406133f586828701613336565b9150509250925092565b6000806000806080858703121561341557600080fd5b60006134238782880161328e565b94505060206134348782880161328e565b935050604061344587828801613336565b925050606085013567ffffffffffffffff81111561346257600080fd5b61346e878288016132e2565b91505092959194509250565b6000806040838503121561348d57600080fd5b600061349b8582860161328e565b92505060206134ac858286016132a3565b9150509250929050565b600080604083850312156134c957600080fd5b60006134d78582860161328e565b92505060206134e885828601613336565b9150509250929050565b60006020828403121561350457600080fd5b6000613512848285016132b8565b91505092915050565b60006020828403121561352d57600080fd5b600061353b848285016132cd565b91505092915050565b60006020828403121561355657600080fd5b600082013567ffffffffffffffff81111561357057600080fd5b61357c8482850161330c565b91505092915050565b60006020828403121561359757600080fd5b60006135a584828501613336565b91505092915050565b60006135ba8383613a5e565b60208301905092915050565b6135cf816140bb565b82525050565b60006135e082613f2f565b6135ea8185613f5d565b93506135f583613f1f565b8060005b8381101561362657815161360d88826135ae565b975061361883613f50565b9250506001810190506135f9565b5085935050505092915050565b61363c816140cd565b82525050565b600061364d82613f3a565b6136578185613f6e565b935061366781856020860161413e565b6136708161430a565b840191505092915050565b600061368682613f3a565b6136908185613f7f565b93506136a081856020860161413e565b80840191505092915050565b60006136b782613f45565b6136c18185613f8a565b93506136d181856020860161413e565b6136da8161430a565b840191505092915050565b60006136f082613f45565b6136fa8185613f9b565b935061370a81856020860161413e565b80840191505092915050565b6000613723602283613f8a565b915061372e8261431b565b604082019050919050565b6000613746603283613f8a565b91506137518261436a565b604082019050919050565b6000613769602683613f8a565b9150613774826143b9565b604082019050919050565b600061378c601c83613f8a565b915061379782614408565b602082019050919050565b60006137af601683613f8a565b91506137ba82614431565b602082019050919050565b60006137d2602483613f8a565b91506137dd8261445a565b604082019050919050565b60006137f5601983613f8a565b9150613800826144a9565b602082019050919050565b6000613818601f83613f8a565b9150613823826144d2565b602082019050919050565b600061383b601b83613f8a565b9150613846826144fb565b602082019050919050565b600061385e602c83613f8a565b915061386982614524565b604082019050919050565b6000613881601d83613f8a565b915061388c82614573565b602082019050919050565b60006138a4603883613f8a565b91506138af8261459c565b604082019050919050565b60006138c7602983613f8a565b91506138d2826145eb565b604082019050919050565b60006138ea602a83613f8a565b91506138f58261463a565b604082019050919050565b600061390d602083613f8a565b915061391882614689565b602082019050919050565b6000613930602c83613f8a565b915061393b826146b2565b604082019050919050565b6000613953602083613f8a565b915061395e82614701565b602082019050919050565b6000613976602983613f8a565b91506139818261472a565b604082019050919050565b6000613999602f83613f8a565b91506139a482614779565b604082019050919050565b60006139bc602183613f8a565b91506139c7826147c8565b604082019050919050565b60006139df601683613f8a565b91506139ea82614817565b602082019050919050565b6000613a02601883613f8a565b9150613a0d82614840565b602082019050919050565b6000613a25602083613f8a565b9150613a3082614869565b602082019050919050565b6000613a48603183613f8a565b9150613a5382614892565b604082019050919050565b613a6781614125565b82525050565b613a7681614125565b82525050565b6000613a88828461367b565b915081905092915050565b6000613a9f82856136e5565b9150613aab82846136e5565b91508190509392505050565b6000602082019050613acc60008301846135c6565b92915050565b6000608082019050613ae760008301876135c6565b613af460208301866135c6565b613b016040830185613a6d565b8181036060830152613b138184613642565b905095945050505050565b60006020820190508181036000830152613b3881846135d5565b905092915050565b6000602082019050613b556000830184613633565b92915050565b60006020820190508181036000830152613b7581846136ac565b905092915050565b60006020820190508181036000830152613b9681613716565b9050919050565b60006020820190508181036000830152613bb681613739565b9050919050565b60006020820190508181036000830152613bd68161375c565b9050919050565b60006020820190508181036000830152613bf68161377f565b9050919050565b60006020820190508181036000830152613c16816137a2565b9050919050565b60006020820190508181036000830152613c36816137c5565b9050919050565b60006020820190508181036000830152613c56816137e8565b9050919050565b60006020820190508181036000830152613c768161380b565b9050919050565b60006020820190508181036000830152613c968161382e565b9050919050565b60006020820190508181036000830152613cb681613851565b9050919050565b60006020820190508181036000830152613cd681613874565b9050919050565b60006020820190508181036000830152613cf681613897565b9050919050565b60006020820190508181036000830152613d16816138ba565b9050919050565b60006020820190508181036000830152613d36816138dd565b9050919050565b60006020820190508181036000830152613d5681613900565b9050919050565b60006020820190508181036000830152613d7681613923565b9050919050565b60006020820190508181036000830152613d9681613946565b9050919050565b60006020820190508181036000830152613db681613969565b9050919050565b60006020820190508181036000830152613dd68161398c565b9050919050565b60006020820190508181036000830152613df6816139af565b9050919050565b60006020820190508181036000830152613e16816139d2565b9050919050565b60006020820190508181036000830152613e36816139f5565b9050919050565b60006020820190508181036000830152613e5681613a18565b9050919050565b60006020820190508181036000830152613e7681613a3b565b9050919050565b6000602082019050613e926000830184613a6d565b92915050565b6000613ea2613eb3565b9050613eae82826141a3565b919050565b6000604051905090565b600067ffffffffffffffff821115613ed857613ed76142db565b5b613ee18261430a565b9050602081019050919050565b600067ffffffffffffffff821115613f0957613f086142db565b5b613f128261430a565b9050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000613fb182614125565b9150613fbc83614125565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613ff157613ff061424e565b5b828201905092915050565b600061400782614125565b915061401283614125565b9250826140225761402161427d565b5b828204905092915050565b600061403882614125565b915061404383614125565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561407c5761407b61424e565b5b828202905092915050565b600061409282614125565b915061409d83614125565b9250828210156140b0576140af61424e565b5b828203905092915050565b60006140c682614105565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b8381101561415c578082015181840152602081019050614141565b8381111561416b576000848401525b50505050565b6000600282049050600182168061418957607f821691505b6020821081141561419d5761419c6142ac565b5b50919050565b6141ac8261430a565b810181811067ffffffffffffffff821117156141cb576141ca6142db565b5b80604052505050565b60006141df82614125565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156142125761421161424e565b5b600182019050919050565b600061422882614125565b915061423383614125565b9250826142435761424261427d565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60008201527f6473000000000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f45786365656473204d41585f4e46545f535550504c5900000000000000000000600082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f45746865722076616c75652073656e74206973206e6f7420636f727265637400600082015250565b7f53616c65206d7573742062652061637469766520746f206d696e740000000000600082015250565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f5374617274696e6720696e64657820697320616c726561647920736574000000600082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b7f596f75206d6179206e6f7420627579206d6f7265207468616e203230204e465460008201527f73206174206f6e63650000000000000000000000000000000000000000000000602082015250565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008201527f73206e6f74206f776e0000000000000000000000000000000000000000000000602082015250565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f53616c652068617320616c726561647920656e64656400000000000000000000600082015250565b7f6e756d6265724f664e6674732063616e6e6f7420626520300000000000000000600082015250565b7f5374617274696e6720696e64657820626c6f636b206d75737420626520736574600082015250565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b6148ea816140bb565b81146148f557600080fd5b50565b614901816140cd565b811461490c57600080fd5b50565b614918816140d9565b811461492357600080fd5b50565b61492f81614125565b811461493a57600080fd5b5056fe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea2646970667358221220062f15ad73324cc34744ab1c4c010ae0fb3ebdbb79ea5b51dd990e81bb0e741864736f6c63430008040033

Deployed Bytecode

0x6080604052600436106102255760003560e01c806370a0823111610123578063b88d4fde116100ab578063e98665501161006f578063e9866550146107e8578063eb8d2444146107ff578063f2fde38b1461082a578063fb107a4f14610853578063ffe630b51461087e57610225565b8063b88d4fde146106ef578063c87b56dd14610718578063cb774d4714610755578063e36d649814610780578063e985e9c5146107ab57610225565b80638da5cb5b116100f25780638da5cb5b1461062e57806395d89b4114610659578063a22cb46514610684578063b5077f44146106ad578063b66a0e5d146106d857610225565b806370a0823114610586578063715018a6146105c35780637d17fcbe146105da5780638462151c146105f157610225565b80633b4b1381116101b157806355367ba91161017557806355367ba9146104b357806355f804b3146104ca5780636352211e146104f3578063660ba124146105305780636c0360eb1461055b57610225565b80633b4b1381146103dd5780633ccfd60b146103f957806342842e0e146104105780634f558e79146104395780634f6ccce71461047657610225565b8063095ea7b3116101f8578063095ea7b3146102f857806318160ddd1461032157806318e20a381461034c57806323b872dd146103775780632f745c59146103a057610225565b8063018a2c371461022a57806301ffc9a71461025357806306fdde0314610290578063081812fc146102bb575b600080fd5b34801561023657600080fd5b50610251600480360381019061024c9190613585565b6108a7565b005b34801561025f57600080fd5b5061027a600480360381019061027591906134f2565b61092d565b6040516102879190613b40565b60405180910390f35b34801561029c57600080fd5b506102a5610994565b6040516102b29190613b5b565b60405180910390f35b3480156102c757600080fd5b506102e260048036038101906102dd9190613585565b610a26565b6040516102ef9190613ab7565b60405180910390f35b34801561030457600080fd5b5061031f600480360381019061031a91906134b6565b610aab565b005b34801561032d57600080fd5b50610336610bc3565b6040516103439190613e7d565b60405180910390f35b34801561035857600080fd5b50610361610bd4565b60405161036e9190613e7d565b60405180910390f35b34801561038357600080fd5b5061039e600480360381019061039991906133b0565b610bda565b005b3480156103ac57600080fd5b506103c760048036038101906103c291906134b6565b610c3a565b6040516103d49190613e7d565b60405180910390f35b6103f760048036038101906103f29190613585565b610c95565b005b34801561040557600080fd5b5061040e610ed5565b005b34801561041c57600080fd5b50610437600480360381019061043291906133b0565b61103a565b005b34801561044557600080fd5b50610460600480360381019061045b9190613585565b61105a565b60405161046d9190613b40565b60405180910390f35b34801561048257600080fd5b5061049d60048036038101906104989190613585565b61106c565b6040516104aa9190613e7d565b60405180910390f35b3480156104bf57600080fd5b506104c861108f565b005b3480156104d657600080fd5b506104f160048036038101906104ec9190613544565b611128565b005b3480156104ff57600080fd5b5061051a60048036038101906105159190613585565b6111b0565b6040516105279190613ab7565b60405180910390f35b34801561053c57600080fd5b506105456111e7565b6040516105529190613b5b565b60405180910390f35b34801561056757600080fd5b50610570611275565b60405161057d9190613b5b565b60405180910390f35b34801561059257600080fd5b506105ad60048036038101906105a8919061334b565b611307565b6040516105ba9190613e7d565b60405180910390f35b3480156105cf57600080fd5b506105d86113c6565b005b3480156105e657600080fd5b506105ef611503565b005b3480156105fd57600080fd5b506106186004803603810190610613919061334b565b6115cd565b6040516106259190613b1e565b60405180910390f35b34801561063a57600080fd5b50610643611749565b6040516106509190613ab7565b60405180910390f35b34801561066557600080fd5b5061066e611773565b60405161067b9190613b5b565b60405180910390f35b34801561069057600080fd5b506106ab60048036038101906106a6919061347a565b611805565b005b3480156106b957600080fd5b506106c2611986565b6040516106cf9190613e7d565b60405180910390f35b3480156106e457600080fd5b506106ed61198c565b005b3480156106fb57600080fd5b50610716600480360381019061071191906133ff565b611a46565b005b34801561072457600080fd5b5061073f600480360381019061073a9190613585565b611aa8565b60405161074c9190613b5b565b60405180910390f35b34801561076157600080fd5b5061076a611c1b565b6040516107779190613e7d565b60405180910390f35b34801561078c57600080fd5b50610795611c21565b6040516107a29190613e7d565b60405180910390f35b3480156107b757600080fd5b506107d260048036038101906107cd9190613374565b611c27565b6040516107df9190613b40565b60405180910390f35b3480156107f457600080fd5b506107fd611cbb565b005b34801561080b57600080fd5b50610814611dcc565b6040516108219190613b40565b60405180910390f35b34801561083657600080fd5b50610851600480360381019061084c919061334b565b611ddf565b005b34801561085f57600080fd5b50610868611f8b565b6040516108759190613e7d565b60405180910390f35b34801561088a57600080fd5b506108a560048036038101906108a09190613544565b612088565b005b6108af61211e565b73ffffffffffffffffffffffffffffffffffffffff166108cd611749565b73ffffffffffffffffffffffffffffffffffffffff1614610923576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161091a90613d7d565b60405180910390fd5b80600f8190555050565b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b6060600780546109a390614171565b80601f01602080910402602001604051908101604052809291908181526020018280546109cf90614171565b8015610a1c5780601f106109f157610100808354040283529160200191610a1c565b820191906000526020600020905b8154815290600101906020018083116109ff57829003601f168201915b5050505050905090565b6000610a3182612126565b610a70576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a6790613d5d565b60405180910390fd5b6005600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b6000610ab6826111b0565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff161415610b27576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b1e90613ddd565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16610b4661211e565b73ffffffffffffffffffffffffffffffffffffffff161480610b755750610b7481610b6f61211e565b611c27565b5b610bb4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bab90613cdd565b60405180910390fd5b610bbe8383612143565b505050565b6000610bcf60026121fc565b905090565b600f5481565b610beb610be561211e565b82612211565b610c2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610c2190613e5d565b60405180910390fd5b610c358383836122ef565b505050565b6000610c8d82600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061250690919063ffffffff16565b905092915050565b601060009054906101000a900460ff16610ce4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610cdb90613c7d565b60405180910390fd5b610e27610cef610bc3565b10610d2f576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d2690613dfd565b60405180910390fd5b60008111610d72576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d6990613e1d565b60405180910390fd5b6014811115610db6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dad90613cfd565b60405180910390fd5b610e27610dca610dc4610bc3565b83612520565b1115610e0b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e0290613bfd565b60405180910390fd5b34610e1d610e17611f8b565b83612536565b14610e5d576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610e5490613c5d565b60405180910390fd5b60005b81811015610e9d576000610e72610bc3565b9050610e27811015610e8957610e88338261254c565b5b508080610e95906141d4565b915050610e60565b506000600d54148015610ec55750610e27610eb6610bc3565b1480610ec45750600f544210155b5b15610ed25743600d819055505b50565b610edd61211e565b73ffffffffffffffffffffffffffffffffffffffff16610efb611749565b73ffffffffffffffffffffffffffffffffffffffff1614610f51576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f4890613d7d565b60405180910390fd5b60004790506000610f6c60048361256a90919063ffffffff16565b90507331ed6272ee42493e0d898a595d15e9fb55196f3273ffffffffffffffffffffffffffffffffffffffff166108fc829081150290604051600060405180830381858888f19350505050158015610fc8573d6000803e3d6000fd5b5073be97e949a89a45f7c141a4d686864da501cd066473ffffffffffffffffffffffffffffffffffffffff166108fc61100a838561258090919063ffffffff16565b9081150290604051600060405180830381858888f19350505050158015611035573d6000803e3d6000fd5b505050565b61105583838360405180602001604052806000815250611a46565b505050565b600061106582612126565b9050919050565b60008061108383600261259690919063ffffffff16565b50905080915050919050565b61109761211e565b73ffffffffffffffffffffffffffffffffffffffff166110b5611749565b73ffffffffffffffffffffffffffffffffffffffff161461110b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161110290613d7d565b60405180910390fd5b6000601060006101000a81548160ff021916908315150217905550565b61113061211e565b73ffffffffffffffffffffffffffffffffffffffff1661114e611749565b73ffffffffffffffffffffffffffffffffffffffff16146111a4576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161119b90613d7d565b60405180910390fd5b6111ad816125c2565b50565b60006111e0826040518060600160405280602981526020016149706029913960026125dc9092919063ffffffff16565b9050919050565b600c80546111f490614171565b80601f016020809104026020016040519081016040528092919081815260200182805461122090614171565b801561126d5780601f106112425761010080835404028352916020019161126d565b820191906000526020600020905b81548152906001019060200180831161125057829003601f168201915b505050505081565b6060600a805461128490614171565b80601f01602080910402602001604051908101604052809291908181526020018280546112b090614171565b80156112fd5780601f106112d2576101008083540402835291602001916112fd565b820191906000526020600020905b8154815290600101906020018083116112e057829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611378576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161136f90613d1d565b60405180910390fd5b6113bf600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206125fb565b9050919050565b6113ce61211e565b73ffffffffffffffffffffffffffffffffffffffff166113ec611749565b73ffffffffffffffffffffffffffffffffffffffff1614611442576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161143990613d7d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b61150b61211e565b73ffffffffffffffffffffffffffffffffffffffff16611529611749565b73ffffffffffffffffffffffffffffffffffffffff161461157f576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161157690613d7d565b60405180910390fd5b6000600e54146115c4576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115bb90613cbd565b60405180910390fd5b43600d81905550565b606060006115da83611307565b9050600081141561165d57600067ffffffffffffffff811115611626577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156116545781602001602082028036833780820191505090505b50915050611744565b60008167ffffffffffffffff81111561169f577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156116cd5781602001602082028036833780820191505090505b50905060005b8281101561173d576116e58582610c3a565b82828151811061171e577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b6020026020010181815250508080611735906141d4565b9150506116d3565b5080925050505b919050565b6000600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606008805461178290614171565b80601f01602080910402602001604051908101604052809291908181526020018280546117ae90614171565b80156117fb5780601f106117d0576101008083540402835291602001916117fb565b820191906000526020600020905b8154815290600101906020018083116117de57829003601f168201915b5050505050905090565b61180d61211e565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561187b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161187290613c3d565b60405180910390fd5b806006600061188861211e565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff1661193561211e565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c318360405161197a9190613b40565b60405180910390a35050565b610e2781565b61199461211e565b73ffffffffffffffffffffffffffffffffffffffff166119b2611749565b73ffffffffffffffffffffffffffffffffffffffff1614611a08576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016119ff90613d7d565b60405180910390fd5b6001601060006101000a81548160ff0219169083151502179055506000600f541415611a44576224ea0042611a3d9190613fa6565b600f819055505b565b611a57611a5161211e565b83612211565b611a96576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611a8d90613e5d565b60405180910390fd5b611aa284848484612610565b50505050565b6060611ab382612126565b611af2576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ae990613dbd565b60405180910390fd5b6000600960008481526020019081526020016000208054611b1290614171565b80601f0160208091040260200160405190810160405280929190818152602001828054611b3e90614171565b8015611b8b5780601f10611b6057610100808354040283529160200191611b8b565b820191906000526020600020905b815481529060010190602001808311611b6e57829003601f168201915b505050505090506000611b9c611275565b9050600081511415611bb2578192505050611c16565b600082511115611be7578082604051602001611bcf929190613a93565b60405160208183030381529060405292505050611c16565b80611bf18561266c565b604051602001611c02929190613a93565b604051602081830303815290604052925050505b919050565b600e5481565b600d5481565b6000600660008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b6000600e5414611d00576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cf790613cbd565b60405180910390fd5b6000600d541415611d46576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d3d90613e3d565b60405180910390fd5b610e27600d544060001c611d5a919061421d565b600e8190555060ff611d77600d544361258090919063ffffffff16565b1115611da257610e27600143611d8d9190614087565b4060001c611d9b919061421d565b600e819055505b6000600e541415611dca57611dc36001600e5461252090919063ffffffff16565b600e819055505b565b601060009054906101000a900460ff1681565b611de761211e565b73ffffffffffffffffffffffffffffffffffffffff16611e05611749565b73ffffffffffffffffffffffffffffffffffffffff1614611e5b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611e5290613d7d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611ecb576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611ec290613bbd565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600b60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600b60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b600080611f96610bc3565b9050610e278110611fab576000915050612085565b610e1d8110611fc5576730927f74c9de0000915050612085565b610d878110611fdf57671a5e27eef13e0000915050612085565b610c8d8110611ff9576710a741a462780000915050612085565b610afd8110612013576709b6e64a8ec60000915050612085565b610873811061202d57670429d069189e0000915050612085565b6104ef81106120475767025bf6196bd10000915050612085565b61029781106120615767013fbe85edc90000915050612085565b60d5811061207957668e1bc9bf040000915050612085565b662386f26fc100009150505b90565b61209061211e565b73ffffffffffffffffffffffffffffffffffffffff166120ae611749565b73ffffffffffffffffffffffffffffffffffffffff1614612104576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016120fb90613d7d565b60405180910390fd5b80600c908051906020019061211a92919061316f565b5050565b600033905090565b600061213c82600261281990919063ffffffff16565b9050919050565b816005600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff166121b6836111b0565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b600061220a82600001612833565b9050919050565b600061221c82612126565b61225b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161225290613c9d565b60405180910390fd5b6000612266836111b0565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff1614806122d557508373ffffffffffffffffffffffffffffffffffffffff166122bd84610a26565b73ffffffffffffffffffffffffffffffffffffffff16145b806122e657506122e58185611c27565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff1661230f826111b0565b73ffffffffffffffffffffffffffffffffffffffff1614612365576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161235c90613d9d565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff1614156123d5576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016123cc90613c1d565b60405180910390fd5b6123e0838383612848565b6123eb600082612143565b61243c81600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061284d90919063ffffffff16565b5061248e81600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061286790919063ffffffff16565b506124a5818360026128819092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b600061251583600001836128b6565b60001c905092915050565b6000818361252e9190613fa6565b905092915050565b60008183612544919061402d565b905092915050565b612566828260405180602001604052806000815250612950565b5050565b600081836125789190613ffc565b905092915050565b6000818361258e9190614087565b905092915050565b6000806000806125a986600001866129ab565b915091508160001c8160001c9350935050509250929050565b80600a90805190602001906125d892919061316f565b5050565b60006125ef846000018460001b846129eb565b60001c90509392505050565b600061260982600001612a6c565b9050919050565b61261b8484846122ef565b61262784848484612a7d565b612666576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161265d90613b9d565b60405180910390fd5b50505050565b606060008214156126b4576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612814565b600082905060005b600082146126e65780806126cf906141d4565b915050600a826126df9190613ffc565b91506126bc565b60008167ffffffffffffffff811115612728577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f19166020018201604052801561275a5781602001600182028036833780820191505090505b5090505b6000851461280d576001826127739190614087565b9150600a85612782919061421d565b603061278e9190613fa6565b60f81b8183815181106127ca577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a856128069190613ffc565b945061275e565b8093505050505b919050565b600061282b836000018360001b612be1565b905092915050565b600061284182600001612c01565b9050919050565b505050565b600061285f836000018360001b612c16565b905092915050565b6000612879836000018360001b612d94565b905092915050565b60006128ad846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b612e04565b90509392505050565b600081836000018054905011612901576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128f890613b7d565b60405180910390fd5b82600001828154811061293d577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b61295a8383612e3f565b6129676000848484612a7d565b6129a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161299d90613b9d565b60405180910390fd5b505050565b60008060006129c68486600001612fcd90919063ffffffff16565b9050808560020160008381526020019081526020016000205492509250509250929050565b6000808460020160008581526020019081526020016000205490506000801b81141580612a1e5750612a1d8585612be1565b5b8390612a60576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612a579190613b5b565b60405180910390fd5b50809150509392505050565b600081600001805490509050919050565b6000612a9e8473ffffffffffffffffffffffffffffffffffffffff16612fe4565b612aab5760019050612bd9565b6000612b7263150b7a0260e01b612ac061211e565b888787604051602401612ad69493929190613ad2565b604051602081830303815290604052907bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19166020820180517bffffffffffffffffffffffffffffffffffffffffffffffffffffffff838183161783525050505060405180606001604052806032815260200161493e603291398773ffffffffffffffffffffffffffffffffffffffff16612ff79092919063ffffffff16565b9050600081806020019051810190612b8a919061351b565b905063150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff191614925050505b949350505050565b6000612bf9828460000161300f90919063ffffffff16565b905092915050565b6000612c0f82600001612a6c565b9050919050565b60008083600101600084815260200190815260200160002054905060008114612d88576000600182612c489190614087565b9050600060018660000180549050612c609190614087565b90506000866000018281548110612ca0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110612cea577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200181905550838760010160008381526020019081526020016000208190555086600001805480612d4c577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050612d8e565b60009150505b92915050565b6000612da08383613026565b612df9578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612dfe565b600090505b92915050565b60008184600201600085815260200190815260200160002081905550612e36838560000161304990919063ffffffff16565b90509392505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612eaf576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612ea690613d3d565b60405180910390fd5b612eb881612126565b15612ef8576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612eef90613bdd565b60405180910390fd5b612f0460008383612848565b612f5581600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061286790919063ffffffff16565b50612f6c818360026128819092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b6000612fdc83600001836128b6565b905092915050565b600080823b905060008111915050919050565b60606130068484600085613060565b90509392505050565b600061301e8360000183613026565b905092915050565b600080836001016000848152602001908152602001600020541415905092915050565b60006130588360000183612d94565b905092915050565b60608247101561306f57600080fd5b61307885612fe4565b61308157600080fd5b6000808673ffffffffffffffffffffffffffffffffffffffff1685876040516130aa9190613a7c565b60006040518083038185875af1925050503d80600081146130e7576040519150601f19603f3d011682016040523d82523d6000602084013e6130ec565b606091505b50915091506130fc828286613108565b92505050949350505050565b6060831561311857829050613168565b60008351111561312b5782518084602001fd5b816040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161315f9190613b5b565b60405180910390fd5b9392505050565b82805461317b90614171565b90600052602060002090601f01602090048101928261319d57600085556131e4565b82601f106131b657805160ff19168380011785556131e4565b828001600101855582156131e4579182015b828111156131e35782518255916020019190600101906131c8565b5b5090506131f191906131f5565b5090565b5b8082111561320e5760008160009055506001016131f6565b5090565b600061322561322084613ebd565b613e98565b90508281526020810184848401111561323d57600080fd5b61324884828561412f565b509392505050565b600061326361325e84613eee565b613e98565b90508281526020810184848401111561327b57600080fd5b61328684828561412f565b509392505050565b60008135905061329d816148e1565b92915050565b6000813590506132b2816148f8565b92915050565b6000813590506132c78161490f565b92915050565b6000815190506132dc8161490f565b92915050565b600082601f8301126132f357600080fd5b8135613303848260208601613212565b91505092915050565b600082601f83011261331d57600080fd5b813561332d848260208601613250565b91505092915050565b60008135905061334581614926565b92915050565b60006020828403121561335d57600080fd5b600061336b8482850161328e565b91505092915050565b6000806040838503121561338757600080fd5b60006133958582860161328e565b92505060206133a68582860161328e565b9150509250929050565b6000806000606084860312156133c557600080fd5b60006133d38682870161328e565b93505060206133e48682870161328e565b92505060406133f586828701613336565b9150509250925092565b6000806000806080858703121561341557600080fd5b60006134238782880161328e565b94505060206134348782880161328e565b935050604061344587828801613336565b925050606085013567ffffffffffffffff81111561346257600080fd5b61346e878288016132e2565b91505092959194509250565b6000806040838503121561348d57600080fd5b600061349b8582860161328e565b92505060206134ac858286016132a3565b9150509250929050565b600080604083850312156134c957600080fd5b60006134d78582860161328e565b92505060206134e885828601613336565b9150509250929050565b60006020828403121561350457600080fd5b6000613512848285016132b8565b91505092915050565b60006020828403121561352d57600080fd5b600061353b848285016132cd565b91505092915050565b60006020828403121561355657600080fd5b600082013567ffffffffffffffff81111561357057600080fd5b61357c8482850161330c565b91505092915050565b60006020828403121561359757600080fd5b60006135a584828501613336565b91505092915050565b60006135ba8383613a5e565b60208301905092915050565b6135cf816140bb565b82525050565b60006135e082613f2f565b6135ea8185613f5d565b93506135f583613f1f565b8060005b8381101561362657815161360d88826135ae565b975061361883613f50565b9250506001810190506135f9565b5085935050505092915050565b61363c816140cd565b82525050565b600061364d82613f3a565b6136578185613f6e565b935061366781856020860161413e565b6136708161430a565b840191505092915050565b600061368682613f3a565b6136908185613f7f565b93506136a081856020860161413e565b80840191505092915050565b60006136b782613f45565b6136c18185613f8a565b93506136d181856020860161413e565b6136da8161430a565b840191505092915050565b60006136f082613f45565b6136fa8185613f9b565b935061370a81856020860161413e565b80840191505092915050565b6000613723602283613f8a565b915061372e8261431b565b604082019050919050565b6000613746603283613f8a565b91506137518261436a565b604082019050919050565b6000613769602683613f8a565b9150613774826143b9565b604082019050919050565b600061378c601c83613f8a565b915061379782614408565b602082019050919050565b60006137af601683613f8a565b91506137ba82614431565b602082019050919050565b60006137d2602483613f8a565b91506137dd8261445a565b604082019050919050565b60006137f5601983613f8a565b9150613800826144a9565b602082019050919050565b6000613818601f83613f8a565b9150613823826144d2565b602082019050919050565b600061383b601b83613f8a565b9150613846826144fb565b602082019050919050565b600061385e602c83613f8a565b915061386982614524565b604082019050919050565b6000613881601d83613f8a565b915061388c82614573565b602082019050919050565b60006138a4603883613f8a565b91506138af8261459c565b604082019050919050565b60006138c7602983613f8a565b91506138d2826145eb565b604082019050919050565b60006138ea602a83613f8a565b91506138f58261463a565b604082019050919050565b600061390d602083613f8a565b915061391882614689565b602082019050919050565b6000613930602c83613f8a565b915061393b826146b2565b604082019050919050565b6000613953602083613f8a565b915061395e82614701565b602082019050919050565b6000613976602983613f8a565b91506139818261472a565b604082019050919050565b6000613999602f83613f8a565b91506139a482614779565b604082019050919050565b60006139bc602183613f8a565b91506139c7826147c8565b604082019050919050565b60006139df601683613f8a565b91506139ea82614817565b602082019050919050565b6000613a02601883613f8a565b9150613a0d82614840565b602082019050919050565b6000613a25602083613f8a565b9150613a3082614869565b602082019050919050565b6000613a48603183613f8a565b9150613a5382614892565b604082019050919050565b613a6781614125565b82525050565b613a7681614125565b82525050565b6000613a88828461367b565b915081905092915050565b6000613a9f82856136e5565b9150613aab82846136e5565b91508190509392505050565b6000602082019050613acc60008301846135c6565b92915050565b6000608082019050613ae760008301876135c6565b613af460208301866135c6565b613b016040830185613a6d565b8181036060830152613b138184613642565b905095945050505050565b60006020820190508181036000830152613b3881846135d5565b905092915050565b6000602082019050613b556000830184613633565b92915050565b60006020820190508181036000830152613b7581846136ac565b905092915050565b60006020820190508181036000830152613b9681613716565b9050919050565b60006020820190508181036000830152613bb681613739565b9050919050565b60006020820190508181036000830152613bd68161375c565b9050919050565b60006020820190508181036000830152613bf68161377f565b9050919050565b60006020820190508181036000830152613c16816137a2565b9050919050565b60006020820190508181036000830152613c36816137c5565b9050919050565b60006020820190508181036000830152613c56816137e8565b9050919050565b60006020820190508181036000830152613c768161380b565b9050919050565b60006020820190508181036000830152613c968161382e565b9050919050565b60006020820190508181036000830152613cb681613851565b9050919050565b60006020820190508181036000830152613cd681613874565b9050919050565b60006020820190508181036000830152613cf681613897565b9050919050565b60006020820190508181036000830152613d16816138ba565b9050919050565b60006020820190508181036000830152613d36816138dd565b9050919050565b60006020820190508181036000830152613d5681613900565b9050919050565b60006020820190508181036000830152613d7681613923565b9050919050565b60006020820190508181036000830152613d9681613946565b9050919050565b60006020820190508181036000830152613db681613969565b9050919050565b60006020820190508181036000830152613dd68161398c565b9050919050565b60006020820190508181036000830152613df6816139af565b9050919050565b60006020820190508181036000830152613e16816139d2565b9050919050565b60006020820190508181036000830152613e36816139f5565b9050919050565b60006020820190508181036000830152613e5681613a18565b9050919050565b60006020820190508181036000830152613e7681613a3b565b9050919050565b6000602082019050613e926000830184613a6d565b92915050565b6000613ea2613eb3565b9050613eae82826141a3565b919050565b6000604051905090565b600067ffffffffffffffff821115613ed857613ed76142db565b5b613ee18261430a565b9050602081019050919050565b600067ffffffffffffffff821115613f0957613f086142db565b5b613f128261430a565b9050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b600082825260208201905092915050565b600081905092915050565b6000613fb182614125565b9150613fbc83614125565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff03821115613ff157613ff061424e565b5b828201905092915050565b600061400782614125565b915061401283614125565b9250826140225761402161427d565b5b828204905092915050565b600061403882614125565b915061404383614125565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561407c5761407b61424e565b5b828202905092915050565b600061409282614125565b915061409d83614125565b9250828210156140b0576140af61424e565b5b828203905092915050565b60006140c682614105565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b8381101561415c578082015181840152602081019050614141565b8381111561416b576000848401525b50505050565b6000600282049050600182168061418957607f821691505b6020821081141561419d5761419c6142ac565b5b50919050565b6141ac8261430a565b810181811067ffffffffffffffff821117156141cb576141ca6142db565b5b80604052505050565b60006141df82614125565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff8214156142125761421161424e565b5b600182019050919050565b600061422882614125565b915061423383614125565b9250826142435761424261427d565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b7f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60008201527f6473000000000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008201527f63656976657220696d706c656d656e7465720000000000000000000000000000602082015250565b7f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008201527f6464726573730000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20746f6b656e20616c7265616479206d696e74656400000000600082015250565b7f45786365656473204d41585f4e46545f535550504c5900000000000000000000600082015250565b7f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008201527f7265737300000000000000000000000000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f766520746f2063616c6c657200000000000000600082015250565b7f45746865722076616c75652073656e74206973206e6f7420636f727265637400600082015250565b7f53616c65206d7573742062652061637469766520746f206d696e740000000000600082015250565b7f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f5374617274696e6720696e64657820697320616c726561647920736574000000600082015250565b7f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008201527f6e6572206e6f7220617070726f76656420666f7220616c6c0000000000000000602082015250565b7f596f75206d6179206e6f7420627579206d6f7265207468616e203230204e465460008201527f73206174206f6e63650000000000000000000000000000000000000000000000602082015250565b7f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008201527f726f206164647265737300000000000000000000000000000000000000000000602082015250565b7f4552433732313a206d696e7420746f20746865207a65726f2061646472657373600082015250565b7f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008201527f697374656e7420746f6b656e0000000000000000000000000000000000000000602082015250565b7f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e6572600082015250565b7f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008201527f73206e6f74206f776e0000000000000000000000000000000000000000000000602082015250565b7f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008201527f6e6578697374656e7420746f6b656e0000000000000000000000000000000000602082015250565b7f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008201527f7200000000000000000000000000000000000000000000000000000000000000602082015250565b7f53616c652068617320616c726561647920656e64656400000000000000000000600082015250565b7f6e756d6265724f664e6674732063616e6e6f7420626520300000000000000000600082015250565b7f5374617274696e6720696e64657820626c6f636b206d75737420626520736574600082015250565b7f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008201527f776e6572206e6f7220617070726f766564000000000000000000000000000000602082015250565b6148ea816140bb565b81146148f557600080fd5b50565b614901816140cd565b811461490c57600080fd5b50565b614918816140d9565b811461492357600080fd5b50565b61492f81614125565b811461493a57600080fd5b5056fe4552433732313a207472616e7366657220746f206e6f6e20455243373231526563656976657220696d706c656d656e7465724552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea2646970667358221220062f15ad73324cc34744ab1c4c010ae0fb3ebdbb79ea5b51dd990e81bb0e741864736f6c63430008040033

Deployed Bytecode Sourcemap

129:5601:1:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4514:123;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1353:148:3;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4523:98:4;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;7228:217;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6772:395;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;6266:208;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;431:31:1;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;8092:300:4;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;6035:160;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2646:1222:1;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;3948:212;;;;;;;;;;;;;:::i;:::-;;8458:149:4;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;780:100:1;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;6546:169:4;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4358:77:1;;;;;;;;;;;;;:::i;:::-;;2362:99;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;4286:175:4;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;210:43:1;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;5861:95:4;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4011:218;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1693:145:13;;;;;;;;;;;;;:::i;:::-;;5546:182:1;;;;;;;;;;;;;:::i;:::-;;886:532;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1061:85:13;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4685:102:4;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;7512:290;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;304:45:1;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4166:186;;;;;;;;;;;;;:::i;:::-;;8673:282:4;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;4853:776;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;396:28:1;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;356:33;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;7868:162:4;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;4708:707:1;;;;;;;;;;;;;:::i;:::-;;687:32;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;1987:240:13;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;1424:818:1;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;2467:124;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;4514:123;1284:12:13;:10;:12::i;:::-;1273:23;;:7;:5;:7::i;:::-;:23;;;1265:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;4615:15:1::1;4596:16;:34;;;;4514:123:::0;:::o;1353:148:3:-;1438:4;1461:20;:33;1482:11;1461:33;;;;;;;;;;;;;;;;;;;;;;;;;;;1454:40;;1353:148;;;:::o;4523:98:4:-;4577:13;4609:5;4602:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4523:98;:::o;7228:217::-;7304:7;7331:16;7339:7;7331;:16::i;:::-;7323:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;7414:15;:24;7430:7;7414:24;;;;;;;;;;;;;;;;;;;;;7407:31;;7228:217;;;:::o;6772:395::-;6852:13;6868:23;6883:7;6868:14;:23::i;:::-;6852:39;;6915:5;6909:11;;:2;:11;;;;6901:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;6993:5;6977:21;;:12;:10;:12::i;:::-;:21;;;:69;;;;7002:44;7026:5;7033:12;:10;:12::i;:::-;7002:23;:44::i;:::-;6977:69;6969:159;;;;;;;;;;;;:::i;:::-;;;;;;;;;7139:21;7148:2;7152:7;7139:8;:21::i;:::-;6772:395;;;:::o;6266:208::-;6327:7;6446:21;:12;:19;:21::i;:::-;6439:28;;6266:208;:::o;431:31:1:-;;;;:::o;8092:300:4:-;8251:41;8270:12;:10;:12::i;:::-;8284:7;8251:18;:41::i;:::-;8243:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;8357:28;8367:4;8373:2;8377:7;8357:9;:28::i;:::-;8092:300;;;:::o;6035:160::-;6132:7;6158:30;6182:5;6158:13;:20;6172:5;6158:20;;;;;;;;;;;;;;;:23;;:30;;;;:::i;:::-;6151:37;;6035:160;;;;:::o;2646:1222:1:-;2714:12;;;;;;;;;;;2706:52;;;;;;;;;;;;:::i;:::-;;;;;;;;;345:4;2776:13;:11;:13::i;:::-;:30;2768:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;2859:1;2851:5;:9;2843:46;;;;;;;;;;;;:::i;:::-;;;;;;;;;2916:2;2907:5;:11;;2899:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;345:4;2995:34;3008:13;:11;:13::i;:::-;3023:5;2995:12;:34::i;:::-;:52;;2974:121;;;;;;;;;;;;:::i;:::-;;;;;;;;;3164:9;3126:34;3139:13;:11;:13::i;:::-;3154:5;3126:12;:34::i;:::-;:47;3105:125;;;;;;;;;;;;:::i;:::-;;;;;;;;;3246:9;3241:204;3265:5;3261:1;:9;3241:204;;;3291:17;3311:13;:11;:13::i;:::-;3291:33;;345:4;3342:9;:26;3338:97;;;3388:32;3398:10;3410:9;3388;:32::i;:::-;3338:97;3241:204;3272:3;;;;;:::i;:::-;;;;3241:204;;;;3688:1;3666:18;;:23;:127;;;;;345:4;3706:13;:11;:13::i;:::-;:31;:86;;;;3776:16;;3757:15;:35;;3706:86;3666:127;3649:213;;;3839:12;3818:18;:33;;;;3649:213;2646:1222;:::o;3948:212::-;1284:12:13;:10;:12::i;:::-;1273:23;;:7;:5;:7::i;:::-;:23;;;1265:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;3997:13:1::1;4013:21;3997:37;;4044:14;4061:12;4071:1;4061:5;:9;;:12;;;;:::i;:::-;4044:29;;528:42;4083:16;;:24;4100:6;4083:24;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;637:42;4117:17;;:36;4135:17;4145:6;4135:5;:9;;:17;;;;:::i;:::-;4117:36;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;::::0;::::1;;;;;;1343:1:13;;3948:212:1:o:0;8458:149:4:-;8561:39;8578:4;8584:2;8588:7;8561:39;;;;;;;;;;;;:16;:39::i;:::-;8458:149;;;:::o;780:100:1:-;834:4;857:16;865:7;857;:16::i;:::-;850:23;;780:100;;;:::o;6546:169:4:-;6621:7;6641:15;6662:22;6678:5;6662:12;:15;;:22;;;;:::i;:::-;6640:44;;;6701:7;6694:14;;;6546:169;;;:::o;4358:77:1:-;1284:12:13;:10;:12::i;:::-;1273:23;;:7;:5;:7::i;:::-;:23;;;1265:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;4423:5:1::1;4408:12;;:20;;;;;;;;;;;;;;;;;;4358:77::o:0;2362:99::-;1284:12:13;:10;:12::i;:::-;1273:23;;:7;:5;:7::i;:::-;:23;;;1265:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;2434:20:1::1;2446:7;2434:11;:20::i;:::-;2362:99:::0;:::o;4286:175:4:-;4358:7;4384:70;4401:7;4384:70;;;;;;;;;;;;;;;;;:12;:16;;:70;;;;;:::i;:::-;4377:77;;4286:175;;;:::o;210:43:1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;5861:95:4:-;5909:13;5941:8;5934:15;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5861:95;:::o;4011:218::-;4083:7;4127:1;4110:19;;:5;:19;;;;4102:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;4193:29;:13;:20;4207:5;4193:20;;;;;;;;;;;;;;;:27;:29::i;:::-;4186:36;;4011:218;;;:::o;1693:145:13:-;1284:12;:10;:12::i;:::-;1273:23;;:7;:5;:7::i;:::-;:23;;;1265:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;1799:1:::1;1762:40;;1783:6;;;;;;;;;;;1762:40;;;;;;;;;;;;1829:1;1812:6;;:19;;;;;;;;;;;;;;;;;;1693:145::o:0;5546:182:1:-;1284:12:13;:10;:12::i;:::-;1273:23;;:7;:5;:7::i;:::-;:23;;;1265:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;5642:1:1::1;5625:13;;:18;5617:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;5709:12;5688:18;:33;;;;5546:182::o:0;886:532::-;972:16;1004:18;1025:17;1035:6;1025:9;:17::i;:::-;1004:38;;1070:1;1056:10;:15;1052:360;;;1145:1;1131:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1124:23;;;;;1052:360;1178:23;1218:10;1204:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1178:51;;1248:13;1243:132;1271:10;1263:5;:18;1243:132;;;1326:34;1346:6;1354:5;1326:19;:34::i;:::-;1310:6;1317:5;1310:13;;;;;;;;;;;;;;;;;;;;;:50;;;;;1283:7;;;;;:::i;:::-;;;;1243:132;;;;1395:6;1388:13;;;;886:532;;;;:::o;1061:85:13:-;1107:7;1133:6;;;;;;;;;;;1126:13;;1061:85;:::o;4685:102:4:-;4741:13;4773:7;4766:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;4685:102;:::o;7512:290::-;7626:12;:10;:12::i;:::-;7614:24;;:8;:24;;;;7606:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;7724:8;7679:18;:32;7698:12;:10;:12::i;:::-;7679:32;;;;;;;;;;;;;;;:42;7712:8;7679:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;7776:8;7747:48;;7762:12;:10;:12::i;:::-;7747:48;;;7786:8;7747:48;;;;;;:::i;:::-;;;;;;;;7512:290;;:::o;304:45:1:-;345:4;304:45;:::o;4166:186::-;1284:12:13;:10;:12::i;:::-;1273:23;;:7;:5;:7::i;:::-;:23;;;1265:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;4231:4:1::1;4216:12;;:19;;;;;;;;;;;;;;;;;;4269:1;4249:16;;:21;4245:101;;;4324:10;4305:15;:30;;;;:::i;:::-;4286:16;:49;;;;4245:101;4166:186::o:0;8673:282:4:-;8804:41;8823:12;:10;:12::i;:::-;8837:7;8804:18;:41::i;:::-;8796:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;8909:39;8923:4;8929:2;8933:7;8942:5;8909:13;:39::i;:::-;8673:282;;;;:::o;4853:776::-;4926:13;4959:16;4967:7;4959;:16::i;:::-;4951:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;5038:23;5064:10;:19;5075:7;5064:19;;;;;;;;;;;5038:45;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;5093:18;5114:9;:7;:9::i;:::-;5093:30;;5218:1;5202:4;5196:18;:23;5192:70;;;5242:9;5235:16;;;;;;5192:70;5390:1;5370:9;5364:23;:27;5360:106;;;5438:4;5444:9;5421:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;5407:48;;;;;;5360:106;5596:4;5602:18;:7;:16;:18::i;:::-;5579:42;;;;;;;;;:::i;:::-;;;;;;;;;;;;;5565:57;;;;4853:776;;;;:::o;396:28:1:-;;;;:::o;356:33::-;;;;:::o;7868:162:4:-;7965:4;7988:18;:25;8007:5;7988:25;;;;;;;;;;;;;;;:35;8014:8;7988:35;;;;;;;;;;;;;;;;;;;;;;;;;7981:42;;7868:162;;;;:::o;4708:707:1:-;4780:1;4763:13;;:18;4755:60;;;;;;;;;;;;:::i;:::-;;;;;;;;;4855:1;4833:18;;:23;;4825:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;345:4;4938:18;;4928:29;4920:38;;:55;;;;:::i;:::-;4904:13;:71;;;;5148:3;5109:36;5126:18;;5109:12;:16;;:36;;;;:::i;:::-;:42;5105:174;;;345:4;5232:1;5217:12;:16;;;;:::i;:::-;5207:27;5199:36;;:69;;;;:::i;:::-;5167:13;:101;;;;5105:174;5345:1;5328:13;;:18;5324:85;;;5378:20;5396:1;5378:13;;:17;;:20;;;;:::i;:::-;5362:13;:36;;;;5324:85;4708:707::o;687:32::-;;;;;;;;;;;;;:::o;1987:240:13:-;1284:12;:10;:12::i;:::-;1273:23;;:7;:5;:7::i;:::-;:23;;;1265:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;2095:1:::1;2075:22;;:8;:22;;;;2067:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;2184:8;2155:38;;2176:6;;;;;;;;;;;2155:38;;;;;;;;;;;;2212:8;2203:6;;:17;;;;;;;;;;;;;;;;;;1987:240:::0;:::o;1424:818:1:-;1468:7;1487:20;1510:13;:11;:13::i;:::-;1487:36;;345:4;1538:12;:30;1534:702;;1591:1;1584:8;;;;;1534:702;1629:4;1613:12;:20;1609:627;;1656:9;1649:16;;;;;1609:627;1702:4;1686:12;:20;1682:554;;1729:9;1722:16;;;;;1682:554;1775:4;1759:12;:20;1755:481;;1802:9;1795:16;;;;;1755:481;1848:4;1832:12;:20;1828:408;;1875:9;1868:16;;;;;1828:408;1921:4;1905:12;:20;1901:335;;1948:9;1941:16;;;;;1901:335;1994:4;1978:12;:20;1974:262;;2021:10;2014:17;;;;;1974:262;2068:3;2052:12;:19;2048:188;;2094:10;2087:17;;;;;2048:188;2141:3;2125:12;:19;2121:115;;2167:10;2160:17;;;;;2121:115;2215:10;2208:17;;;1424:818;;:::o;2467:124::-;1284:12:13;:10;:12::i;:::-;1273:23;;:7;:5;:7::i;:::-;:23;;;1265:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;2573:11:1::1;2546:24;:38;;;;;;;;;;;;:::i;:::-;;2467:124:::0;:::o;586:96:2:-;639:7;665:10;658:17;;586:96;:::o;10389:125:4:-;10454:4;10477:30;10499:7;10477:12;:21;;:30;;;;:::i;:::-;10470:37;;10389:125;;;:::o;16124:180::-;16216:2;16189:15;:24;16205:7;16189:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;16271:7;16267:2;16233:46;;16242:23;16257:7;16242:14;:23::i;:::-;16233:46;;;;;;;;;;;;16124:180;;:::o;5520:121:5:-;5589:7;5615:19;5623:3;:10;;5615:7;:19::i;:::-;5608:26;;5520:121;;;:::o;10672:351:4:-;10765:4;10789:16;10797:7;10789;:16::i;:::-;10781:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;10864:13;10880:23;10895:7;10880:14;:23::i;:::-;10864:39;;10932:5;10921:16;;:7;:16;;;:51;;;;10965:7;10941:31;;:20;10953:7;10941:11;:20::i;:::-;:31;;;10921:51;:94;;;;10976:39;11000:5;11007:7;10976:23;:39::i;:::-;10921:94;10913:103;;;10672:351;;;;:::o;13712:584::-;13836:4;13809:31;;:23;13824:7;13809:14;:23::i;:::-;:31;;;13801:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;13936:1;13922:16;;:2;:16;;;;13914:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;13990:39;14011:4;14017:2;14021:7;13990:20;:39::i;:::-;14091:29;14108:1;14112:7;14091:8;:29::i;:::-;14131:35;14158:7;14131:13;:19;14145:4;14131:19;;;;;;;;;;;;;;;:26;;:35;;;;:::i;:::-;;14176:30;14198:7;14176:13;:17;14190:2;14176:17;;;;;;;;;;;;;;;:21;;:30;;;;:::i;:::-;;14217:29;14234:7;14243:2;14217:12;:16;;:29;;;;;:::i;:::-;;14281:7;14277:2;14262:27;;14271:4;14262:27;;;;;;;;;;;;13712:584;;;:::o;9251:135:6:-;9322:7;9356:22;9360:3;:10;;9372:5;9356:3;:22::i;:::-;9348:31;;9341:38;;9251:135;;;;:::o;650:96:14:-;708:7;738:1;734;:5;;;;:::i;:::-;727:12;;650:96;;;;:::o;1360:::-;1418:7;1448:1;1444;:5;;;;:::i;:::-;1437:12;;1360:96;;;;:::o;11353:108:4:-;11428:26;11438:2;11442:7;11428:26;;;;;;;;;;;;:9;:26::i;:::-;11353:108;;:::o;1745:96:14:-;1803:7;1833:1;1829;:5;;;;:::i;:::-;1822:12;;1745:96;;;;:::o;1017:::-;1075:7;1105:1;1101;:5;;;;:::i;:::-;1094:12;;1017:96;;;;:::o;5969:233:5:-;6049:7;6058;6078:11;6091:13;6108:22;6112:3;:10;;6124:5;6108:3;:22::i;:::-;6077:53;;;;6156:3;6148:12;;6186:5;6178:14;;6140:55;;;;;;5969:233;;;;;:::o;14878:98:4:-;14961:8;14950;:19;;;;;;;;;;;;:::i;:::-;;14878:98;:::o;7222:211:5:-;7329:7;7379:44;7384:3;:10;;7404:3;7396:12;;7410;7379:4;:44::i;:::-;7371:53;;7348:78;;7222:211;;;;;:::o;8807:112:6:-;8867:7;8893:19;8901:3;:10;;8893:7;:19::i;:::-;8886:26;;8807:112;;;:::o;9817:269:4:-;9930:28;9940:4;9946:2;9950:7;9930:9;:28::i;:::-;9976:48;9999:4;10005:2;10009:7;10018:5;9976:22;:48::i;:::-;9968:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;9817:269;;;;:::o;210:703:15:-;266:13;492:1;483:5;:10;479:51;;;509:10;;;;;;;;;;;;;;;;;;;;;479:51;539:12;554:5;539:20;;569:14;593:75;608:1;600:4;:9;593:75;;625:8;;;;;:::i;:::-;;;;655:2;647:10;;;;;:::i;:::-;;;593:75;;;677:19;709:6;699:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;677:39;;726:150;742:1;733:5;:10;726:150;;769:1;759:11;;;;;:::i;:::-;;;835:2;827:5;:10;;;;:::i;:::-;814:2;:24;;;;:::i;:::-;801:39;;784:6;791;784:14;;;;;;;;;;;;;;;;;;;:56;;;;;;;;;;;863:2;854:11;;;;;:::i;:::-;;;726:150;;;899:6;885:21;;;;;210:703;;;;:::o;5288:149:5:-;5372:4;5395:35;5405:3;:10;;5425:3;5417:12;;5395:9;:35::i;:::-;5388:42;;5288:149;;;;:::o;2462:107::-;2518:7;2544:18;:3;:9;;:16;:18::i;:::-;2537:25;;2462:107;;;:::o;16900:93:4:-;;;;:::o;8366:135:6:-;8436:4;8459:35;8467:3;:10;;8487:5;8479:14;;8459:7;:35::i;:::-;8452:42;;8366:135;;;;:::o;8069:129::-;8136:4;8159:32;8164:3;:10;;8184:5;8176:14;;8159:4;:32::i;:::-;8152:39;;8069:129;;;;:::o;4727:183:5:-;4816:4;4839:64;4844:3;:10;;4864:3;4856:12;;4894:5;4878:23;;4870:32;;4839:4;:64::i;:::-;4832:71;;4727:183;;;;;:::o;4453:201:6:-;4520:7;4568:5;4547:3;:11;;:18;;;;:26;4539:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;4629:3;:11;;4641:5;4629:18;;;;;;;;;;;;;;;;;;;;;;;;4622:25;;4453:201;;;;:::o;11682:247:4:-;11777:18;11783:2;11787:7;11777:5;:18::i;:::-;11813:54;11844:1;11848:2;11852:7;11861:5;11813:22;:54::i;:::-;11805:117;;;;;;;;;;;;:::i;:::-;;;;;;;;;11682:247;;;:::o;2912:175:5:-;2979:7;2988;3007:11;3021:19;3034:5;3021:3;:9;;:12;;:19;;;;:::i;:::-;3007:33;;3058:3;3063;:11;;:16;3075:3;3063:16;;;;;;;;;;;;3050:30;;;;;2912:175;;;;;:::o;4178:240::-;4272:7;4291:13;4307:3;:11;;:16;4319:3;4307:16;;;;;;;;;;;;4291:32;;4350:1;4341:10;;:5;:10;;:33;;;;4355:19;4365:3;4370;4355:9;:19::i;:::-;4341:33;4376:12;4333:56;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;4406:5;4399:12;;;4178:240;;;;;:::o;4014:107:6:-;4070:7;4096:3;:11;;:18;;;;4089:25;;4014:107;;;:::o;15529:589:4:-;15649:4;15674:15;:2;:13;;;:15::i;:::-;15669:58;;15712:4;15705:11;;;;15669:58;15736:23;15762:246;15814:45;;;15873:12;:10;:12::i;:::-;15899:4;15917:7;15938:5;15778:175;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;15762:246;;;;;;;;;;;;;;;;;:2;:15;;;;:246;;;;;:::i;:::-;15736:272;;16018:13;16045:10;16034:32;;;;;;;;;;;;:::i;:::-;16018:48;;1091:10;16094:16;;16084:26;;;:6;:26;;;;16076:35;;;;15529:589;;;;;;;:::o;2248:124:5:-;2319:4;2342:23;2361:3;2342;:9;;:18;;:23;;;;:::i;:::-;2335:30;;2248:124;;;;:::o;5614:115:6:-;5677:7;5703:19;5711:3;:10;;5703:7;:19::i;:::-;5696:26;;5614:115;;;:::o;2204:1521::-;2270:4;2386:18;2407:3;:12;;:19;2420:5;2407:19;;;;;;;;;;;;2386:40;;2455:1;2441:10;:15;2437:1282;;2798:21;2835:1;2822:10;:14;;;;:::i;:::-;2798:38;;2850:17;2891:1;2870:3;:11;;:18;;;;:22;;;;:::i;:::-;2850:42;;3132:17;3152:3;:11;;3164:9;3152:22;;;;;;;;;;;;;;;;;;;;;;;;3132:42;;3295:9;3266:3;:11;;3278:13;3266:26;;;;;;;;;;;;;;;;;;;;;;;:38;;;;3396:10;3370:3;:12;;:23;3383:9;3370:23;;;;;;;;;;;:36;;;;3528:3;:11;;:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3620:3;:12;;:19;3633:5;3620:19;;;;;;;;;;;3613:26;;;3661:4;3654:11;;;;;;;;2437:1282;3703:5;3696:12;;;2204:1521;;;;;:::o;1632:404::-;1695:4;1716:21;1726:3;1731:5;1716:9;:21::i;:::-;1711:319;;1753:3;:11;;1770:5;1753:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;1933:3;:11;;:18;;;;1911:3;:12;;:19;1924:5;1911:19;;;;;;;;;;;:40;;;;1972:4;1965:11;;;;1711:319;2014:5;2007:12;;1632:404;;;;;:::o;1695:158:5:-;1771:4;1806:5;1787:3;:11;;:16;1799:3;1787:16;;;;;;;;;;;:24;;;;1828:18;1842:3;1828;:9;;:13;;:18;;;;:::i;:::-;1821:25;;1695:158;;;;;:::o;12251:393:4:-;12344:1;12330:16;;:2;:16;;;;12322:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;12402:16;12410:7;12402;:16::i;:::-;12401:17;12393:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;12462:45;12491:1;12495:2;12499:7;12462:20;:45::i;:::-;12518:30;12540:7;12518:13;:17;12532:2;12518:17;;;;;;;;;;;;;;;:21;;:30;;;;:::i;:::-;;12559:29;12576:7;12585:2;12559:12;:16;;:29;;;;;:::i;:::-;;12629:7;12625:2;12604:33;;12621:1;12604:33;;;;;;;;;;;;12251:393;;:::o;6061:129:6:-;6135:7;6161:22;6165:3;:10;;6177:5;6161:3;:22::i;:::-;6154:29;;6061:129;;;;:::o;718:413:0:-;778:4;981:12;1090:7;1078:20;1070:28;;1123:1;1116:4;:8;1109:15;;;718:413;;;:::o;2231:193::-;2334:12;2365:52;2387:6;2395:4;2401:1;2404:12;2365:21;:52::i;:::-;2358:59;;2231:193;;;;;:::o;5395:138:6:-;5475:4;5498:28;5508:3;:10;;5520:5;5498:9;:28::i;:::-;5491:35;;5395:138;;;;:::o;3806:127::-;3879:4;3925:1;3902:3;:12;;:19;3915:5;3902:19;;;;;;;;;;;;:24;;3895:31;;3806:127;;;;:::o;4894:123::-;4964:4;4987:23;4992:3;:10;;5004:5;4987:4;:23::i;:::-;4980:30;;4894:123;;;;:::o;3213:448:0:-;3340:12;3397:5;3372:21;:30;;3364:39;;;;;;3421:18;3432:6;3421:10;:18::i;:::-;3413:27;;;;;;3511:12;3525:23;3552:6;:11;;3572:5;3580:4;3552:33;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;3510:75;;;;3602:52;3620:7;3629:10;3641:12;3602:17;:52::i;:::-;3595:59;;;;3213:448;;;;;;:::o;3667:725::-;3782:12;3810:7;3806:580;;;3840:10;3833:17;;;;3806:580;3971:1;3951:10;:17;:21;3947:429;;;4209:10;4203:17;4269:15;4256:10;4252:2;4248:19;4241:44;4158:145;4348:12;4341:20;;;;;;;;;;;:::i;:::-;;;;;;;;3667:725;;;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;7:343:16:-;84:5;109:65;125:48;166:6;125:48;:::i;:::-;109:65;:::i;:::-;100:74;;197:6;190:5;183:21;235:4;228:5;224:16;273:3;264:6;259:3;255:16;252:25;249:2;;;290:1;287;280:12;249:2;303:41;337:6;332:3;327;303:41;:::i;:::-;90:260;;;;;;:::o;356:345::-;434:5;459:66;475:49;517:6;475:49;:::i;:::-;459:66;:::i;:::-;450:75;;548:6;541:5;534:21;586:4;579:5;575:16;624:3;615:6;610:3;606:16;603:25;600:2;;;641:1;638;631:12;600:2;654:41;688:6;683:3;678;654:41;:::i;:::-;440:261;;;;;;:::o;707:139::-;753:5;791:6;778:20;769:29;;807:33;834:5;807:33;:::i;:::-;759:87;;;;:::o;852:133::-;895:5;933:6;920:20;911:29;;949:30;973:5;949:30;:::i;:::-;901:84;;;;:::o;991:137::-;1036:5;1074:6;1061:20;1052:29;;1090:32;1116:5;1090:32;:::i;:::-;1042:86;;;;:::o;1134:141::-;1190:5;1221:6;1215:13;1206:22;;1237:32;1263:5;1237:32;:::i;:::-;1196:79;;;;:::o;1294:271::-;1349:5;1398:3;1391:4;1383:6;1379:17;1375:27;1365:2;;1416:1;1413;1406:12;1365:2;1456:6;1443:20;1481:78;1555:3;1547:6;1540:4;1532:6;1528:17;1481:78;:::i;:::-;1472:87;;1355:210;;;;;:::o;1585:273::-;1641:5;1690:3;1683:4;1675:6;1671:17;1667:27;1657:2;;1708:1;1705;1698:12;1657:2;1748:6;1735:20;1773:79;1848:3;1840:6;1833:4;1825:6;1821:17;1773:79;:::i;:::-;1764:88;;1647:211;;;;;:::o;1864:139::-;1910:5;1948:6;1935:20;1926:29;;1964:33;1991:5;1964:33;:::i;:::-;1916:87;;;;:::o;2009:262::-;2068:6;2117:2;2105:9;2096:7;2092:23;2088:32;2085:2;;;2133:1;2130;2123:12;2085:2;2176:1;2201:53;2246:7;2237:6;2226:9;2222:22;2201:53;:::i;:::-;2191:63;;2147:117;2075:196;;;;:::o;2277:407::-;2345:6;2353;2402:2;2390:9;2381:7;2377:23;2373:32;2370:2;;;2418:1;2415;2408:12;2370:2;2461:1;2486:53;2531:7;2522:6;2511:9;2507:22;2486:53;:::i;:::-;2476:63;;2432:117;2588:2;2614:53;2659:7;2650:6;2639:9;2635:22;2614:53;:::i;:::-;2604:63;;2559:118;2360:324;;;;;:::o;2690:552::-;2767:6;2775;2783;2832:2;2820:9;2811:7;2807:23;2803:32;2800:2;;;2848:1;2845;2838:12;2800:2;2891:1;2916:53;2961:7;2952:6;2941:9;2937:22;2916:53;:::i;:::-;2906:63;;2862:117;3018:2;3044:53;3089:7;3080:6;3069:9;3065:22;3044:53;:::i;:::-;3034:63;;2989:118;3146:2;3172:53;3217:7;3208:6;3197:9;3193:22;3172:53;:::i;:::-;3162:63;;3117:118;2790:452;;;;;:::o;3248:809::-;3343:6;3351;3359;3367;3416:3;3404:9;3395:7;3391:23;3387:33;3384:2;;;3433:1;3430;3423:12;3384:2;3476:1;3501:53;3546:7;3537:6;3526:9;3522:22;3501:53;:::i;:::-;3491:63;;3447:117;3603:2;3629:53;3674:7;3665:6;3654:9;3650:22;3629:53;:::i;:::-;3619:63;;3574:118;3731:2;3757:53;3802:7;3793:6;3782:9;3778:22;3757:53;:::i;:::-;3747:63;;3702:118;3887:2;3876:9;3872:18;3859:32;3918:18;3910:6;3907:30;3904:2;;;3950:1;3947;3940:12;3904:2;3978:62;4032:7;4023:6;4012:9;4008:22;3978:62;:::i;:::-;3968:72;;3830:220;3374:683;;;;;;;:::o;4063:401::-;4128:6;4136;4185:2;4173:9;4164:7;4160:23;4156:32;4153:2;;;4201:1;4198;4191:12;4153:2;4244:1;4269:53;4314:7;4305:6;4294:9;4290:22;4269:53;:::i;:::-;4259:63;;4215:117;4371:2;4397:50;4439:7;4430:6;4419:9;4415:22;4397:50;:::i;:::-;4387:60;;4342:115;4143:321;;;;;:::o;4470:407::-;4538:6;4546;4595:2;4583:9;4574:7;4570:23;4566:32;4563:2;;;4611:1;4608;4601:12;4563:2;4654:1;4679:53;4724:7;4715:6;4704:9;4700:22;4679:53;:::i;:::-;4669:63;;4625:117;4781:2;4807:53;4852:7;4843:6;4832:9;4828:22;4807:53;:::i;:::-;4797:63;;4752:118;4553:324;;;;;:::o;4883:260::-;4941:6;4990:2;4978:9;4969:7;4965:23;4961:32;4958:2;;;5006:1;5003;4996:12;4958:2;5049:1;5074:52;5118:7;5109:6;5098:9;5094:22;5074:52;:::i;:::-;5064:62;;5020:116;4948:195;;;;:::o;5149:282::-;5218:6;5267:2;5255:9;5246:7;5242:23;5238:32;5235:2;;;5283:1;5280;5273:12;5235:2;5326:1;5351:63;5406:7;5397:6;5386:9;5382:22;5351:63;:::i;:::-;5341:73;;5297:127;5225:206;;;;:::o;5437:375::-;5506:6;5555:2;5543:9;5534:7;5530:23;5526:32;5523:2;;;5571:1;5568;5561:12;5523:2;5642:1;5631:9;5627:17;5614:31;5672:18;5664:6;5661:30;5658:2;;;5704:1;5701;5694:12;5658:2;5732:63;5787:7;5778:6;5767:9;5763:22;5732:63;:::i;:::-;5722:73;;5585:220;5513:299;;;;:::o;5818:262::-;5877:6;5926:2;5914:9;5905:7;5901:23;5897:32;5894:2;;;5942:1;5939;5932:12;5894:2;5985:1;6010:53;6055:7;6046:6;6035:9;6031:22;6010:53;:::i;:::-;6000:63;;5956:117;5884:196;;;;:::o;6086:179::-;6155:10;6176:46;6218:3;6210:6;6176:46;:::i;:::-;6254:4;6249:3;6245:14;6231:28;;6166:99;;;;:::o;6271:118::-;6358:24;6376:5;6358:24;:::i;:::-;6353:3;6346:37;6336:53;;:::o;6425:732::-;6544:3;6573:54;6621:5;6573:54;:::i;:::-;6643:86;6722:6;6717:3;6643:86;:::i;:::-;6636:93;;6753:56;6803:5;6753:56;:::i;:::-;6832:7;6863:1;6848:284;6873:6;6870:1;6867:13;6848:284;;;6949:6;6943:13;6976:63;7035:3;7020:13;6976:63;:::i;:::-;6969:70;;7062:60;7115:6;7062:60;:::i;:::-;7052:70;;6908:224;6895:1;6892;6888:9;6883:14;;6848:284;;;6852:14;7148:3;7141:10;;6549:608;;;;;;;:::o;7163:109::-;7244:21;7259:5;7244:21;:::i;:::-;7239:3;7232:34;7222:50;;:::o;7278:360::-;7364:3;7392:38;7424:5;7392:38;:::i;:::-;7446:70;7509:6;7504:3;7446:70;:::i;:::-;7439:77;;7525:52;7570:6;7565:3;7558:4;7551:5;7547:16;7525:52;:::i;:::-;7602:29;7624:6;7602:29;:::i;:::-;7597:3;7593:39;7586:46;;7368:270;;;;;:::o;7644:373::-;7748:3;7776:38;7808:5;7776:38;:::i;:::-;7830:88;7911:6;7906:3;7830:88;:::i;:::-;7823:95;;7927:52;7972:6;7967:3;7960:4;7953:5;7949:16;7927:52;:::i;:::-;8004:6;7999:3;7995:16;7988:23;;7752:265;;;;;:::o;8023:364::-;8111:3;8139:39;8172:5;8139:39;:::i;:::-;8194:71;8258:6;8253:3;8194:71;:::i;:::-;8187:78;;8274:52;8319:6;8314:3;8307:4;8300:5;8296:16;8274:52;:::i;:::-;8351:29;8373:6;8351:29;:::i;:::-;8346:3;8342:39;8335:46;;8115:272;;;;;:::o;8393:377::-;8499:3;8527:39;8560:5;8527:39;:::i;:::-;8582:89;8664:6;8659:3;8582:89;:::i;:::-;8575:96;;8680:52;8725:6;8720:3;8713:4;8706:5;8702:16;8680:52;:::i;:::-;8757:6;8752:3;8748:16;8741:23;;8503:267;;;;;:::o;8776:366::-;8918:3;8939:67;9003:2;8998:3;8939:67;:::i;:::-;8932:74;;9015:93;9104:3;9015:93;:::i;:::-;9133:2;9128:3;9124:12;9117:19;;8922:220;;;:::o;9148:366::-;9290:3;9311:67;9375:2;9370:3;9311:67;:::i;:::-;9304:74;;9387:93;9476:3;9387:93;:::i;:::-;9505:2;9500:3;9496:12;9489:19;;9294:220;;;:::o;9520:366::-;9662:3;9683:67;9747:2;9742:3;9683:67;:::i;:::-;9676:74;;9759:93;9848:3;9759:93;:::i;:::-;9877:2;9872:3;9868:12;9861:19;;9666:220;;;:::o;9892:366::-;10034:3;10055:67;10119:2;10114:3;10055:67;:::i;:::-;10048:74;;10131:93;10220:3;10131:93;:::i;:::-;10249:2;10244:3;10240:12;10233:19;;10038:220;;;:::o;10264:366::-;10406:3;10427:67;10491:2;10486:3;10427:67;:::i;:::-;10420:74;;10503:93;10592:3;10503:93;:::i;:::-;10621:2;10616:3;10612:12;10605:19;;10410:220;;;:::o;10636:366::-;10778:3;10799:67;10863:2;10858:3;10799:67;:::i;:::-;10792:74;;10875:93;10964:3;10875:93;:::i;:::-;10993:2;10988:3;10984:12;10977:19;;10782:220;;;:::o;11008:366::-;11150:3;11171:67;11235:2;11230:3;11171:67;:::i;:::-;11164:74;;11247:93;11336:3;11247:93;:::i;:::-;11365:2;11360:3;11356:12;11349:19;;11154:220;;;:::o;11380:366::-;11522:3;11543:67;11607:2;11602:3;11543:67;:::i;:::-;11536:74;;11619:93;11708:3;11619:93;:::i;:::-;11737:2;11732:3;11728:12;11721:19;;11526:220;;;:::o;11752:366::-;11894:3;11915:67;11979:2;11974:3;11915:67;:::i;:::-;11908:74;;11991:93;12080:3;11991:93;:::i;:::-;12109:2;12104:3;12100:12;12093:19;;11898:220;;;:::o;12124:366::-;12266:3;12287:67;12351:2;12346:3;12287:67;:::i;:::-;12280:74;;12363:93;12452:3;12363:93;:::i;:::-;12481:2;12476:3;12472:12;12465:19;;12270:220;;;:::o;12496:366::-;12638:3;12659:67;12723:2;12718:3;12659:67;:::i;:::-;12652:74;;12735:93;12824:3;12735:93;:::i;:::-;12853:2;12848:3;12844:12;12837:19;;12642:220;;;:::o;12868:366::-;13010:3;13031:67;13095:2;13090:3;13031:67;:::i;:::-;13024:74;;13107:93;13196:3;13107:93;:::i;:::-;13225:2;13220:3;13216:12;13209:19;;13014:220;;;:::o;13240:366::-;13382:3;13403:67;13467:2;13462:3;13403:67;:::i;:::-;13396:74;;13479:93;13568:3;13479:93;:::i;:::-;13597:2;13592:3;13588:12;13581:19;;13386:220;;;:::o;13612:366::-;13754:3;13775:67;13839:2;13834:3;13775:67;:::i;:::-;13768:74;;13851:93;13940:3;13851:93;:::i;:::-;13969:2;13964:3;13960:12;13953:19;;13758:220;;;:::o;13984:366::-;14126:3;14147:67;14211:2;14206:3;14147:67;:::i;:::-;14140:74;;14223:93;14312:3;14223:93;:::i;:::-;14341:2;14336:3;14332:12;14325:19;;14130:220;;;:::o;14356:366::-;14498:3;14519:67;14583:2;14578:3;14519:67;:::i;:::-;14512:74;;14595:93;14684:3;14595:93;:::i;:::-;14713:2;14708:3;14704:12;14697:19;;14502:220;;;:::o;14728:366::-;14870:3;14891:67;14955:2;14950:3;14891:67;:::i;:::-;14884:74;;14967:93;15056:3;14967:93;:::i;:::-;15085:2;15080:3;15076:12;15069:19;;14874:220;;;:::o;15100:366::-;15242:3;15263:67;15327:2;15322:3;15263:67;:::i;:::-;15256:74;;15339:93;15428:3;15339:93;:::i;:::-;15457:2;15452:3;15448:12;15441:19;;15246:220;;;:::o;15472:366::-;15614:3;15635:67;15699:2;15694:3;15635:67;:::i;:::-;15628:74;;15711:93;15800:3;15711:93;:::i;:::-;15829:2;15824:3;15820:12;15813:19;;15618:220;;;:::o;15844:366::-;15986:3;16007:67;16071:2;16066:3;16007:67;:::i;:::-;16000:74;;16083:93;16172:3;16083:93;:::i;:::-;16201:2;16196:3;16192:12;16185:19;;15990:220;;;:::o;16216:366::-;16358:3;16379:67;16443:2;16438:3;16379:67;:::i;:::-;16372:74;;16455:93;16544:3;16455:93;:::i;:::-;16573:2;16568:3;16564:12;16557:19;;16362:220;;;:::o;16588:366::-;16730:3;16751:67;16815:2;16810:3;16751:67;:::i;:::-;16744:74;;16827:93;16916:3;16827:93;:::i;:::-;16945:2;16940:3;16936:12;16929:19;;16734:220;;;:::o;16960:366::-;17102:3;17123:67;17187:2;17182:3;17123:67;:::i;:::-;17116:74;;17199:93;17288:3;17199:93;:::i;:::-;17317:2;17312:3;17308:12;17301:19;;17106:220;;;:::o;17332:366::-;17474:3;17495:67;17559:2;17554:3;17495:67;:::i;:::-;17488:74;;17571:93;17660:3;17571:93;:::i;:::-;17689:2;17684:3;17680:12;17673:19;;17478:220;;;:::o;17704:108::-;17781:24;17799:5;17781:24;:::i;:::-;17776:3;17769:37;17759:53;;:::o;17818:118::-;17905:24;17923:5;17905:24;:::i;:::-;17900:3;17893:37;17883:53;;:::o;17942:271::-;18072:3;18094:93;18183:3;18174:6;18094:93;:::i;:::-;18087:100;;18204:3;18197:10;;18076:137;;;;:::o;18219:435::-;18399:3;18421:95;18512:3;18503:6;18421:95;:::i;:::-;18414:102;;18533:95;18624:3;18615:6;18533:95;:::i;:::-;18526:102;;18645:3;18638:10;;18403:251;;;;;:::o;18660:222::-;18753:4;18791:2;18780:9;18776:18;18768:26;;18804:71;18872:1;18861:9;18857:17;18848:6;18804:71;:::i;:::-;18758:124;;;;:::o;18888:640::-;19083:4;19121:3;19110:9;19106:19;19098:27;;19135:71;19203:1;19192:9;19188:17;19179:6;19135:71;:::i;:::-;19216:72;19284:2;19273:9;19269:18;19260:6;19216:72;:::i;:::-;19298;19366:2;19355:9;19351:18;19342:6;19298:72;:::i;:::-;19417:9;19411:4;19407:20;19402:2;19391:9;19387:18;19380:48;19445:76;19516:4;19507:6;19445:76;:::i;:::-;19437:84;;19088:440;;;;;;;:::o;19534:373::-;19677:4;19715:2;19704:9;19700:18;19692:26;;19764:9;19758:4;19754:20;19750:1;19739:9;19735:17;19728:47;19792:108;19895:4;19886:6;19792:108;:::i;:::-;19784:116;;19682:225;;;;:::o;19913:210::-;20000:4;20038:2;20027:9;20023:18;20015:26;;20051:65;20113:1;20102:9;20098:17;20089:6;20051:65;:::i;:::-;20005:118;;;;:::o;20129:313::-;20242:4;20280:2;20269:9;20265:18;20257:26;;20329:9;20323:4;20319:20;20315:1;20304:9;20300:17;20293:47;20357:78;20430:4;20421:6;20357:78;:::i;:::-;20349:86;;20247:195;;;;:::o;20448:419::-;20614:4;20652:2;20641:9;20637:18;20629:26;;20701:9;20695:4;20691:20;20687:1;20676:9;20672:17;20665:47;20729:131;20855:4;20729:131;:::i;:::-;20721:139;;20619:248;;;:::o;20873:419::-;21039:4;21077:2;21066:9;21062:18;21054:26;;21126:9;21120:4;21116:20;21112:1;21101:9;21097:17;21090:47;21154:131;21280:4;21154:131;:::i;:::-;21146:139;;21044:248;;;:::o;21298:419::-;21464:4;21502:2;21491:9;21487:18;21479:26;;21551:9;21545:4;21541:20;21537:1;21526:9;21522:17;21515:47;21579:131;21705:4;21579:131;:::i;:::-;21571:139;;21469:248;;;:::o;21723:419::-;21889:4;21927:2;21916:9;21912:18;21904:26;;21976:9;21970:4;21966:20;21962:1;21951:9;21947:17;21940:47;22004:131;22130:4;22004:131;:::i;:::-;21996:139;;21894:248;;;:::o;22148:419::-;22314:4;22352:2;22341:9;22337:18;22329:26;;22401:9;22395:4;22391:20;22387:1;22376:9;22372:17;22365:47;22429:131;22555:4;22429:131;:::i;:::-;22421:139;;22319:248;;;:::o;22573:419::-;22739:4;22777:2;22766:9;22762:18;22754:26;;22826:9;22820:4;22816:20;22812:1;22801:9;22797:17;22790:47;22854:131;22980:4;22854:131;:::i;:::-;22846:139;;22744:248;;;:::o;22998:419::-;23164:4;23202:2;23191:9;23187:18;23179:26;;23251:9;23245:4;23241:20;23237:1;23226:9;23222:17;23215:47;23279:131;23405:4;23279:131;:::i;:::-;23271:139;;23169:248;;;:::o;23423:419::-;23589:4;23627:2;23616:9;23612:18;23604:26;;23676:9;23670:4;23666:20;23662:1;23651:9;23647:17;23640:47;23704:131;23830:4;23704:131;:::i;:::-;23696:139;;23594:248;;;:::o;23848:419::-;24014:4;24052:2;24041:9;24037:18;24029:26;;24101:9;24095:4;24091:20;24087:1;24076:9;24072:17;24065:47;24129:131;24255:4;24129:131;:::i;:::-;24121:139;;24019:248;;;:::o;24273:419::-;24439:4;24477:2;24466:9;24462:18;24454:26;;24526:9;24520:4;24516:20;24512:1;24501:9;24497:17;24490:47;24554:131;24680:4;24554:131;:::i;:::-;24546:139;;24444:248;;;:::o;24698:419::-;24864:4;24902:2;24891:9;24887:18;24879:26;;24951:9;24945:4;24941:20;24937:1;24926:9;24922:17;24915:47;24979:131;25105:4;24979:131;:::i;:::-;24971:139;;24869:248;;;:::o;25123:419::-;25289:4;25327:2;25316:9;25312:18;25304:26;;25376:9;25370:4;25366:20;25362:1;25351:9;25347:17;25340:47;25404:131;25530:4;25404:131;:::i;:::-;25396:139;;25294:248;;;:::o;25548:419::-;25714:4;25752:2;25741:9;25737:18;25729:26;;25801:9;25795:4;25791:20;25787:1;25776:9;25772:17;25765:47;25829:131;25955:4;25829:131;:::i;:::-;25821:139;;25719:248;;;:::o;25973:419::-;26139:4;26177:2;26166:9;26162:18;26154:26;;26226:9;26220:4;26216:20;26212:1;26201:9;26197:17;26190:47;26254:131;26380:4;26254:131;:::i;:::-;26246:139;;26144:248;;;:::o;26398:419::-;26564:4;26602:2;26591:9;26587:18;26579:26;;26651:9;26645:4;26641:20;26637:1;26626:9;26622:17;26615:47;26679:131;26805:4;26679:131;:::i;:::-;26671:139;;26569:248;;;:::o;26823:419::-;26989:4;27027:2;27016:9;27012:18;27004:26;;27076:9;27070:4;27066:20;27062:1;27051:9;27047:17;27040:47;27104:131;27230:4;27104:131;:::i;:::-;27096:139;;26994:248;;;:::o;27248:419::-;27414:4;27452:2;27441:9;27437:18;27429:26;;27501:9;27495:4;27491:20;27487:1;27476:9;27472:17;27465:47;27529:131;27655:4;27529:131;:::i;:::-;27521:139;;27419:248;;;:::o;27673:419::-;27839:4;27877:2;27866:9;27862:18;27854:26;;27926:9;27920:4;27916:20;27912:1;27901:9;27897:17;27890:47;27954:131;28080:4;27954:131;:::i;:::-;27946:139;;27844:248;;;:::o;28098:419::-;28264:4;28302:2;28291:9;28287:18;28279:26;;28351:9;28345:4;28341:20;28337:1;28326:9;28322:17;28315:47;28379:131;28505:4;28379:131;:::i;:::-;28371:139;;28269:248;;;:::o;28523:419::-;28689:4;28727:2;28716:9;28712:18;28704:26;;28776:9;28770:4;28766:20;28762:1;28751:9;28747:17;28740:47;28804:131;28930:4;28804:131;:::i;:::-;28796:139;;28694:248;;;:::o;28948:419::-;29114:4;29152:2;29141:9;29137:18;29129:26;;29201:9;29195:4;29191:20;29187:1;29176:9;29172:17;29165:47;29229:131;29355:4;29229:131;:::i;:::-;29221:139;;29119:248;;;:::o;29373:419::-;29539:4;29577:2;29566:9;29562:18;29554:26;;29626:9;29620:4;29616:20;29612:1;29601:9;29597:17;29590:47;29654:131;29780:4;29654:131;:::i;:::-;29646:139;;29544:248;;;:::o;29798:419::-;29964:4;30002:2;29991:9;29987:18;29979:26;;30051:9;30045:4;30041:20;30037:1;30026:9;30022:17;30015:47;30079:131;30205:4;30079:131;:::i;:::-;30071:139;;29969:248;;;:::o;30223:419::-;30389:4;30427:2;30416:9;30412:18;30404:26;;30476:9;30470:4;30466:20;30462:1;30451:9;30447:17;30440:47;30504:131;30630:4;30504:131;:::i;:::-;30496:139;;30394:248;;;:::o;30648:222::-;30741:4;30779:2;30768:9;30764:18;30756:26;;30792:71;30860:1;30849:9;30845:17;30836:6;30792:71;:::i;:::-;30746:124;;;;:::o;30876:129::-;30910:6;30937:20;;:::i;:::-;30927:30;;30966:33;30994:4;30986:6;30966:33;:::i;:::-;30917:88;;;:::o;31011:75::-;31044:6;31077:2;31071:9;31061:19;;31051:35;:::o;31092:307::-;31153:4;31243:18;31235:6;31232:30;31229:2;;;31265:18;;:::i;:::-;31229:2;31303:29;31325:6;31303:29;:::i;:::-;31295:37;;31387:4;31381;31377:15;31369:23;;31158:241;;;:::o;31405:308::-;31467:4;31557:18;31549:6;31546:30;31543:2;;;31579:18;;:::i;:::-;31543:2;31617:29;31639:6;31617:29;:::i;:::-;31609:37;;31701:4;31695;31691:15;31683:23;;31472:241;;;:::o;31719:132::-;31786:4;31809:3;31801:11;;31839:4;31834:3;31830:14;31822:22;;31791:60;;;:::o;31857:114::-;31924:6;31958:5;31952:12;31942:22;;31931:40;;;:::o;31977:98::-;32028:6;32062:5;32056:12;32046:22;;32035:40;;;:::o;32081:99::-;32133:6;32167:5;32161:12;32151:22;;32140:40;;;:::o;32186:113::-;32256:4;32288;32283:3;32279:14;32271:22;;32261:38;;;:::o;32305:184::-;32404:11;32438:6;32433:3;32426:19;32478:4;32473:3;32469:14;32454:29;;32416:73;;;;:::o;32495:168::-;32578:11;32612:6;32607:3;32600:19;32652:4;32647:3;32643:14;32628:29;;32590:73;;;;:::o;32669:147::-;32770:11;32807:3;32792:18;;32782:34;;;;:::o;32822:169::-;32906:11;32940:6;32935:3;32928:19;32980:4;32975:3;32971:14;32956:29;;32918:73;;;;:::o;32997:148::-;33099:11;33136:3;33121:18;;33111:34;;;;:::o;33151:305::-;33191:3;33210:20;33228:1;33210:20;:::i;:::-;33205:25;;33244:20;33262:1;33244:20;:::i;:::-;33239:25;;33398:1;33330:66;33326:74;33323:1;33320:81;33317:2;;;33404:18;;:::i;:::-;33317:2;33448:1;33445;33441:9;33434:16;;33195:261;;;;:::o;33462:185::-;33502:1;33519:20;33537:1;33519:20;:::i;:::-;33514:25;;33553:20;33571:1;33553:20;:::i;:::-;33548:25;;33592:1;33582:2;;33597:18;;:::i;:::-;33582:2;33639:1;33636;33632:9;33627:14;;33504:143;;;;:::o;33653:348::-;33693:7;33716:20;33734:1;33716:20;:::i;:::-;33711:25;;33750:20;33768:1;33750:20;:::i;:::-;33745:25;;33938:1;33870:66;33866:74;33863:1;33860:81;33855:1;33848:9;33841:17;33837:105;33834:2;;;33945:18;;:::i;:::-;33834:2;33993:1;33990;33986:9;33975:20;;33701:300;;;;:::o;34007:191::-;34047:4;34067:20;34085:1;34067:20;:::i;:::-;34062:25;;34101:20;34119:1;34101:20;:::i;:::-;34096:25;;34140:1;34137;34134:8;34131:2;;;34145:18;;:::i;:::-;34131:2;34190:1;34187;34183:9;34175:17;;34052:146;;;;:::o;34204:96::-;34241:7;34270:24;34288:5;34270:24;:::i;:::-;34259:35;;34249:51;;;:::o;34306:90::-;34340:7;34383:5;34376:13;34369:21;34358:32;;34348:48;;;:::o;34402:149::-;34438:7;34478:66;34471:5;34467:78;34456:89;;34446:105;;;:::o;34557:126::-;34594:7;34634:42;34627:5;34623:54;34612:65;;34602:81;;;:::o;34689:77::-;34726:7;34755:5;34744:16;;34734:32;;;:::o;34772:154::-;34856:6;34851:3;34846;34833:30;34918:1;34909:6;34904:3;34900:16;34893:27;34823:103;;;:::o;34932:307::-;35000:1;35010:113;35024:6;35021:1;35018:13;35010:113;;;35109:1;35104:3;35100:11;35094:18;35090:1;35085:3;35081:11;35074:39;35046:2;35043:1;35039:10;35034:15;;35010:113;;;35141:6;35138:1;35135:13;35132:2;;;35221:1;35212:6;35207:3;35203:16;35196:27;35132:2;34981:258;;;;:::o;35245:320::-;35289:6;35326:1;35320:4;35316:12;35306:22;;35373:1;35367:4;35363:12;35394:18;35384:2;;35450:4;35442:6;35438:17;35428:27;;35384:2;35512;35504:6;35501:14;35481:18;35478:38;35475:2;;;35531:18;;:::i;:::-;35475:2;35296:269;;;;:::o;35571:281::-;35654:27;35676:4;35654:27;:::i;:::-;35646:6;35642:40;35784:6;35772:10;35769:22;35748:18;35736:10;35733:34;35730:62;35727:2;;;35795:18;;:::i;:::-;35727:2;35835:10;35831:2;35824:22;35614:238;;;:::o;35858:233::-;35897:3;35920:24;35938:5;35920:24;:::i;:::-;35911:33;;35966:66;35959:5;35956:77;35953:2;;;36036:18;;:::i;:::-;35953:2;36083:1;36076:5;36072:13;36065:20;;35901:190;;;:::o;36097:176::-;36129:1;36146:20;36164:1;36146:20;:::i;:::-;36141:25;;36180:20;36198:1;36180:20;:::i;:::-;36175:25;;36219:1;36209:2;;36224:18;;:::i;:::-;36209:2;36265:1;36262;36258:9;36253:14;;36131:142;;;;:::o;36279:180::-;36327:77;36324:1;36317:88;36424:4;36421:1;36414:15;36448:4;36445:1;36438:15;36465:180;36513:77;36510:1;36503:88;36610:4;36607:1;36600:15;36634:4;36631:1;36624:15;36651:180;36699:77;36696:1;36689:88;36796:4;36793:1;36786:15;36820:4;36817:1;36810:15;36837:180;36885:77;36882:1;36875:88;36982:4;36979:1;36972:15;37006:4;37003:1;36996:15;37023:102;37064:6;37115:2;37111:7;37106:2;37099:5;37095:14;37091:28;37081:38;;37071:54;;;:::o;37131:221::-;37271:34;37267:1;37259:6;37255:14;37248:58;37340:4;37335:2;37327:6;37323:15;37316:29;37237:115;:::o;37358:237::-;37498:34;37494:1;37486:6;37482:14;37475:58;37567:20;37562:2;37554:6;37550:15;37543:45;37464:131;:::o;37601:225::-;37741:34;37737:1;37729:6;37725:14;37718:58;37810:8;37805:2;37797:6;37793:15;37786:33;37707:119;:::o;37832:178::-;37972:30;37968:1;37960:6;37956:14;37949:54;37938:72;:::o;38016:172::-;38156:24;38152:1;38144:6;38140:14;38133:48;38122:66;:::o;38194:223::-;38334:34;38330:1;38322:6;38318:14;38311:58;38403:6;38398:2;38390:6;38386:15;38379:31;38300:117;:::o;38423:175::-;38563:27;38559:1;38551:6;38547:14;38540:51;38529:69;:::o;38604:181::-;38744:33;38740:1;38732:6;38728:14;38721:57;38710:75;:::o;38791:177::-;38931:29;38927:1;38919:6;38915:14;38908:53;38897:71;:::o;38974:231::-;39114:34;39110:1;39102:6;39098:14;39091:58;39183:14;39178:2;39170:6;39166:15;39159:39;39080:125;:::o;39211:179::-;39351:31;39347:1;39339:6;39335:14;39328:55;39317:73;:::o;39396:243::-;39536:34;39532:1;39524:6;39520:14;39513:58;39605:26;39600:2;39592:6;39588:15;39581:51;39502:137;:::o;39645:228::-;39785:34;39781:1;39773:6;39769:14;39762:58;39854:11;39849:2;39841:6;39837:15;39830:36;39751:122;:::o;39879:229::-;40019:34;40015:1;40007:6;40003:14;39996:58;40088:12;40083:2;40075:6;40071:15;40064:37;39985:123;:::o;40114:182::-;40254:34;40250:1;40242:6;40238:14;40231:58;40220:76;:::o;40302:231::-;40442:34;40438:1;40430:6;40426:14;40419:58;40511:14;40506:2;40498:6;40494:15;40487:39;40408:125;:::o;40539:182::-;40679:34;40675:1;40667:6;40663:14;40656:58;40645:76;:::o;40727:228::-;40867:34;40863:1;40855:6;40851:14;40844:58;40936:11;40931:2;40923:6;40919:15;40912:36;40833:122;:::o;40961:234::-;41101:34;41097:1;41089:6;41085:14;41078:58;41170:17;41165:2;41157:6;41153:15;41146:42;41067:128;:::o;41201:220::-;41341:34;41337:1;41329:6;41325:14;41318:58;41410:3;41405:2;41397:6;41393:15;41386:28;41307:114;:::o;41427:172::-;41567:24;41563:1;41555:6;41551:14;41544:48;41533:66;:::o;41605:174::-;41745:26;41741:1;41733:6;41729:14;41722:50;41711:68;:::o;41785:182::-;41925:34;41921:1;41913:6;41909:14;41902:58;41891:76;:::o;41973:236::-;42113:34;42109:1;42101:6;42097:14;42090:58;42182:19;42177:2;42169:6;42165:15;42158:44;42079:130;:::o;42215:122::-;42288:24;42306:5;42288:24;:::i;:::-;42281:5;42278:35;42268:2;;42327:1;42324;42317:12;42268:2;42258:79;:::o;42343:116::-;42413:21;42428:5;42413:21;:::i;:::-;42406:5;42403:32;42393:2;;42449:1;42446;42439:12;42393:2;42383:76;:::o;42465:120::-;42537:23;42554:5;42537:23;:::i;:::-;42530:5;42527:34;42517:2;;42575:1;42572;42565:12;42517:2;42507:78;:::o;42591:122::-;42664:24;42682:5;42664:24;:::i;:::-;42657:5;42654:35;42644:2;;42703:1;42700;42693:12;42644:2;42634:79;:::o

Swarm Source

ipfs://062f15ad73324cc34744ab1c4c010ae0fb3ebdbb79ea5b51dd990e81bb0e7418
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.