ETH Price: $3,336.19 (-1.22%)
Gas: 5.83 Gwei

Token

FRYCOOKS (FRYCOOK)
 

Overview

Max Total Supply

2,214 FRYCOOK

Holders

985

Market

Volume (24H)

N/A

Min Price (24H)

N/A

Max Price (24H)

N/A
Balance
1 FRYCOOK
0x1f2091d9d5d79d0b0d4752cd458c08920e80e814
Loading...
Loading
Loading...
Loading
Loading...
Loading

OVERVIEW

SUDOBURGER presents FRYCOOKs entry point into the SUDOBURGER universe. Each FRYCOOK features close to two dozen attributes classes in 1-of-1 configurations, painstakingly-handcrafted in a 3D environment.

# Exchange Pair Price  24H Volume % Volume

Contract Source Code Verified (Exact Match)

Contract Name:
FRYCOOKS

Compiler Version
v0.8.0+commit.c7dfd78e

Optimization Enabled:
No with 200 runs

Other Settings:
default evmVersion, None license

Contract Source Code (Solidity)

/**
 *Submitted for verification at Etherscan.io on 2021-09-11
*/

// File: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/utils/Strings.sol

// SPDX-License-Identifier: MIT

    //                                 ██▓▓████████████████████                                        
    //                           ██████▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░▒▒██████                                  
    //                         ██░░▒▒▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒████                              
    //                       ██░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒▒▒▒████                          
    //                     ██░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒████                      
    //                   ██░░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░░░▒▒▒▒▒▒██                    
    //                 ██░░░░░░░░░░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██                  
    //                 ██░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░██                
    //             ████▒▒████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒░░██                
    //           ██▒▒░░▒▒▒▒▒▒██████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░▒▒▒▒▒▒▒▒▒▒▒▒░░░░░░██              
    //         ▓▓░░░░░░░░▒▒▒▒▒▒▒▒▒▒████▓▓██▓▓░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░██              
    //         ████▒▒▒▒▒▒░░░░▒▒▒▒░░▒▒▒▒▒▒▒▒▒▒██████████░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░░██              
    //             ██▒▒░░░░▒▒▒▒▒▒░░░░▒▒▒▒▒▒▒▒▒▒░░▒▒▒▒▒▒████████░░░░░░░░░░░░░░░░░░░░░░░░██              
    //           ▓▓▒▒░░░░░░▒▒▒▒░░░░░░▒▒▒▒░░░░░░░░▒▒▒▒░░▒▒▒▒▒▒▒▒██▓▓██▓▓░░░░░░░░░░░░░░░░██▒▒▓▓▓▓        
    //           ██▒▒░░▒▒▒▒▒▒░░░░▒▒▒▒▒▒▒▒░░░░░░▒▒▒▒▒▒░░░░░░▒▒▒▒▒▒░░▒▒▒▒████░░░░░░░░░░██░░░░░░░░██      
    //             ████████████████▒▒▒▒██████▒▒▒▒▒▒▒▒░░░░░░▒▒▒▒▒▒░░░░▒▒▒▒▒▒██████████▒▒▒▒▒▒░░░░██      
    //               ████▒▒▓▓▓▓▓▓▓▓████▓▓▓▓██▒▒▒▒▒▒▒▒████████▒▒▒▒░░░░██▒▒▒▒▒▒░░░░▒▒▒▒░░░░▒▒▒▒██        
    //             ██▒▒██▒▒▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓████████▓▓▓▓▓▓▓▓██▒▒░░██▓▓██▒▒▒▒░░░░▒▒▒▒▒▒░░░░██          
    //           ██▒▒▒▒▒▒████▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓▓▓▓▓██▒▒██▒▒▒▒▓▓▓▓████▓▓▓▓██▒▒▒▒░░░░████▒▒░░░░░░██        
    //           ██▒▒▒▒▒▒▒▒▒▒██▓▓▓▓██▒▒▒▒▒▒▒▒████▒▒▒▒▒▒▓▓▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓██▒▒░░▓▓▒▒▒▒████▒▒▓▓██        
    //         ██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒████████▒▒▒▒▒▒▒▒▒▒▒▒██████████▒▒▒▒▒▒▒▒████▒▒▒▒▒▒▒▒▒▒██▒▒▒▒██      
    //     ██████▒▒▒▒██████▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██████████▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒████  
    //   ██▒▒▒▒▒▒████▒▒▒▒▒▒██▒▒▒▒▒▒▒▒▒▒██████▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██████▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██
    // ██▒▒▒▒▒▒▒▒▓▓▒▒▒▒▒▒▒▒▒▒██▒▒▒▒████▓▓▓▓▓▓████▒▒▒▒▒▒██████▓▓▓▓██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██████▓▓▒▒▒▒▒▒▒▒██
    // ████▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒████▓▓▓▓▓▓▒▒▓▓▓▓▓▓██████▓▓▓▓▓▓▒▒▒▒▓▓██▒▒▒▒▒▒▒▒▒▒██████▓▓▓▓██  ██████▒▒██
    //     ████▓▓██▒▒▒▒▒▒▒▒▒▒████▓▓▓▓▓▓▓▓▒▒▓▓▓▓▓▓▓▓▓▓▓▓▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓████████▓▓▓▓▓▓████░░██      ██  
    //           ██▒▒▒▒▒▒████░░░░████████▒▒▒▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▒▒▓▓▓▓▓▓▓▓▒▒▓▓████░░░░██          
    //           ████████▓▓██░░░░░░░░░░░░████████████████████████▓▓▓▓██████▓▓▓▓▓▓██░░██░░░░██          
    //               ██▓▓▓▓▓▓██░░░░░░░░░░░░░░░░░░░░░░░░██▓▓▓▓▓▓▓▓████▓▓▓▓▓▓██████░░░░██░░░░██          
    //               ██▓▓▒▒▓▓▓▓▓▓░░░░░░░░░░░░░░░░░░▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓██░░░░▒▒▒▒██░░██          
    //                 ████████████░░░░░░░░░░░░████▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓████████░░░░▒▒▒▒▒▒████            
    //               ██▒▒▒▒▒▒░░░░░░██░░░░░░████░░░░██████████████████░░░░██░░░░▒▒▒▒▒▒▒▒██              
    //               ██▒▒▒▒▒▒▒▒▒▒░░▒▒▓▓░░██░░░░░░░░░░░░░░████░░░░░░░░░░▓▓░░▒▒▒▒▒▒▒▒▒▒██                
    //               ██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██▓▓░░░░██▒▒▒▒▒▒▒▒▒▒▒▒▒▒██                
    //                 ██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒████▒▒▒▒▒▒▒▒▒▒▒▒▒▒██                  
    //                 ░░▓▓██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▓▓██░░                  
    //                       ████▓▓██▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒▒██████▓▓                        
    //                               ██████████████████████████████████                  

// NhhdNNNNNNNNNNNNNNNMNhhNMMMMMMMMmhhhhdMMMMMMMMMddMMMMMMMMMMMMMMMMMMMMNdhhhhhdMmdddddddddddddddddNNhN
// moyo/:::::::::::::::+doy::::::::m....h+-------/dm:-------------------:oy/..ss:-.................-+hN
// Mo..................-moo........N....h:.......:dm-.....................-d-/h....................../M
// M...................-moo........N....h:.......:dd-......................y++s......................-M
// N.........----------:dos........m....h/.......:dd-.......-:::::-........yo+s........:+++++-.......-M
// N......../y+++++++++o/os........m....h/.......:dd-......./h++++h........so+s........d/:::h/.......-M
// N........oo...........os........m....h/.......:dd-......./h....m........so+y........d-...y/.......-M
// M........+h:::::::-...os........m....h/.......-dd-......./h....m........so+y........d-...y+.......-M
// M........-///////+os/.os........m....h/.......-dd-......./h....m........so+y........d-...y+.......-M
// M..................-y+os........m....h/.......-dd-......./h....m........so+y........d-...y+.......-M
// M/..................:dos........m....h/.......-dd:......./h....m........so+y........d-...y+.......-M
// Ny/--------..........mos........m....h/.......-dd:......./h....m........so+y........d-...y+.......-M
// m-+ooooooooy-........moy........m-...h/.......-dd:......./h....m........so+y........d-...y+.......-M
// m..........h+........Noy........d:...h+.......-md:.......:h....N........oo+y........d-...y+........M
// m----------h+........N+y........d/---h/.......-Nd:.......:h---:m........oo+y........h:---y+........M
// Msoooooooooo-........N/y........:oooo+-.......-Nd:.......-oooo+:........oo+h......../ooooo-........M
// M-...................N/y......................-Nd:......................oo+h.......................M
// M-..................:d:d......................:dd:.........SUDOSIX2k21..oo+h......................-M
// M-................./h/.ss-..................-/h:d:....................:ss..ss-...................:hN
// Nsoooooooooooooooos+-...:osooooooooosoooooooo+-.+soooosssssssssssssosso:----/ssooooossssssssssssso:m
// Nsssssssssssssss+hsssssh:./hsssssdsssssssssooooos+-ossssssssssssssoysooooooooooooomhooooooooooooossm
// N.............-:dh.....y+.oo.....d-.............-ydo-............-sM-.............do............../M
// N...............sh.....y+.os.....d-..............+M:......--......+M:.....--------do.....----......M
// N...../ysso.....sh.....y+.os.....d-....:dssh.....+M:....-dooh...../M:....-d+++++++ho.....ho+h:.....M
// N.....+y:+d.....sh.....y+.os.....d-....:d..m...../M:....-m..d/////oM:....-m/////..so.....m-.y/.....M
// N.....:o++/.....hh.....y+.os.....d:....-hooy.....+M:....-m:/+oossssm:....-/////h/.so.....ysss-....-M
// N............-/yhh.....y+.os.....d:.....---...--/hm:....-mm///::::oM:..........y+.so............-/yN
// N.....-----..-:+dh.....y+.os.....d:...........-:shd:....-mm::...../M:.....:::::y/.ss............:/yN
// M...../y+oy.....sh.....s+.os.....d:....-yooo.....+M:....-m/+m-..../M:....-m++++/-.ss.....ssoy:....-M
// M...../h/+h.....oh.....ss/ss.....h:....-m..m-..../M/....-d++m-..../M:....-m+++++++hs.....d-.y+.....N
// M.....-///:.....od.....-///-.....h:....-m..m-..../M/.....-::-...../M:.....-:------hs.....d-.y+.....N
// M...............ym-.............-m:....-m..m-..../Mo..............+M/.............hs.....d/.y+.....N
// M/////////////+ydyho//////////+ohNo/++++m::m+++++sdhyo++++++++++oyhdsooooooooooooomdooooom+:yhoooooM

pragma solidity ^0.8.0;

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

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

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

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

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

}

// File: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/utils/EnumerableMap.sol




pragma solidity ^0.8.0;

/**
 * @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 {
    // 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 MapEntry {
        bytes32 _key;
        bytes32 _value;
    }

    struct Map {
        // Storage of map keys and values
        MapEntry[] _entries;

        // Position of the entry defined by a key in the `entries` array, plus 1
        // because index 0 means a key is not in the map.
        mapping (bytes32 => uint256) _indexes;
    }

    /**
     * @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) {
        // We read and store the key's index to prevent multiple reads from the same storage slot
        uint256 keyIndex = map._indexes[key];

        if (keyIndex == 0) { // Equivalent to !contains(map, key)
            map._entries.push(MapEntry({ _key: key, _value: value }));
            // The entry is stored at length-1, but we add 1 to all indexes
            // and use 0 as a sentinel value
            map._indexes[key] = map._entries.length;
            return true;
        } else {
            map._entries[keyIndex - 1]._value = value;
            return false;
        }
    }

    /**
     * @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) {
        // We read and store the key's index to prevent multiple reads from the same storage slot
        uint256 keyIndex = map._indexes[key];

        if (keyIndex != 0) { // Equivalent to contains(map, key)
            // To delete a key-value pair from the _entries array in O(1), we swap the entry to delete with the last one
            // in the array, and then remove the last entry (sometimes called as 'swap and pop').
            // This modifies the order of the array, as noted in {at}.

            uint256 toDeleteIndex = keyIndex - 1;
            uint256 lastIndex = map._entries.length - 1;

            // When the entry 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.

            MapEntry storage lastEntry = map._entries[lastIndex];

            // Move the last entry to the index where the entry to delete is
            map._entries[toDeleteIndex] = lastEntry;
            // Update the index for the moved entry
            map._indexes[lastEntry._key] = toDeleteIndex + 1; // All indexes are 1-based

            // Delete the slot where the moved entry was stored
            map._entries.pop();

            // Delete the index for the deleted slot
            delete map._indexes[key];

            return true;
        } else {
            return false;
        }
    }

    /**
     * @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._indexes[key] != 0;
    }

    /**
     * @dev Returns the number of key-value pairs in the map. O(1).
     */
    function _length(Map storage map) private view returns (uint256) {
        return map._entries.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) {
        require(map._entries.length > index, "EnumerableMap: index out of bounds");

        MapEntry storage entry = map._entries[index];
        return (entry._key, entry._value);
    }

    /**
     * @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) {
        uint256 keyIndex = map._indexes[key];
        if (keyIndex == 0) return (false, 0); // Equivalent to contains(map, key)
        return (true, map._entries[keyIndex - 1]._value); // All indexes are 1-based
    }

    /**
     * @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) {
        uint256 keyIndex = map._indexes[key];
        require(keyIndex != 0, "EnumerableMap: nonexistent key"); // Equivalent to contains(map, key)
        return map._entries[keyIndex - 1]._value; // All indexes are 1-based
    }

    /**
     * @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) {
        uint256 keyIndex = map._indexes[key];
        require(keyIndex != 0, errorMessage); // Equivalent to contains(map, key)
        return map._entries[keyIndex - 1]._value; // All indexes are 1-based
    }

    // 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: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/utils/EnumerableSet.sol




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] = toDeleteIndex + 1; // All indexes are 1-based

            // 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: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/utils/Address.sol




pragma solidity ^0.8.0;

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

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

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

        // solhint-disable-next-line avoid-low-level-calls, avoid-call-value
        (bool success, ) = recipient.call{ value: amount }("");
        require(success, "Address: unable to send value, recipient may have reverted");
    }

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

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

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

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

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

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

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

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

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

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

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

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

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

// File: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/introspection/ERC165.sol


pragma solidity ^0.8.0;

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

// File: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC721/IERC721.sol


pragma solidity ^0.8.0;


/**
 * @dev Implementation of the {IERC165} interface.
 *
 * Contracts may inherit from this and call {_registerInterface} to declare
 * their support of an interface.
 */
abstract contract ERC165 is IERC165 {
    /**
     * @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(type(IERC165).interfaceId);
    }

    /**
     * @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: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC721/IERC721Receiver.sol




pragma solidity ^0.8.0;


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

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

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

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

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

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

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

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

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

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

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

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


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: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC721/IERC721Enumerable.sol




pragma solidity ^0.8.0;


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

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

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

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

// File: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC721/IERC721Metadata.sol




pragma solidity ^0.8.0;


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

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

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

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

// File: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/introspection/IERC165.sol



// File: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/utils/Context.sol




pragma solidity ^0.8.0;

/*
 * @dev Provides information about the current execution context, including the
 * sender of the transaction and its data. While these are generally available
 * via msg.sender and msg.data, they should not be accessed in such a direct
 * manner, since when dealing with GSN 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: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/token/ERC721/ERC721.sol




pragma solidity ^0.8.0;











/**
 * @title ERC721 Non-Fungible Token Standard basic implementation
 * @dev see https://eips.ethereum.org/EIPS/eip-721
 */
contract ERC721 is Context, ERC165, IERC721, IERC721Metadata, IERC721Enumerable {
    using Address for address;
    using EnumerableSet for EnumerableSet.UintSet;
    using EnumerableMap for EnumerableMap.UintToAddressMap;
    using Strings for uint256;

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

    /**
     * @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(type(IERC721).interfaceId);
        _registerInterface(type(IERC721Metadata).interfaceId);
        _registerInterface(type(IERC721Enumerable).interfaceId);
    }

    /**
     * @dev See {IERC721-balanceOf}.
     */
    function balanceOf(address owner) public view virtual override returns (uint256) {
        require(owner != address(0), "ERC721: balance query for the zero address");
        return _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:
     d*
     * - `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()) {
            try IERC721Receiver(to).onERC721Received(_msgSender(), from, tokenId, _data) returns (bytes4 retval) {
                return retval == IERC721Receiver(to).onERC721Received.selector;
            } catch (bytes memory reason) {
                if (reason.length == 0) {
                    revert("ERC721: transfer to non ERC721Receiver implementer");
                } else {
                    // solhint-disable-next-line no-inline-assembly
                    assembly {
                        revert(add(32, reason), mload(reason))
                    }
                }
            }
        } else {
            return true;
        }
    }

    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: http://github.com/OpenZeppelin/openzeppelin-contracts/contracts/access/Ownable.sol




pragma solidity ^0.8.0;

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

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

    /**
     * @dev Initializes the contract setting the deployer as the initial owner.
     */
    constructor () {
        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: https://github.com/OpenZeppelin/openzeppelin-contracts/contracts/utils/math/SafeMath.sol




pragma solidity ^0.8.0;

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

/**
 * @dev Wrappers over Solidity's arithmetic operations.
 *
 * NOTE: `SafeMath` is 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, with an overflow flag.
     *
     * _Available since v3.4._
     */
    function tryAdd(uint256 a, uint256 b) internal pure returns (bool, uint256) {
        unchecked {
            uint256 c = a + b;
            if (c < a) return (false, 0);
            return (true, c);
        }
    }

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

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

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

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

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

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

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

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

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

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

    /**
     * @dev Returns the integer division of two unsigned integers, reverting with custom message on
     * division by zero. The result is rounded towards zero.
     *
     * Counterpart to Solidity's `%` operator. 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;
        }
    }
}


pragma solidity ^0.8.0;





contract FRYCOOKS is ERC721, Ownable {
    using SafeMath for uint256;
    uint public constant MAX_COOKS = 11112;
    bool public hasSaleStarted = false;
    
    // THE IPFS HASH OF ALL TOKEN DATAS WILL BE ADDED HERE WHEN ALL JABBA FORMS ARE FINALIZED.
    string public METADATA_PROVENANCE_HASH = "";
    
    
    constructor() ERC721("FRYCOOKS","FRYCOOK")  {
        setBaseURI("https://j48baforms.io/frycook/");
    }
    
	
    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);
            uint256 index;
            for (index = 0; index < tokenCount; index++) {
                result[index] = tokenOfOwnerByIndex(_owner, index);
            }
            return result;
        }
    }
    
    function calculatePrice() public view returns (uint256) {
        require(hasSaleStarted == true, "SUDOBURGER is not open yet");

        require(totalSupply() < MAX_COOKS, "All FRYCOOKS have been minted!");

        uint currentSupply = totalSupply();
        require(currentSupply < MAX_COOKS, "All FRYCOOKS have been minted!");

        return 100000000000000000; //0.1 ETH
    }

     function calculatePriceTest(uint _id) public view returns (uint256) {


        require(_id < MAX_COOKS, "All FRYCOOKS have been minted!");

        return 100000000000000000; //0.1 ETH
        
    }
    
   function fryCOOK(uint256 numCooks) public payable {
        require(totalSupply() < MAX_COOKS, "All FRYCOOKS have been minted!");
        require(numCooks > 0 && numCooks <= 20, "Only 20 FRYCOOKS can be minted at a time");
        require(totalSupply().add(numCooks) <= MAX_COOKS, "All FRYCOOKS have been minted!");
        require(msg.value >= calculatePrice().mul(numCooks), "Not enough ETH sent in transaction");

        for (uint i = 0; i < numCooks; i++) {
            uint mintIndex = totalSupply();
            _safeMint(msg.sender, mintIndex);
        }

    }
	// AIRDROP FOR ALL J48BAFORMS HOLDERS. FUNCTION IS DESIGNED TO STOP WORKING AFTER AIRDROP. -sd6
    function jabbaAIRDROP(address[] memory userAddresses) public onlyOwner {
        require(totalSupply() < 985, "Airdrop is done.");
        for (uint256 i = 0; i < userAddresses.length; i++) {
            uint mintIndex = totalSupply();
            _safeMint(userAddresses[i], mintIndex);
        }
    }
    
    // ONLYOWNER FUNCTIONS
    
    function setProvenanceHash(string memory _hash) public onlyOwner {
        METADATA_PROVENANCE_HASH = _hash;
    }
    
    function setBaseURI(string memory baseURI) public onlyOwner {
        _setBaseURI(baseURI);
    }
    
    function startDrop() public onlyOwner {
        hasSaleStarted = true;
    }
    function pauseDrop() public onlyOwner {
        hasSaleStarted = false;
    }
    
    
    function withdrawAll() public payable onlyOwner {
        require(payable(msg.sender).send(address(this).balance));
    }
    


}

Contract Security Audit

Contract ABI

[{"inputs":[],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"approved","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Approval","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"owner","type":"address"},{"indexed":true,"internalType":"address","name":"operator","type":"address"},{"indexed":false,"internalType":"bool","name":"approved","type":"bool"}],"name":"ApprovalForAll","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"previousOwner","type":"address"},{"indexed":true,"internalType":"address","name":"newOwner","type":"address"}],"name":"OwnershipTransferred","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":true,"internalType":"address","name":"to","type":"address"},{"indexed":true,"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"Transfer","type":"event"},{"inputs":[],"name":"MAX_COOKS","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"METADATA_PROVENANCE_HASH","outputs":[{"internalType":"string","name":"","type":"string"}],"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":"calculatePrice","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"_id","type":"uint256"}],"name":"calculatePriceTest","outputs":[{"internalType":"uint256","name":"","type":"uint256"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"uint256","name":"numCooks","type":"uint256"}],"name":"fryCOOK","outputs":[],"stateMutability":"payable","type":"function"},{"inputs":[{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"getApproved","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"hasSaleStarted","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"owner","type":"address"},{"internalType":"address","name":"operator","type":"address"}],"name":"isApprovedForAll","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address[]","name":"userAddresses","type":"address[]"}],"name":"jabbaAIRDROP","outputs":[],"stateMutability":"nonpayable","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":"pauseDrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"renounceOwnership","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"from","type":"address"},{"internalType":"address","name":"to","type":"address"},{"internalType":"uint256","name":"tokenId","type":"uint256"},{"internalType":"bytes","name":"_data","type":"bytes"}],"name":"safeTransferFrom","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"operator","type":"address"},{"internalType":"bool","name":"approved","type":"bool"}],"name":"setApprovalForAll","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"baseURI","type":"string"}],"name":"setBaseURI","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"string","name":"_hash","type":"string"}],"name":"setProvenanceHash","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"startDrop","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"bytes4","name":"interfaceId","type":"bytes4"}],"name":"supportsInterface","outputs":[{"internalType":"bool","name":"","type":"bool"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"symbol","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"},{"inputs":[{"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":"withdrawAll","outputs":[],"stateMutability":"payable","type":"function"}]

60806040526000600a60146101000a81548160ff02191690831515021790555060405180602001604052806000815250600b9080519060200190620000469291906200047f565b503480156200005457600080fd5b506040518060400160405280600881526020017f465259434f4f4b530000000000000000000000000000000000000000000000008152506040518060400160405280600781526020017f465259434f4f4b00000000000000000000000000000000000000000000000000815250620000f27f01ffc9a700000000000000000000000000000000000000000000000000000000620002b660201b60201c565b81600690805190602001906200010a9291906200047f565b508060079080519060200190620001239291906200047f565b50620001557f80ac58cd00000000000000000000000000000000000000000000000000000000620002b660201b60201c565b620001867f5b5e139f00000000000000000000000000000000000000000000000000000000620002b660201b60201c565b620001b77f780e9d6300000000000000000000000000000000000000000000000000000000620002b660201b60201c565b50506000620001cb6200038e60201b60201c565b905080600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff1602179055508073ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a350620002b06040518060400160405280601e81526020017f68747470733a2f2f6a34386261666f726d732e696f2f667279636f6f6b2f00008152506200039660201b60201c565b6200066d565b63ffffffff60e01b817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916141562000322576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200031990620005b3565b60405180910390fd5b6001600080837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060006101000a81548160ff02191690831515021790555050565b600033905090565b620003a66200038e60201b60201c565b73ffffffffffffffffffffffffffffffffffffffff16620003cc6200043960201b60201c565b73ffffffffffffffffffffffffffffffffffffffff161462000425576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016200041c90620005d5565b60405180910390fd5b62000436816200046360201b60201c565b50565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b80600990805190602001906200047b9291906200047f565b5050565b8280546200048d9062000608565b90600052602060002090601f016020900481019282620004b15760008555620004fd565b82601f10620004cc57805160ff1916838001178555620004fd565b82800160010185558215620004fd579182015b82811115620004fc578251825591602001919060010190620004df565b5b5090506200050c919062000510565b5090565b5b808211156200052b57600081600090555060010162000511565b5090565b60006200053e601c83620005f7565b91507f4552433136353a20696e76616c696420696e74657266616365206964000000006000830152602082019050919050565b600062000580602083620005f7565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b60006020820190508181036000830152620005ce816200052f565b9050919050565b60006020820190508181036000830152620005f08162000571565b9050919050565b600082825260208201905092915050565b600060028204905060018216806200062157607f821691505b602082108114156200063857620006376200063e565b5b50919050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b614557806200067d6000396000f3fe6080604052600436106101ee5760003560e01c80636c0360eb1161010d578063a599ab39116100a0578063d348b4091161006f578063d348b409146106cf578063e985e9c5146106fa578063f0c9dc6014610737578063f2fde38b14610762578063f36e0c201461078b576101ee565b8063a599ab3914610622578063b36d9f171461064d578063b88d4fde14610669578063c87b56dd14610692576101ee565b8063853828b6116100dc578063853828b6146105995780638da5cb5b146105a357806395d89b41146105ce578063a22cb465146105f9576101ee565b80636c0360eb146104dd57806370a0823114610508578063715018a6146105455780638462151c1461055c576101ee565b80632808c92c116101855780634f6ccce7116101545780634f6ccce7146103fd57806350d7c72d1461043a57806355f804b3146104775780636352211e146104a0576101ee565b80632808c92c146103695780632f745c591461038057806334d84c7b146103bd57806342842e0e146103d4576101ee565b806310969523116101c157806310969523146102c157806318160ddd146102ea5780631c8b232d1461031557806323b872dd14610340576101ee565b806301ffc9a7146101f357806306fdde0314610230578063081812fc1461025b578063095ea7b314610298575b600080fd5b3480156101ff57600080fd5b5061021a6004803603810190610215919061328f565b6107b4565b6040516102279190613d07565b60405180910390f35b34801561023c57600080fd5b5061024561081b565b6040516102529190613d22565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d9190613322565b6108ad565b60405161028f9190613c7e565b60405180910390f35b3480156102a457600080fd5b506102bf60048036038101906102ba9190613212565b610932565b005b3480156102cd57600080fd5b506102e860048036038101906102e391906132e1565b610a4a565b005b3480156102f657600080fd5b506102ff610ae0565b60405161030c9190614004565b60405180910390f35b34801561032157600080fd5b5061032a610af1565b6040516103379190613d07565b60405180910390f35b34801561034c57600080fd5b506103676004803603810190610362919061310c565b610b04565b005b34801561037557600080fd5b5061037e610b64565b005b34801561038c57600080fd5b506103a760048036038101906103a29190613212565b610bfd565b6040516103b49190614004565b60405180910390f35b3480156103c957600080fd5b506103d2610c58565b005b3480156103e057600080fd5b506103fb60048036038101906103f6919061310c565b610cf1565b005b34801561040957600080fd5b50610424600480360381019061041f9190613322565b610d11565b6040516104319190614004565b60405180910390f35b34801561044657600080fd5b50610461600480360381019061045c9190613322565b610d34565b60405161046e9190614004565b60405180910390f35b34801561048357600080fd5b5061049e600480360381019061049991906132e1565b610d8a565b005b3480156104ac57600080fd5b506104c760048036038101906104c29190613322565b610e12565b6040516104d49190613c7e565b60405180910390f35b3480156104e957600080fd5b506104f2610e49565b6040516104ff9190613d22565b60405180910390f35b34801561051457600080fd5b5061052f600480360381019061052a91906130a7565b610edb565b60405161053c9190614004565b60405180910390f35b34801561055157600080fd5b5061055a610f9a565b005b34801561056857600080fd5b50610583600480360381019061057e91906130a7565b6110d7565b6040516105909190613ce5565b60405180910390f35b6105a1611253565b005b3480156105af57600080fd5b506105b861130f565b6040516105c59190613c7e565b60405180910390f35b3480156105da57600080fd5b506105e3611339565b6040516105f09190613d22565b60405180910390f35b34801561060557600080fd5b50610620600480360381019061061b91906131d6565b6113cb565b005b34801561062e57600080fd5b5061063761154c565b6040516106449190614004565b60405180910390f35b61066760048036038101906106629190613322565b611552565b005b34801561067557600080fd5b50610690600480360381019061068b919061315b565b6116e0565b005b34801561069e57600080fd5b506106b960048036038101906106b49190613322565b611742565b6040516106c69190613d22565b60405180910390f35b3480156106db57600080fd5b506106e46118b5565b6040516106f19190614004565b60405180910390f35b34801561070657600080fd5b50610721600480360381019061071c91906130d0565b6119b7565b60405161072e9190613d07565b60405180910390f35b34801561074357600080fd5b5061074c611a4b565b6040516107599190613d22565b60405180910390f35b34801561076e57600080fd5b50610789600480360381019061078491906130a7565b611ad9565b005b34801561079757600080fd5b506107b260048036038101906107ad919061324e565b611c85565b005b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b60606006805461082a90614323565b80601f016020809104026020016040519081016040528092919081815260200182805461085690614323565b80156108a35780601f10610878576101008083540402835291602001916108a3565b820191906000526020600020905b81548152906001019060200180831161088657829003601f168201915b5050505050905090565b60006108b882611dc6565b6108f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ee90613f24565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061093d82610e12565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156109ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109a590613fa4565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166109cd611de3565b73ffffffffffffffffffffffffffffffffffffffff1614806109fc57506109fb816109f6611de3565b6119b7565b5b610a3b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a3290613e44565b60405180910390fd5b610a458383611deb565b505050565b610a52611de3565b73ffffffffffffffffffffffffffffffffffffffff16610a7061130f565b73ffffffffffffffffffffffffffffffffffffffff1614610ac6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610abd90613f44565b60405180910390fd5b80600b9080519060200190610adc929190612e35565b5050565b6000610aec6002611ea4565b905090565b600a60149054906101000a900460ff1681565b610b15610b0f611de3565b82611eb9565b610b54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b4b90613fc4565b60405180910390fd5b610b5f838383611f97565b505050565b610b6c611de3565b73ffffffffffffffffffffffffffffffffffffffff16610b8a61130f565b73ffffffffffffffffffffffffffffffffffffffff1614610be0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bd790613f44565b60405180910390fd5b6000600a60146101000a81548160ff021916908315150217905550565b6000610c5082600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206121ae90919063ffffffff16565b905092915050565b610c60611de3565b73ffffffffffffffffffffffffffffffffffffffff16610c7e61130f565b73ffffffffffffffffffffffffffffffffffffffff1614610cd4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ccb90613f44565b60405180910390fd5b6001600a60146101000a81548160ff021916908315150217905550565b610d0c838383604051806020016040528060008152506116e0565b505050565b600080610d288360026121c890919063ffffffff16565b50905080915050919050565b6000612b688210610d7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7190613fe4565b60405180910390fd5b67016345785d8a00009050919050565b610d92611de3565b73ffffffffffffffffffffffffffffffffffffffff16610db061130f565b73ffffffffffffffffffffffffffffffffffffffff1614610e06576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dfd90613f44565b60405180910390fd5b610e0f816121f4565b50565b6000610e42826040518060600160405280602981526020016144f960299139600261220e9092919063ffffffff16565b9050919050565b606060098054610e5890614323565b80601f0160208091040260200160405190810160405280929190818152602001828054610e8490614323565b8015610ed15780601f10610ea657610100808354040283529160200191610ed1565b820191906000526020600020905b815481529060010190602001808311610eb457829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610f4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f4390613e84565b60405180910390fd5b610f93600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061222d565b9050919050565b610fa2611de3565b73ffffffffffffffffffffffffffffffffffffffff16610fc061130f565b73ffffffffffffffffffffffffffffffffffffffff1614611016576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161100d90613f44565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b606060006110e483610edb565b9050600081141561116757600067ffffffffffffffff811115611130577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405190808252806020026020018201604052801561115e5781602001602082028036833780820191505090505b5091505061124e565b60008167ffffffffffffffff8111156111a9577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156111d75781602001602082028036833780820191505090505b50905060005b82811015611247576111ef8582610bfd565b828281518110611228577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050808061123f90614355565b9150506111dd565b8193505050505b919050565b61125b611de3565b73ffffffffffffffffffffffffffffffffffffffff1661127961130f565b73ffffffffffffffffffffffffffffffffffffffff16146112cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112c690613f44565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f1935050505061130d57600080fd5b565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606007805461134890614323565b80601f016020809104026020016040519081016040528092919081815260200182805461137490614323565b80156113c15780601f10611396576101008083540402835291602001916113c1565b820191906000526020600020905b8154815290600101906020018083116113a457829003601f168201915b5050505050905090565b6113d3611de3565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611441576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161143890613e04565b60405180910390fd5b806005600061144e611de3565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166114fb611de3565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516115409190613d07565b60405180910390a35050565b612b6881565b612b6861155d610ae0565b1061159d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159490613fe4565b60405180910390fd5b6000811180156115ae575060148111155b6115ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115e490613d64565b60405180910390fd5b612b6861160a826115fc610ae0565b61224290919063ffffffff16565b111561164b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161164290613fe4565b60405180910390fd5b611665816116576118b5565b61225890919063ffffffff16565b3410156116a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161169e90613ea4565b60405180910390fd5b60005b818110156116dc5760006116bc610ae0565b90506116c8338261226e565b5080806116d490614355565b9150506116aa565b5050565b6116f16116eb611de3565b83611eb9565b611730576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161172790613fc4565b60405180910390fd5b61173c8484848461228c565b50505050565b606061174d82611dc6565b61178c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161178390613f84565b60405180910390fd5b60006008600084815260200190815260200160002080546117ac90614323565b80601f01602080910402602001604051908101604052809291908181526020018280546117d890614323565b80156118255780601f106117fa57610100808354040283529160200191611825565b820191906000526020600020905b81548152906001019060200180831161180857829003601f168201915b505050505090506000611836610e49565b905060008151141561184c5781925050506118b0565b600082511115611881578082604051602001611869929190613c5a565b604051602081830303815290604052925050506118b0565b8061188b856122e8565b60405160200161189c929190613c5a565b604051602081830303815290604052925050505b919050565b600060011515600a60149054906101000a900460ff1615151461190d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161190490613ee4565b60405180910390fd5b612b68611918610ae0565b10611958576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161194f90613fe4565b60405180910390fd5b6000611962610ae0565b9050612b6881106119a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161199f90613fe4565b60405180910390fd5b67016345785d8a000091505090565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600b8054611a5890614323565b80601f0160208091040260200160405190810160405280929190818152602001828054611a8490614323565b8015611ad15780601f10611aa657610100808354040283529160200191611ad1565b820191906000526020600020905b815481529060010190602001808311611ab457829003601f168201915b505050505081565b611ae1611de3565b73ffffffffffffffffffffffffffffffffffffffff16611aff61130f565b73ffffffffffffffffffffffffffffffffffffffff1614611b55576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b4c90613f44565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611bc5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bbc90613da4565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b611c8d611de3565b73ffffffffffffffffffffffffffffffffffffffff16611cab61130f565b73ffffffffffffffffffffffffffffffffffffffff1614611d01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cf890613f44565b60405180910390fd5b6103d9611d0c610ae0565b10611d4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d4390613e64565b60405180910390fd5b60005b8151811015611dc2576000611d62610ae0565b9050611dae838381518110611da0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101518261226e565b508080611dba90614355565b915050611d4f565b5050565b6000611ddc82600261249590919063ffffffff16565b9050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611e5e83610e12565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611eb2826000016124af565b9050919050565b6000611ec482611dc6565b611f03576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611efa90613e24565b60405180910390fd5b6000611f0e83610e12565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611f7d57508373ffffffffffffffffffffffffffffffffffffffff16611f65846108ad565b73ffffffffffffffffffffffffffffffffffffffff16145b80611f8e5750611f8d81856119b7565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611fb782610e12565b73ffffffffffffffffffffffffffffffffffffffff161461200d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161200490613f64565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561207d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161207490613de4565b60405180910390fd5b6120888383836124c0565b612093600082611deb565b6120e481600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206124c590919063ffffffff16565b5061213681600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206124df90919063ffffffff16565b5061214d818360026124f99092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60006121bd836000018361252e565b60001c905092915050565b6000806000806121db86600001866125c8565b915091508160001c8160001c9350935050509250929050565b806009908051906020019061220a929190612e35565b5050565b6000612221846000018460001b84612678565b60001c90509392505050565b600061223b8260000161273f565b9050919050565b600081836122509190614158565b905092915050565b6000818361226691906141df565b905092915050565b612288828260405180602001604052806000815250612750565b5050565b612297848484611f97565b6122a3848484846127ab565b6122e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122d990613d84565b60405180910390fd5b50505050565b60606000821415612330576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612490565b600082905060005b6000821461236257808061234b90614355565b915050600a8261235b91906141ae565b9150612338565b60008167ffffffffffffffff8111156123a4577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156123d65781602001600182028036833780820191505090505b5090505b60008514612489576001826123ef9190614239565b9150600a856123fe919061439e565b603061240a9190614158565b60f81b818381518110612446577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8561248291906141ae565b94506123da565b8093505050505b919050565b60006124a7836000018360001b612942565b905092915050565b600081600001805490509050919050565b505050565b60006124d7836000018360001b612965565b905092915050565b60006124f1836000018360001b612aef565b905092915050565b6000612525846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b612b5f565b90509392505050565b600081836000018054905011612579576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161257090613d44565b60405180910390fd5b8260000182815481106125b5577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b60008082846000018054905011612614576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161260b90613ec4565b60405180910390fd5b6000846000018481548110612652577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020906002020190508060000154816001015492509250509250929050565b600080846001016000858152602001908152602001600020549050600081141583906126da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126d19190613d22565b60405180910390fd5b50846000016001826126ec9190614239565b81548110612723577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b61275a8383612c71565b61276760008484846127ab565b6127a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161279d90613d84565b60405180910390fd5b505050565b60006127cc8473ffffffffffffffffffffffffffffffffffffffff16612dff565b15612935578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026127f5611de3565b8786866040518563ffffffff1660e01b81526004016128179493929190613c99565b602060405180830381600087803b15801561283157600080fd5b505af192505050801561286257506040513d601f19601f8201168201806040525081019061285f91906132b8565b60015b6128e5573d8060008114612892576040519150601f19603f3d011682016040523d82523d6000602084013e612897565b606091505b506000815114156128dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128d490613d84565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061293a565b600190505b949350505050565b600080836001016000848152602001908152602001600020541415905092915050565b60008083600101600084815260200190815260200160002054905060008114612ae35760006001826129979190614239565b90506000600186600001805490506129af9190614239565b905060008660000182815481106129ef577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110612a39577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200181905550600183612a549190614158565b8760010160008381526020019081526020016000208190555086600001805480612aa7577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050612ae9565b60009150505b92915050565b6000612afb8383612e12565b612b54578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612b59565b600090505b92915050565b6000808460010160008581526020019081526020016000205490506000811415612c0657846000016040518060400160405280868152602001858152509080600181540180825580915050600190039060005260206000209060020201600090919091909150600082015181600001556020820151816001015550508460000180549050856001016000868152602001908152602001600020819055506001915050612c6a565b8285600001600183612c189190614239565b81548110612c4f577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002090600202016001018190555060009150505b9392505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612ce1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cd890613f04565b60405180910390fd5b612cea81611dc6565b15612d2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d2190613dc4565b60405180910390fd5b612d36600083836124c0565b612d8781600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206124df90919063ffffffff16565b50612d9e818360026124f99092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600080823b905060008111915050919050565b600080836001016000848152602001908152602001600020541415905092915050565b828054612e4190614323565b90600052602060002090601f016020900481019282612e635760008555612eaa565b82601f10612e7c57805160ff1916838001178555612eaa565b82800160010185558215612eaa579182015b82811115612ea9578251825591602001919060010190612e8e565b5b509050612eb79190612ebb565b5090565b5b80821115612ed4576000816000905550600101612ebc565b5090565b6000612eeb612ee684614050565b61401f565b90508083825260208201905082856020860282011115612f0a57600080fd5b60005b85811015612f3a5781612f208882612fc0565b845260208401935060208301925050600181019050612f0d565b5050509392505050565b6000612f57612f528461407c565b61401f565b905082815260208101848484011115612f6f57600080fd5b612f7a8482856142e1565b509392505050565b6000612f95612f90846140ac565b61401f565b905082815260208101848484011115612fad57600080fd5b612fb88482856142e1565b509392505050565b600081359050612fcf8161449c565b92915050565b600082601f830112612fe657600080fd5b8135612ff6848260208601612ed8565b91505092915050565b60008135905061300e816144b3565b92915050565b600081359050613023816144ca565b92915050565b600081519050613038816144ca565b92915050565b600082601f83011261304f57600080fd5b813561305f848260208601612f44565b91505092915050565b600082601f83011261307957600080fd5b8135613089848260208601612f82565b91505092915050565b6000813590506130a1816144e1565b92915050565b6000602082840312156130b957600080fd5b60006130c784828501612fc0565b91505092915050565b600080604083850312156130e357600080fd5b60006130f185828601612fc0565b925050602061310285828601612fc0565b9150509250929050565b60008060006060848603121561312157600080fd5b600061312f86828701612fc0565b935050602061314086828701612fc0565b925050604061315186828701613092565b9150509250925092565b6000806000806080858703121561317157600080fd5b600061317f87828801612fc0565b945050602061319087828801612fc0565b93505060406131a187828801613092565b925050606085013567ffffffffffffffff8111156131be57600080fd5b6131ca8782880161303e565b91505092959194509250565b600080604083850312156131e957600080fd5b60006131f785828601612fc0565b925050602061320885828601612fff565b9150509250929050565b6000806040838503121561322557600080fd5b600061323385828601612fc0565b925050602061324485828601613092565b9150509250929050565b60006020828403121561326057600080fd5b600082013567ffffffffffffffff81111561327a57600080fd5b61328684828501612fd5565b91505092915050565b6000602082840312156132a157600080fd5b60006132af84828501613014565b91505092915050565b6000602082840312156132ca57600080fd5b60006132d884828501613029565b91505092915050565b6000602082840312156132f357600080fd5b600082013567ffffffffffffffff81111561330d57600080fd5b61331984828501613068565b91505092915050565b60006020828403121561333457600080fd5b600061334284828501613092565b91505092915050565b60006133578383613c3c565b60208301905092915050565b61336c8161426d565b82525050565b600061337d826140ec565b613387818561411a565b9350613392836140dc565b8060005b838110156133c35781516133aa888261334b565b97506133b58361410d565b925050600181019050613396565b5085935050505092915050565b6133d98161427f565b82525050565b60006133ea826140f7565b6133f4818561412b565b93506134048185602086016142f0565b61340d8161448b565b840191505092915050565b600061342382614102565b61342d818561413c565b935061343d8185602086016142f0565b6134468161448b565b840191505092915050565b600061345c82614102565b613466818561414d565b93506134768185602086016142f0565b80840191505092915050565b600061348f60228361413c565b91507f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006134f560288361413c565b91507f4f6e6c7920323020465259434f4f4b532063616e206265206d696e746564206160008301527f7420612074696d650000000000000000000000000000000000000000000000006020830152604082019050919050565b600061355b60328361413c565b91507f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008301527f63656976657220696d706c656d656e74657200000000000000000000000000006020830152604082019050919050565b60006135c160268361413c565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613627601c8361413c565b91507f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006000830152602082019050919050565b600061366760248361413c565b91507f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008301527f72657373000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006136cd60198361413c565b91507f4552433732313a20617070726f766520746f2063616c6c6572000000000000006000830152602082019050919050565b600061370d602c8361413c565b91507f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b600061377360388361413c565b91507f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008301527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006020830152604082019050919050565b60006137d960108361413c565b91507f41697264726f7020697320646f6e652e000000000000000000000000000000006000830152602082019050919050565b6000613819602a8361413c565b91507f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008301527f726f2061646472657373000000000000000000000000000000000000000000006020830152604082019050919050565b600061387f60228361413c565b91507f4e6f7420656e6f756768204554482073656e7420696e207472616e736163746960008301527f6f6e0000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006138e560228361413c565b91507f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061394b601a8361413c565b91507f5355444f425552474552206973206e6f74206f70656e207965740000000000006000830152602082019050919050565b600061398b60208361413c565b91507f4552433732313a206d696e7420746f20746865207a65726f20616464726573736000830152602082019050919050565b60006139cb602c8361413c565b91507f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b6000613a3160208361413c565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b6000613a7160298361413c565b91507f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008301527f73206e6f74206f776e00000000000000000000000000000000000000000000006020830152604082019050919050565b6000613ad7602f8361413c565b91507f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008301527f6e6578697374656e7420746f6b656e00000000000000000000000000000000006020830152604082019050919050565b6000613b3d60218361413c565b91507f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008301527f72000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613ba360318361413c565b91507f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008301527f776e6572206e6f7220617070726f7665640000000000000000000000000000006020830152604082019050919050565b6000613c09601e8361413c565b91507f416c6c20465259434f4f4b532068617665206265656e206d696e7465642100006000830152602082019050919050565b613c45816142d7565b82525050565b613c54816142d7565b82525050565b6000613c668285613451565b9150613c728284613451565b91508190509392505050565b6000602082019050613c936000830184613363565b92915050565b6000608082019050613cae6000830187613363565b613cbb6020830186613363565b613cc86040830185613c4b565b8181036060830152613cda81846133df565b905095945050505050565b60006020820190508181036000830152613cff8184613372565b905092915050565b6000602082019050613d1c60008301846133d0565b92915050565b60006020820190508181036000830152613d3c8184613418565b905092915050565b60006020820190508181036000830152613d5d81613482565b9050919050565b60006020820190508181036000830152613d7d816134e8565b9050919050565b60006020820190508181036000830152613d9d8161354e565b9050919050565b60006020820190508181036000830152613dbd816135b4565b9050919050565b60006020820190508181036000830152613ddd8161361a565b9050919050565b60006020820190508181036000830152613dfd8161365a565b9050919050565b60006020820190508181036000830152613e1d816136c0565b9050919050565b60006020820190508181036000830152613e3d81613700565b9050919050565b60006020820190508181036000830152613e5d81613766565b9050919050565b60006020820190508181036000830152613e7d816137cc565b9050919050565b60006020820190508181036000830152613e9d8161380c565b9050919050565b60006020820190508181036000830152613ebd81613872565b9050919050565b60006020820190508181036000830152613edd816138d8565b9050919050565b60006020820190508181036000830152613efd8161393e565b9050919050565b60006020820190508181036000830152613f1d8161397e565b9050919050565b60006020820190508181036000830152613f3d816139be565b9050919050565b60006020820190508181036000830152613f5d81613a24565b9050919050565b60006020820190508181036000830152613f7d81613a64565b9050919050565b60006020820190508181036000830152613f9d81613aca565b9050919050565b60006020820190508181036000830152613fbd81613b30565b9050919050565b60006020820190508181036000830152613fdd81613b96565b9050919050565b60006020820190508181036000830152613ffd81613bfc565b9050919050565b60006020820190506140196000830184613c4b565b92915050565b6000604051905081810181811067ffffffffffffffff821117156140465761404561445c565b5b8060405250919050565b600067ffffffffffffffff82111561406b5761406a61445c565b5b602082029050602081019050919050565b600067ffffffffffffffff8211156140975761409661445c565b5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff8211156140c7576140c661445c565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6000614163826142d7565b915061416e836142d7565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156141a3576141a26143cf565b5b828201905092915050565b60006141b9826142d7565b91506141c4836142d7565b9250826141d4576141d36143fe565b5b828204905092915050565b60006141ea826142d7565b91506141f5836142d7565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561422e5761422d6143cf565b5b828202905092915050565b6000614244826142d7565b915061424f836142d7565b925082821015614262576142616143cf565b5b828203905092915050565b6000614278826142b7565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b8381101561430e5780820151818401526020810190506142f3565b8381111561431d576000848401525b50505050565b6000600282049050600182168061433b57607f821691505b6020821081141561434f5761434e61442d565b5b50919050565b6000614360826142d7565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415614393576143926143cf565b5b600182019050919050565b60006143a9826142d7565b91506143b4836142d7565b9250826143c4576143c36143fe565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b6144a58161426d565b81146144b057600080fd5b50565b6144bc8161427f565b81146144c757600080fd5b50565b6144d38161428b565b81146144de57600080fd5b50565b6144ea816142d7565b81146144f557600080fd5b5056fe4552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea264697066735822122021fb5a2265b62e2caa7cfb584ae81a406027030be7912d5896bb8669020036e564736f6c63430008000033

Deployed Bytecode

0x6080604052600436106101ee5760003560e01c80636c0360eb1161010d578063a599ab39116100a0578063d348b4091161006f578063d348b409146106cf578063e985e9c5146106fa578063f0c9dc6014610737578063f2fde38b14610762578063f36e0c201461078b576101ee565b8063a599ab3914610622578063b36d9f171461064d578063b88d4fde14610669578063c87b56dd14610692576101ee565b8063853828b6116100dc578063853828b6146105995780638da5cb5b146105a357806395d89b41146105ce578063a22cb465146105f9576101ee565b80636c0360eb146104dd57806370a0823114610508578063715018a6146105455780638462151c1461055c576101ee565b80632808c92c116101855780634f6ccce7116101545780634f6ccce7146103fd57806350d7c72d1461043a57806355f804b3146104775780636352211e146104a0576101ee565b80632808c92c146103695780632f745c591461038057806334d84c7b146103bd57806342842e0e146103d4576101ee565b806310969523116101c157806310969523146102c157806318160ddd146102ea5780631c8b232d1461031557806323b872dd14610340576101ee565b806301ffc9a7146101f357806306fdde0314610230578063081812fc1461025b578063095ea7b314610298575b600080fd5b3480156101ff57600080fd5b5061021a6004803603810190610215919061328f565b6107b4565b6040516102279190613d07565b60405180910390f35b34801561023c57600080fd5b5061024561081b565b6040516102529190613d22565b60405180910390f35b34801561026757600080fd5b50610282600480360381019061027d9190613322565b6108ad565b60405161028f9190613c7e565b60405180910390f35b3480156102a457600080fd5b506102bf60048036038101906102ba9190613212565b610932565b005b3480156102cd57600080fd5b506102e860048036038101906102e391906132e1565b610a4a565b005b3480156102f657600080fd5b506102ff610ae0565b60405161030c9190614004565b60405180910390f35b34801561032157600080fd5b5061032a610af1565b6040516103379190613d07565b60405180910390f35b34801561034c57600080fd5b506103676004803603810190610362919061310c565b610b04565b005b34801561037557600080fd5b5061037e610b64565b005b34801561038c57600080fd5b506103a760048036038101906103a29190613212565b610bfd565b6040516103b49190614004565b60405180910390f35b3480156103c957600080fd5b506103d2610c58565b005b3480156103e057600080fd5b506103fb60048036038101906103f6919061310c565b610cf1565b005b34801561040957600080fd5b50610424600480360381019061041f9190613322565b610d11565b6040516104319190614004565b60405180910390f35b34801561044657600080fd5b50610461600480360381019061045c9190613322565b610d34565b60405161046e9190614004565b60405180910390f35b34801561048357600080fd5b5061049e600480360381019061049991906132e1565b610d8a565b005b3480156104ac57600080fd5b506104c760048036038101906104c29190613322565b610e12565b6040516104d49190613c7e565b60405180910390f35b3480156104e957600080fd5b506104f2610e49565b6040516104ff9190613d22565b60405180910390f35b34801561051457600080fd5b5061052f600480360381019061052a91906130a7565b610edb565b60405161053c9190614004565b60405180910390f35b34801561055157600080fd5b5061055a610f9a565b005b34801561056857600080fd5b50610583600480360381019061057e91906130a7565b6110d7565b6040516105909190613ce5565b60405180910390f35b6105a1611253565b005b3480156105af57600080fd5b506105b861130f565b6040516105c59190613c7e565b60405180910390f35b3480156105da57600080fd5b506105e3611339565b6040516105f09190613d22565b60405180910390f35b34801561060557600080fd5b50610620600480360381019061061b91906131d6565b6113cb565b005b34801561062e57600080fd5b5061063761154c565b6040516106449190614004565b60405180910390f35b61066760048036038101906106629190613322565b611552565b005b34801561067557600080fd5b50610690600480360381019061068b919061315b565b6116e0565b005b34801561069e57600080fd5b506106b960048036038101906106b49190613322565b611742565b6040516106c69190613d22565b60405180910390f35b3480156106db57600080fd5b506106e46118b5565b6040516106f19190614004565b60405180910390f35b34801561070657600080fd5b50610721600480360381019061071c91906130d0565b6119b7565b60405161072e9190613d07565b60405180910390f35b34801561074357600080fd5b5061074c611a4b565b6040516107599190613d22565b60405180910390f35b34801561076e57600080fd5b50610789600480360381019061078491906130a7565b611ad9565b005b34801561079757600080fd5b506107b260048036038101906107ad919061324e565b611c85565b005b6000806000837bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19167bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916815260200190815260200160002060009054906101000a900460ff169050919050565b60606006805461082a90614323565b80601f016020809104026020016040519081016040528092919081815260200182805461085690614323565b80156108a35780601f10610878576101008083540402835291602001916108a3565b820191906000526020600020905b81548152906001019060200180831161088657829003601f168201915b5050505050905090565b60006108b882611dc6565b6108f7576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016108ee90613f24565b60405180910390fd5b6004600083815260200190815260200160002060009054906101000a900473ffffffffffffffffffffffffffffffffffffffff169050919050565b600061093d82610e12565b90508073ffffffffffffffffffffffffffffffffffffffff168373ffffffffffffffffffffffffffffffffffffffff1614156109ae576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016109a590613fa4565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff166109cd611de3565b73ffffffffffffffffffffffffffffffffffffffff1614806109fc57506109fb816109f6611de3565b6119b7565b5b610a3b576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610a3290613e44565b60405180910390fd5b610a458383611deb565b505050565b610a52611de3565b73ffffffffffffffffffffffffffffffffffffffff16610a7061130f565b73ffffffffffffffffffffffffffffffffffffffff1614610ac6576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610abd90613f44565b60405180910390fd5b80600b9080519060200190610adc929190612e35565b5050565b6000610aec6002611ea4565b905090565b600a60149054906101000a900460ff1681565b610b15610b0f611de3565b82611eb9565b610b54576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610b4b90613fc4565b60405180910390fd5b610b5f838383611f97565b505050565b610b6c611de3565b73ffffffffffffffffffffffffffffffffffffffff16610b8a61130f565b73ffffffffffffffffffffffffffffffffffffffff1614610be0576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610bd790613f44565b60405180910390fd5b6000600a60146101000a81548160ff021916908315150217905550565b6000610c5082600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206121ae90919063ffffffff16565b905092915050565b610c60611de3565b73ffffffffffffffffffffffffffffffffffffffff16610c7e61130f565b73ffffffffffffffffffffffffffffffffffffffff1614610cd4576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610ccb90613f44565b60405180910390fd5b6001600a60146101000a81548160ff021916908315150217905550565b610d0c838383604051806020016040528060008152506116e0565b505050565b600080610d288360026121c890919063ffffffff16565b50905080915050919050565b6000612b688210610d7a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610d7190613fe4565b60405180910390fd5b67016345785d8a00009050919050565b610d92611de3565b73ffffffffffffffffffffffffffffffffffffffff16610db061130f565b73ffffffffffffffffffffffffffffffffffffffff1614610e06576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610dfd90613f44565b60405180910390fd5b610e0f816121f4565b50565b6000610e42826040518060600160405280602981526020016144f960299139600261220e9092919063ffffffff16565b9050919050565b606060098054610e5890614323565b80601f0160208091040260200160405190810160405280929190818152602001828054610e8490614323565b8015610ed15780601f10610ea657610100808354040283529160200191610ed1565b820191906000526020600020905b815481529060010190602001808311610eb457829003601f168201915b5050505050905090565b60008073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415610f4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401610f4390613e84565b60405180910390fd5b610f93600160008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002061222d565b9050919050565b610fa2611de3565b73ffffffffffffffffffffffffffffffffffffffff16610fc061130f565b73ffffffffffffffffffffffffffffffffffffffff1614611016576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161100d90613f44565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a36000600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550565b606060006110e483610edb565b9050600081141561116757600067ffffffffffffffff811115611130577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b60405190808252806020026020018201604052801561115e5781602001602082028036833780820191505090505b5091505061124e565b60008167ffffffffffffffff8111156111a9577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280602002602001820160405280156111d75781602001602082028036833780820191505090505b50905060005b82811015611247576111ef8582610bfd565b828281518110611228577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b602002602001018181525050808061123f90614355565b9150506111dd565b8193505050505b919050565b61125b611de3565b73ffffffffffffffffffffffffffffffffffffffff1661127961130f565b73ffffffffffffffffffffffffffffffffffffffff16146112cf576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016112c690613f44565b60405180910390fd5b3373ffffffffffffffffffffffffffffffffffffffff166108fc479081150290604051600060405180830381858888f1935050505061130d57600080fd5b565b6000600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff16905090565b60606007805461134890614323565b80601f016020809104026020016040519081016040528092919081815260200182805461137490614323565b80156113c15780601f10611396576101008083540402835291602001916113c1565b820191906000526020600020905b8154815290600101906020018083116113a457829003601f168201915b5050505050905090565b6113d3611de3565b73ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415611441576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161143890613e04565b60405180910390fd5b806005600061144e611de3565b73ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060006101000a81548160ff0219169083151502179055508173ffffffffffffffffffffffffffffffffffffffff166114fb611de3565b73ffffffffffffffffffffffffffffffffffffffff167f17307eab39ab6107e8899845ad3d59bd9653f200f220920489ca2b5937696c31836040516115409190613d07565b60405180910390a35050565b612b6881565b612b6861155d610ae0565b1061159d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161159490613fe4565b60405180910390fd5b6000811180156115ae575060148111155b6115ed576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016115e490613d64565b60405180910390fd5b612b6861160a826115fc610ae0565b61224290919063ffffffff16565b111561164b576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161164290613fe4565b60405180910390fd5b611665816116576118b5565b61225890919063ffffffff16565b3410156116a7576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161169e90613ea4565b60405180910390fd5b60005b818110156116dc5760006116bc610ae0565b90506116c8338261226e565b5080806116d490614355565b9150506116aa565b5050565b6116f16116eb611de3565b83611eb9565b611730576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161172790613fc4565b60405180910390fd5b61173c8484848461228c565b50505050565b606061174d82611dc6565b61178c576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161178390613f84565b60405180910390fd5b60006008600084815260200190815260200160002080546117ac90614323565b80601f01602080910402602001604051908101604052809291908181526020018280546117d890614323565b80156118255780601f106117fa57610100808354040283529160200191611825565b820191906000526020600020905b81548152906001019060200180831161180857829003601f168201915b505050505090506000611836610e49565b905060008151141561184c5781925050506118b0565b600082511115611881578082604051602001611869929190613c5a565b604051602081830303815290604052925050506118b0565b8061188b856122e8565b60405160200161189c929190613c5a565b604051602081830303815290604052925050505b919050565b600060011515600a60149054906101000a900460ff1615151461190d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161190490613ee4565b60405180910390fd5b612b68611918610ae0565b10611958576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161194f90613fe4565b60405180910390fd5b6000611962610ae0565b9050612b6881106119a8576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161199f90613fe4565b60405180910390fd5b67016345785d8a000091505090565b6000600560008473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060008373ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff16815260200190815260200160002060009054906101000a900460ff16905092915050565b600b8054611a5890614323565b80601f0160208091040260200160405190810160405280929190818152602001828054611a8490614323565b8015611ad15780601f10611aa657610100808354040283529160200191611ad1565b820191906000526020600020905b815481529060010190602001808311611ab457829003601f168201915b505050505081565b611ae1611de3565b73ffffffffffffffffffffffffffffffffffffffff16611aff61130f565b73ffffffffffffffffffffffffffffffffffffffff1614611b55576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611b4c90613f44565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168173ffffffffffffffffffffffffffffffffffffffff161415611bc5576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611bbc90613da4565b60405180910390fd5b8073ffffffffffffffffffffffffffffffffffffffff16600a60009054906101000a900473ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff167f8be0079c531659141344cd1fd0a4f28419497f9722a3daafe3b4186f6b6457e060405160405180910390a380600a60006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff16021790555050565b611c8d611de3565b73ffffffffffffffffffffffffffffffffffffffff16611cab61130f565b73ffffffffffffffffffffffffffffffffffffffff1614611d01576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611cf890613f44565b60405180910390fd5b6103d9611d0c610ae0565b10611d4c576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611d4390613e64565b60405180910390fd5b60005b8151811015611dc2576000611d62610ae0565b9050611dae838381518110611da0577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200260200101518261226e565b508080611dba90614355565b915050611d4f565b5050565b6000611ddc82600261249590919063ffffffff16565b9050919050565b600033905090565b816004600083815260200190815260200160002060006101000a81548173ffffffffffffffffffffffffffffffffffffffff021916908373ffffffffffffffffffffffffffffffffffffffff160217905550808273ffffffffffffffffffffffffffffffffffffffff16611e5e83610e12565b73ffffffffffffffffffffffffffffffffffffffff167f8c5be1e5ebec7d5bd14f71427d1e84f3dd0314c0f7b2291e5b200ac8c7c3b92560405160405180910390a45050565b6000611eb2826000016124af565b9050919050565b6000611ec482611dc6565b611f03576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401611efa90613e24565b60405180910390fd5b6000611f0e83610e12565b90508073ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff161480611f7d57508373ffffffffffffffffffffffffffffffffffffffff16611f65846108ad565b73ffffffffffffffffffffffffffffffffffffffff16145b80611f8e5750611f8d81856119b7565b5b91505092915050565b8273ffffffffffffffffffffffffffffffffffffffff16611fb782610e12565b73ffffffffffffffffffffffffffffffffffffffff161461200d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161200490613f64565b60405180910390fd5b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff16141561207d576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161207490613de4565b60405180910390fd5b6120888383836124c0565b612093600082611deb565b6120e481600160008673ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206124c590919063ffffffff16565b5061213681600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206124df90919063ffffffff16565b5061214d818360026124f99092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff168473ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a4505050565b60006121bd836000018361252e565b60001c905092915050565b6000806000806121db86600001866125c8565b915091508160001c8160001c9350935050509250929050565b806009908051906020019061220a929190612e35565b5050565b6000612221846000018460001b84612678565b60001c90509392505050565b600061223b8260000161273f565b9050919050565b600081836122509190614158565b905092915050565b6000818361226691906141df565b905092915050565b612288828260405180602001604052806000815250612750565b5050565b612297848484611f97565b6122a3848484846127ab565b6122e2576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016122d990613d84565b60405180910390fd5b50505050565b60606000821415612330576040518060400160405280600181526020017f30000000000000000000000000000000000000000000000000000000000000008152509050612490565b600082905060005b6000821461236257808061234b90614355565b915050600a8261235b91906141ae565b9150612338565b60008167ffffffffffffffff8111156123a4577f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6040519080825280601f01601f1916602001820160405280156123d65781602001600182028036833780820191505090505b5090505b60008514612489576001826123ef9190614239565b9150600a856123fe919061439e565b603061240a9190614158565b60f81b818381518110612446577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b60200101907effffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916908160001a905350600a8561248291906141ae565b94506123da565b8093505050505b919050565b60006124a7836000018360001b612942565b905092915050565b600081600001805490509050919050565b505050565b60006124d7836000018360001b612965565b905092915050565b60006124f1836000018360001b612aef565b905092915050565b6000612525846000018460001b8473ffffffffffffffffffffffffffffffffffffffff1660001b612b5f565b90509392505050565b600081836000018054905011612579576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161257090613d44565b60405180910390fd5b8260000182815481106125b5577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905092915050565b60008082846000018054905011612614576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161260b90613ec4565b60405180910390fd5b6000846000018481548110612652577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b906000526020600020906002020190508060000154816001015492509250509250929050565b600080846001016000858152602001908152602001600020549050600081141583906126da576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016126d19190613d22565b60405180910390fd5b50846000016001826126ec9190614239565b81548110612723577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000209060020201600101549150509392505050565b600081600001805490509050919050565b61275a8383612c71565b61276760008484846127ab565b6127a6576040517f08c379a000000000000000000000000000000000000000000000000000000000815260040161279d90613d84565b60405180910390fd5b505050565b60006127cc8473ffffffffffffffffffffffffffffffffffffffff16612dff565b15612935578373ffffffffffffffffffffffffffffffffffffffff1663150b7a026127f5611de3565b8786866040518563ffffffff1660e01b81526004016128179493929190613c99565b602060405180830381600087803b15801561283157600080fd5b505af192505050801561286257506040513d601f19601f8201168201806040525081019061285f91906132b8565b60015b6128e5573d8060008114612892576040519150601f19603f3d011682016040523d82523d6000602084013e612897565b606091505b506000815114156128dd576040517f08c379a00000000000000000000000000000000000000000000000000000000081526004016128d490613d84565b60405180910390fd5b805181602001fd5b63150b7a0260e01b7bffffffffffffffffffffffffffffffffffffffffffffffffffffffff1916817bffffffffffffffffffffffffffffffffffffffffffffffffffffffff19161491505061293a565b600190505b949350505050565b600080836001016000848152602001908152602001600020541415905092915050565b60008083600101600084815260200190815260200160002054905060008114612ae35760006001826129979190614239565b90506000600186600001805490506129af9190614239565b905060008660000182815481106129ef577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200154905080876000018481548110612a39577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b9060005260206000200181905550600183612a549190614158565b8760010160008381526020019081526020016000208190555086600001805480612aa7577f4e487b7100000000000000000000000000000000000000000000000000000000600052603160045260246000fd5b60019003818190600052602060002001600090559055866001016000878152602001908152602001600020600090556001945050505050612ae9565b60009150505b92915050565b6000612afb8383612e12565b612b54578260000182908060018154018082558091505060019003906000526020600020016000909190919091505582600001805490508360010160008481526020019081526020016000208190555060019050612b59565b600090505b92915050565b6000808460010160008581526020019081526020016000205490506000811415612c0657846000016040518060400160405280868152602001858152509080600181540180825580915050600190039060005260206000209060020201600090919091909150600082015181600001556020820151816001015550508460000180549050856001016000868152602001908152602001600020819055506001915050612c6a565b8285600001600183612c189190614239565b81548110612c4f577f4e487b7100000000000000000000000000000000000000000000000000000000600052603260045260246000fd5b90600052602060002090600202016001018190555060009150505b9392505050565b600073ffffffffffffffffffffffffffffffffffffffff168273ffffffffffffffffffffffffffffffffffffffff161415612ce1576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612cd890613f04565b60405180910390fd5b612cea81611dc6565b15612d2a576040517f08c379a0000000000000000000000000000000000000000000000000000000008152600401612d2190613dc4565b60405180910390fd5b612d36600083836124c0565b612d8781600160008573ffffffffffffffffffffffffffffffffffffffff1673ffffffffffffffffffffffffffffffffffffffff1681526020019081526020016000206124df90919063ffffffff16565b50612d9e818360026124f99092919063ffffffff16565b50808273ffffffffffffffffffffffffffffffffffffffff16600073ffffffffffffffffffffffffffffffffffffffff167fddf252ad1be2c89b69c2b068fc378daa952ba7f163c4a11628f55a4df523b3ef60405160405180910390a45050565b600080823b905060008111915050919050565b600080836001016000848152602001908152602001600020541415905092915050565b828054612e4190614323565b90600052602060002090601f016020900481019282612e635760008555612eaa565b82601f10612e7c57805160ff1916838001178555612eaa565b82800160010185558215612eaa579182015b82811115612ea9578251825591602001919060010190612e8e565b5b509050612eb79190612ebb565b5090565b5b80821115612ed4576000816000905550600101612ebc565b5090565b6000612eeb612ee684614050565b61401f565b90508083825260208201905082856020860282011115612f0a57600080fd5b60005b85811015612f3a5781612f208882612fc0565b845260208401935060208301925050600181019050612f0d565b5050509392505050565b6000612f57612f528461407c565b61401f565b905082815260208101848484011115612f6f57600080fd5b612f7a8482856142e1565b509392505050565b6000612f95612f90846140ac565b61401f565b905082815260208101848484011115612fad57600080fd5b612fb88482856142e1565b509392505050565b600081359050612fcf8161449c565b92915050565b600082601f830112612fe657600080fd5b8135612ff6848260208601612ed8565b91505092915050565b60008135905061300e816144b3565b92915050565b600081359050613023816144ca565b92915050565b600081519050613038816144ca565b92915050565b600082601f83011261304f57600080fd5b813561305f848260208601612f44565b91505092915050565b600082601f83011261307957600080fd5b8135613089848260208601612f82565b91505092915050565b6000813590506130a1816144e1565b92915050565b6000602082840312156130b957600080fd5b60006130c784828501612fc0565b91505092915050565b600080604083850312156130e357600080fd5b60006130f185828601612fc0565b925050602061310285828601612fc0565b9150509250929050565b60008060006060848603121561312157600080fd5b600061312f86828701612fc0565b935050602061314086828701612fc0565b925050604061315186828701613092565b9150509250925092565b6000806000806080858703121561317157600080fd5b600061317f87828801612fc0565b945050602061319087828801612fc0565b93505060406131a187828801613092565b925050606085013567ffffffffffffffff8111156131be57600080fd5b6131ca8782880161303e565b91505092959194509250565b600080604083850312156131e957600080fd5b60006131f785828601612fc0565b925050602061320885828601612fff565b9150509250929050565b6000806040838503121561322557600080fd5b600061323385828601612fc0565b925050602061324485828601613092565b9150509250929050565b60006020828403121561326057600080fd5b600082013567ffffffffffffffff81111561327a57600080fd5b61328684828501612fd5565b91505092915050565b6000602082840312156132a157600080fd5b60006132af84828501613014565b91505092915050565b6000602082840312156132ca57600080fd5b60006132d884828501613029565b91505092915050565b6000602082840312156132f357600080fd5b600082013567ffffffffffffffff81111561330d57600080fd5b61331984828501613068565b91505092915050565b60006020828403121561333457600080fd5b600061334284828501613092565b91505092915050565b60006133578383613c3c565b60208301905092915050565b61336c8161426d565b82525050565b600061337d826140ec565b613387818561411a565b9350613392836140dc565b8060005b838110156133c35781516133aa888261334b565b97506133b58361410d565b925050600181019050613396565b5085935050505092915050565b6133d98161427f565b82525050565b60006133ea826140f7565b6133f4818561412b565b93506134048185602086016142f0565b61340d8161448b565b840191505092915050565b600061342382614102565b61342d818561413c565b935061343d8185602086016142f0565b6134468161448b565b840191505092915050565b600061345c82614102565b613466818561414d565b93506134768185602086016142f0565b80840191505092915050565b600061348f60228361413c565b91507f456e756d657261626c655365743a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006134f560288361413c565b91507f4f6e6c7920323020465259434f4f4b532063616e206265206d696e746564206160008301527f7420612074696d650000000000000000000000000000000000000000000000006020830152604082019050919050565b600061355b60328361413c565b91507f4552433732313a207472616e7366657220746f206e6f6e20455243373231526560008301527f63656976657220696d706c656d656e74657200000000000000000000000000006020830152604082019050919050565b60006135c160268361413c565b91507f4f776e61626c653a206e6577206f776e657220697320746865207a65726f206160008301527f64647265737300000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613627601c8361413c565b91507f4552433732313a20746f6b656e20616c7265616479206d696e746564000000006000830152602082019050919050565b600061366760248361413c565b91507f4552433732313a207472616e7366657220746f20746865207a65726f2061646460008301527f72657373000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006136cd60198361413c565b91507f4552433732313a20617070726f766520746f2063616c6c6572000000000000006000830152602082019050919050565b600061370d602c8361413c565b91507f4552433732313a206f70657261746f7220717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b600061377360388361413c565b91507f4552433732313a20617070726f76652063616c6c6572206973206e6f74206f7760008301527f6e6572206e6f7220617070726f76656420666f7220616c6c00000000000000006020830152604082019050919050565b60006137d960108361413c565b91507f41697264726f7020697320646f6e652e000000000000000000000000000000006000830152602082019050919050565b6000613819602a8361413c565b91507f4552433732313a2062616c616e636520717565727920666f7220746865207a6560008301527f726f2061646472657373000000000000000000000000000000000000000000006020830152604082019050919050565b600061387f60228361413c565b91507f4e6f7420656e6f756768204554482073656e7420696e207472616e736163746960008301527f6f6e0000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b60006138e560228361413c565b91507f456e756d657261626c654d61703a20696e646578206f7574206f6620626f756e60008301527f64730000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b600061394b601a8361413c565b91507f5355444f425552474552206973206e6f74206f70656e207965740000000000006000830152602082019050919050565b600061398b60208361413c565b91507f4552433732313a206d696e7420746f20746865207a65726f20616464726573736000830152602082019050919050565b60006139cb602c8361413c565b91507f4552433732313a20617070726f76656420717565727920666f72206e6f6e657860008301527f697374656e7420746f6b656e00000000000000000000000000000000000000006020830152604082019050919050565b6000613a3160208361413c565b91507f4f776e61626c653a2063616c6c6572206973206e6f7420746865206f776e65726000830152602082019050919050565b6000613a7160298361413c565b91507f4552433732313a207472616e73666572206f6620746f6b656e2074686174206960008301527f73206e6f74206f776e00000000000000000000000000000000000000000000006020830152604082019050919050565b6000613ad7602f8361413c565b91507f4552433732314d657461646174613a2055524920717565727920666f72206e6f60008301527f6e6578697374656e7420746f6b656e00000000000000000000000000000000006020830152604082019050919050565b6000613b3d60218361413c565b91507f4552433732313a20617070726f76616c20746f2063757272656e74206f776e6560008301527f72000000000000000000000000000000000000000000000000000000000000006020830152604082019050919050565b6000613ba360318361413c565b91507f4552433732313a207472616e736665722063616c6c6572206973206e6f74206f60008301527f776e6572206e6f7220617070726f7665640000000000000000000000000000006020830152604082019050919050565b6000613c09601e8361413c565b91507f416c6c20465259434f4f4b532068617665206265656e206d696e7465642100006000830152602082019050919050565b613c45816142d7565b82525050565b613c54816142d7565b82525050565b6000613c668285613451565b9150613c728284613451565b91508190509392505050565b6000602082019050613c936000830184613363565b92915050565b6000608082019050613cae6000830187613363565b613cbb6020830186613363565b613cc86040830185613c4b565b8181036060830152613cda81846133df565b905095945050505050565b60006020820190508181036000830152613cff8184613372565b905092915050565b6000602082019050613d1c60008301846133d0565b92915050565b60006020820190508181036000830152613d3c8184613418565b905092915050565b60006020820190508181036000830152613d5d81613482565b9050919050565b60006020820190508181036000830152613d7d816134e8565b9050919050565b60006020820190508181036000830152613d9d8161354e565b9050919050565b60006020820190508181036000830152613dbd816135b4565b9050919050565b60006020820190508181036000830152613ddd8161361a565b9050919050565b60006020820190508181036000830152613dfd8161365a565b9050919050565b60006020820190508181036000830152613e1d816136c0565b9050919050565b60006020820190508181036000830152613e3d81613700565b9050919050565b60006020820190508181036000830152613e5d81613766565b9050919050565b60006020820190508181036000830152613e7d816137cc565b9050919050565b60006020820190508181036000830152613e9d8161380c565b9050919050565b60006020820190508181036000830152613ebd81613872565b9050919050565b60006020820190508181036000830152613edd816138d8565b9050919050565b60006020820190508181036000830152613efd8161393e565b9050919050565b60006020820190508181036000830152613f1d8161397e565b9050919050565b60006020820190508181036000830152613f3d816139be565b9050919050565b60006020820190508181036000830152613f5d81613a24565b9050919050565b60006020820190508181036000830152613f7d81613a64565b9050919050565b60006020820190508181036000830152613f9d81613aca565b9050919050565b60006020820190508181036000830152613fbd81613b30565b9050919050565b60006020820190508181036000830152613fdd81613b96565b9050919050565b60006020820190508181036000830152613ffd81613bfc565b9050919050565b60006020820190506140196000830184613c4b565b92915050565b6000604051905081810181811067ffffffffffffffff821117156140465761404561445c565b5b8060405250919050565b600067ffffffffffffffff82111561406b5761406a61445c565b5b602082029050602081019050919050565b600067ffffffffffffffff8211156140975761409661445c565b5b601f19601f8301169050602081019050919050565b600067ffffffffffffffff8211156140c7576140c661445c565b5b601f19601f8301169050602081019050919050565b6000819050602082019050919050565b600081519050919050565b600081519050919050565b600081519050919050565b6000602082019050919050565b600082825260208201905092915050565b600082825260208201905092915050565b600082825260208201905092915050565b600081905092915050565b6000614163826142d7565b915061416e836142d7565b9250827fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff038211156141a3576141a26143cf565b5b828201905092915050565b60006141b9826142d7565b91506141c4836142d7565b9250826141d4576141d36143fe565b5b828204905092915050565b60006141ea826142d7565b91506141f5836142d7565b9250817fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff048311821515161561422e5761422d6143cf565b5b828202905092915050565b6000614244826142d7565b915061424f836142d7565b925082821015614262576142616143cf565b5b828203905092915050565b6000614278826142b7565b9050919050565b60008115159050919050565b60007fffffffff0000000000000000000000000000000000000000000000000000000082169050919050565b600073ffffffffffffffffffffffffffffffffffffffff82169050919050565b6000819050919050565b82818337600083830152505050565b60005b8381101561430e5780820151818401526020810190506142f3565b8381111561431d576000848401525b50505050565b6000600282049050600182168061433b57607f821691505b6020821081141561434f5761434e61442d565b5b50919050565b6000614360826142d7565b91507fffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff821415614393576143926143cf565b5b600182019050919050565b60006143a9826142d7565b91506143b4836142d7565b9250826143c4576143c36143fe565b5b828206905092915050565b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601160045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052601260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052602260045260246000fd5b7f4e487b7100000000000000000000000000000000000000000000000000000000600052604160045260246000fd5b6000601f19601f8301169050919050565b6144a58161426d565b81146144b057600080fd5b50565b6144bc8161427f565b81146144c757600080fd5b50565b6144d38161428b565b81146144de57600080fd5b50565b6144ea816142d7565b81146144f557600080fd5b5056fe4552433732313a206f776e657220717565727920666f72206e6f6e6578697374656e7420746f6b656ea264697066735822122021fb5a2265b62e2caa7cfb584ae81a406027030be7912d5896bb8669020036e564736f6c63430008000033

Deployed Bytecode Sourcemap

78681:3214:0:-:0;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;44418:150;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56106:100;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58892:221;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;58422:404;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;81339:116;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;57900:211;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;78803:34;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;59782:305;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;81662:79;;;;;;;;;;;;;:::i;:::-;;57662:162;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;81578:78;;;;;;;;;;;;;:::i;:::-;;60158:151;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;58188:172;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80082:207;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;81467:99;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;55862:177;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;57481:97;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;55567:221;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;70965:148;;;;;;;;;;;;;:::i;:::-;;79130:540;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;81759:123;;;:::i;:::-;;70314:87;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;56275:104;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;59185:295;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;78758:38;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;80300:580;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;60380:285;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;56450:792;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;79682:391;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;59551:164;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;78946:43;;;;;;;;;;;;;:::i;:::-;;;;;;;:::i;:::-;;;;;;;;71268:244;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;80984:309;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;:::i;:::-;;44418:150;44503:4;44527:20;:33;44548:11;44527:33;;;;;;;;;;;;;;;;;;;;;;;;;;;44520:40;;44418:150;;;:::o;56106:100::-;56160:13;56193:5;56186:12;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56106:100;:::o;58892:221::-;58968:7;58996:16;59004:7;58996;:16::i;:::-;58988:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;59081:15;:24;59097:7;59081:24;;;;;;;;;;;;;;;;;;;;;59074:31;;58892:221;;;:::o;58422:404::-;58503:13;58519:23;58534:7;58519:14;:23::i;:::-;58503:39;;58567:5;58561:11;;:2;:11;;;;58553:57;;;;;;;;;;;;:::i;:::-;;;;;;;;;58647:5;58631:21;;:12;:10;:12::i;:::-;:21;;;:69;;;;58656:44;58680:5;58687:12;:10;:12::i;:::-;58656:23;:44::i;:::-;58631:69;58623:161;;;;;;;;;;;;:::i;:::-;;;;;;;;;58797:21;58806:2;58810:7;58797:8;:21::i;:::-;58422:404;;;:::o;81339:116::-;70545:12;:10;:12::i;:::-;70534:23;;:7;:5;:7::i;:::-;:23;;;70526:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;81442:5:::1;81415:24;:32;;;;;;;;;;;;:::i;:::-;;81339:116:::0;:::o;57900:211::-;57961:7;58082:21;:12;:19;:21::i;:::-;58075:28;;57900:211;:::o;78803:34::-;;;;;;;;;;;;;:::o;59782:305::-;59943:41;59962:12;:10;:12::i;:::-;59976:7;59943:18;:41::i;:::-;59935:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;60051:28;60061:4;60067:2;60071:7;60051:9;:28::i;:::-;59782:305;;;:::o;81662:79::-;70545:12;:10;:12::i;:::-;70534:23;;:7;:5;:7::i;:::-;:23;;;70526:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;81728:5:::1;81711:14;;:22;;;;;;;;;;;;;;;;;;81662:79::o:0;57662:162::-;57759:7;57786:30;57810:5;57786:13;:20;57800:5;57786:20;;;;;;;;;;;;;;;:23;;:30;;;;:::i;:::-;57779:37;;57662:162;;;;:::o;81578:78::-;70545:12;:10;:12::i;:::-;70534:23;;:7;:5;:7::i;:::-;:23;;;70526:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;81644:4:::1;81627:14;;:21;;;;;;;;;;;;;;;;;;81578:78::o:0;60158:151::-;60262:39;60279:4;60285:2;60289:7;60262:39;;;;;;;;;;;;:16;:39::i;:::-;60158:151;;;:::o;58188:172::-;58263:7;58284:15;58305:22;58321:5;58305:12;:15;;:22;;;;:::i;:::-;58283:44;;;58345:7;58338:14;;;58188:172;;;:::o;80082:207::-;80141:7;78791:5;80173:3;:15;80165:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;80243:18;80236:25;;80082:207;;;:::o;81467:99::-;70545:12;:10;:12::i;:::-;70534:23;;:7;:5;:7::i;:::-;:23;;;70526:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;81538:20:::1;81550:7;81538:11;:20::i;:::-;81467:99:::0;:::o;55862:177::-;55934:7;55961:70;55978:7;55961:70;;;;;;;;;;;;;;;;;:12;:16;;:70;;;;;:::i;:::-;55954:77;;55862:177;;;:::o;57481:97::-;57529:13;57562:8;57555:15;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;57481:97;:::o;55567:221::-;55639:7;55684:1;55667:19;;:5;:19;;;;55659:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;55751:29;:13;:20;55765:5;55751:20;;;;;;;;;;;;;;;:27;:29::i;:::-;55744:36;;55567:221;;;:::o;70965:148::-;70545:12;:10;:12::i;:::-;70534:23;;:7;:5;:7::i;:::-;:23;;;70526:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;71072:1:::1;71035:40;;71056:6;;;;;;;;;;;71035:40;;;;;;;;;;;;71103:1;71086:6;;:19;;;;;;;;;;;;;;;;;;70965:148::o:0;79130:540::-;79191:16;79221:18;79242:17;79252:6;79242:9;:17::i;:::-;79221:38;;79288:1;79274:10;:15;79270:393;;;79365:1;79351:16;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79344:23;;;;;79270:393;79400:23;79440:10;79426:25;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;79400:51;;79466:13;79494:130;79518:10;79510:5;:18;79494:130;;;79574:34;79594:6;79602:5;79574:19;:34::i;:::-;79558:6;79565:5;79558:13;;;;;;;;;;;;;;;;;;;;;:50;;;;;79530:7;;;;;:::i;:::-;;;;79494:130;;;79645:6;79638:13;;;;;79130:540;;;;:::o;81759:123::-;70545:12;:10;:12::i;:::-;70534:23;;:7;:5;:7::i;:::-;:23;;;70526:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;81834:10:::1;81826:24;;:47;81851:21;81826:47;;;;;;;;;;;;;;;;;;;;;;;81818:56;;;::::0;::::1;;81759:123::o:0;70314:87::-;70360:7;70387:6;;;;;;;;;;;70380:13;;70314:87;:::o;56275:104::-;56331:13;56364:7;56357:14;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56275:104;:::o;59185:295::-;59300:12;:10;:12::i;:::-;59288:24;;:8;:24;;;;59280:62;;;;;;;;;;;;:::i;:::-;;;;;;;;;59400:8;59355:18;:32;59374:12;:10;:12::i;:::-;59355:32;;;;;;;;;;;;;;;:42;59388:8;59355:42;;;;;;;;;;;;;;;;:53;;;;;;;;;;;;;;;;;;59453:8;59424:48;;59439:12;:10;:12::i;:::-;59424:48;;;59463:8;59424:48;;;;;;:::i;:::-;;;;;;;;59185:295;;:::o;78758:38::-;78791:5;78758:38;:::o;80300:580::-;78791:5;80369:13;:11;:13::i;:::-;:25;80361:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;80459:1;80448:8;:12;:30;;;;;80476:2;80464:8;:14;;80448:30;80440:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;78791:5;80542:27;80560:8;80542:13;:11;:13::i;:::-;:17;;:27;;;;:::i;:::-;:40;;80534:83;;;;;;;;;;;;:::i;:::-;;;;;;;;;80649:30;80670:8;80649:16;:14;:16::i;:::-;:20;;:30;;;;:::i;:::-;80636:9;:43;;80628:90;;;;;;;;;;;;:::i;:::-;;;;;;;;;80736:6;80731:140;80752:8;80748:1;:12;80731:140;;;80782:14;80799:13;:11;:13::i;:::-;80782:30;;80827:32;80837:10;80849:9;80827;:32::i;:::-;80731:140;80762:3;;;;;:::i;:::-;;;;80731:140;;;;80300:580;:::o;60380:285::-;60512:41;60531:12;:10;:12::i;:::-;60545:7;60512:18;:41::i;:::-;60504:103;;;;;;;;;;;;:::i;:::-;;;;;;;;;60618:39;60632:4;60638:2;60642:7;60651:5;60618:13;:39::i;:::-;60380:285;;;;:::o;56450:792::-;56523:13;56557:16;56565:7;56557;:16::i;:::-;56549:76;;;;;;;;;;;;:::i;:::-;;;;;;;;;56638:23;56664:10;:19;56675:7;56664:19;;;;;;;;;;;56638:45;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;56694:18;56715:9;:7;:9::i;:::-;56694:30;;56822:1;56806:4;56800:18;:23;56796:72;;;56847:9;56840:16;;;;;;56796:72;56998:1;56978:9;56972:23;:27;56968:108;;;57047:4;57053:9;57030:33;;;;;;;;;:::i;:::-;;;;;;;;;;;;;57016:48;;;;;;56968:108;57208:4;57214:18;:7;:16;:18::i;:::-;57191:42;;;;;;;;;:::i;:::-;;;;;;;;;;;;;57177:57;;;;56450:792;;;;:::o;79682:391::-;79729:7;79775:4;79757:22;;:14;;;;;;;;;;;:22;;;79749:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;78791:5;79831:13;:11;:13::i;:::-;:25;79823:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;79904:18;79925:13;:11;:13::i;:::-;79904:34;;78791:5;79957:13;:25;79949:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;80037:18;80030:25;;;79682:391;:::o;59551:164::-;59648:4;59672:18;:25;59691:5;59672:25;;;;;;;;;;;;;;;:35;59698:8;59672:35;;;;;;;;;;;;;;;;;;;;;;;;;59665:42;;59551:164;;;;:::o;78946:43::-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::o;71268:244::-;70545:12;:10;:12::i;:::-;70534:23;;:7;:5;:7::i;:::-;:23;;;70526:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;71377:1:::1;71357:22;;:8;:22;;;;71349:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;71467:8;71438:38;;71459:6;;;;;;;;;;;71438:38;;;;;;;;;;;;71496:8;71487:6;;:17;;;;;;;;;;;;;;;;;;71268:244:::0;:::o;80984:309::-;70545:12;:10;:12::i;:::-;70534:23;;:7;:5;:7::i;:::-;:23;;;70526:68;;;;;;;;;;;;:::i;:::-;;;;;;;;;81090:3:::1;81074:13;:11;:13::i;:::-;:19;81066:48;;;;;;;;;;;;:::i;:::-;;;;;;;;;81130:9;81125:161;81149:13;:20;81145:1;:24;81125:161;;;81191:14;81208:13;:11;:13::i;:::-;81191:30;;81236:38;81246:13;81260:1;81246:16;;;;;;;;;;;;;;;;;;;;;;81264:9;81236;:38::i;:::-;81125:161;81171:3;;;;;:::i;:::-;;;;81125:161;;;;80984:309:::0;:::o;62132:127::-;62197:4;62221:30;62243:7;62221:12;:21;;:30;;;;:::i;:::-;62214:37;;62132:127;;;:::o;53349:98::-;53402:7;53429:10;53422:17;;53349:98;:::o;68278:183::-;68371:2;68344:15;:24;68360:7;68344:24;;;;;;;;;;;;:29;;;;;;;;;;;;;;;;;;68427:7;68423:2;68389:46;;68398:23;68413:7;68398:14;:23::i;:::-;68389:46;;;;;;;;;;;;68278:183;;:::o;22875:123::-;22944:7;22971:19;22979:3;:10;;22971:7;:19::i;:::-;22964:26;;22875:123;;;:::o;62426:355::-;62519:4;62544:16;62552:7;62544;:16::i;:::-;62536:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;62620:13;62636:23;62651:7;62636:14;:23::i;:::-;62620:39;;62689:5;62678:16;;:7;:16;;;:51;;;;62722:7;62698:31;;:20;62710:7;62698:11;:20::i;:::-;:31;;;62678:51;:94;;;;62733:39;62757:5;62764:7;62733:23;:39::i;:::-;62678:94;62670:103;;;62426:355;;;;:::o;65562:599::-;65687:4;65660:31;;:23;65675:7;65660:14;:23::i;:::-;:31;;;65652:85;;;;;;;;;;;;:::i;:::-;;;;;;;;;65788:1;65774:16;;:2;:16;;;;65766:65;;;;;;;;;;;;:::i;:::-;;;;;;;;;65844:39;65865:4;65871:2;65875:7;65844:20;:39::i;:::-;65948:29;65965:1;65969:7;65948:8;:29::i;:::-;65990:35;66017:7;65990:13;:19;66004:4;65990:19;;;;;;;;;;;;;;;:26;;:35;;;;:::i;:::-;;66036:30;66058:7;66036:13;:17;66050:2;66036:17;;;;;;;;;;;;;;;:21;;:30;;;;:::i;:::-;;66079:29;66096:7;66105:2;66079:12;:16;;:29;;;;;:::i;:::-;;66145:7;66141:2;66126:27;;66135:4;66126:27;;;;;;;;;;;;65562:599;;;:::o;34449:137::-;34520:7;34555:22;34559:3;:10;;34571:5;34555:3;:22::i;:::-;34547:31;;34540:38;;34449:137;;;;:::o;23337:236::-;23417:7;23426;23447:11;23460:13;23477:22;23481:3;:10;;23493:5;23477:3;:22::i;:::-;23446:53;;;;23526:3;23518:12;;23556:5;23548:14;;23510:55;;;;;;23337:236;;;;;:::o;66762:100::-;66846:8;66835;:19;;;;;;;;;;;;:::i;:::-;;66762:100;:::o;24623:213::-;24730:7;24781:44;24786:3;:10;;24806:3;24798:12;;24812;24781:4;:44::i;:::-;24773:53;;24750:78;;24623:213;;;;;:::o;33991:114::-;34051:7;34078:19;34086:3;:10;;34078:7;:19::i;:::-;34071:26;;33991:114;;;:::o;74354:98::-;74412:7;74443:1;74439;:5;;;;:::i;:::-;74432:12;;74354:98;;;;:::o;75092:::-;75150:7;75181:1;75177;:5;;;;:::i;:::-;75170:12;;75092:98;;;;:::o;63124:110::-;63200:26;63210:2;63214:7;63200:26;;;;;;;;;;;;:9;:26::i;:::-;63124:110;;:::o;61547:272::-;61661:28;61671:4;61677:2;61681:7;61661:9;:28::i;:::-;61708:48;61731:4;61737:2;61741:7;61750:5;61708:22;:48::i;:::-;61700:111;;;;;;;;;;;;:::i;:::-;;;;;;;;;61547:272;;;;:::o;13019:723::-;13075:13;13305:1;13296:5;:10;13292:53;;;13323:10;;;;;;;;;;;;;;;;;;;;;13292:53;13355:12;13370:5;13355:20;;13386:14;13411:78;13426:1;13418:4;:9;13411:78;;13444:8;;;;;:::i;:::-;;;;13475:2;13467:10;;;;;:::i;:::-;;;13411:78;;;13499:19;13531:6;13521:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;13499:39;;13549:154;13565:1;13556:5;:10;13549:154;;13593:1;13583:11;;;;;:::i;:::-;;;13660:2;13652:5;:10;;;;:::i;:::-;13639:2;:24;;;;:::i;:::-;13626:39;;13609:6;13616;13609:14;;;;;;;;;;;;;;;;;;;:56;;;;;;;;;;;13689:2;13680:11;;;;;:::i;:::-;;;13549:154;;;13727:6;13713:21;;;;;13019:723;;;;:::o;22636:151::-;22720:4;22744:35;22754:3;:10;;22774:3;22766:12;;22744:9;:35::i;:::-;22737:42;;22636:151;;;;:::o;19454:110::-;19510:7;19537:3;:12;;:19;;;;19530:26;;19454:110;;;:::o;69074:93::-;;;;:::o;33536:137::-;33606:4;33630:35;33638:3;:10;;33658:5;33650:14;;33630:7;:35::i;:::-;33623:42;;33536:137;;;;:::o;33229:131::-;33296:4;33320:32;33325:3;:10;;33345:5;33337:14;;33320:4;:32::i;:::-;33313:39;;33229:131;;;;:::o;22059:185::-;22148:4;22172:64;22177:3;:10;;22197:3;22189:12;;22227:5;22211:23;;22203:32;;22172:4;:64::i;:::-;22165:71;;22059:185;;;;;:::o;29487:204::-;29554:7;29603:5;29582:3;:11;;:18;;;;:26;29574:73;;;;;;;;;;;;:::i;:::-;;;;;;;;;29665:3;:11;;29677:5;29665:18;;;;;;;;;;;;;;;;;;;;;;;;29658:25;;29487:204;;;;:::o;19919:279::-;19986:7;19995;20045:5;20023:3;:12;;:19;;;;:27;20015:74;;;;;;;;;;;;:::i;:::-;;;;;;;;;20102:22;20127:3;:12;;20140:5;20127:19;;;;;;;;;;;;;;;;;;;;;;;;;;20102:44;;20165:5;:10;;;20177:5;:12;;;20157:33;;;;;19919:279;;;;;:::o;21416:319::-;21510:7;21530:16;21549:3;:12;;:17;21562:3;21549:17;;;;;;;;;;;;21530:36;;21597:1;21585:8;:13;;21600:12;21577:36;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;21667:3;:12;;21691:1;21680:8;:12;;;;:::i;:::-;21667:26;;;;;;;;;;;;;;;;;;;;;;;;;;:33;;;21660:40;;;21416:319;;;;;:::o;29034:109::-;29090:7;29117:3;:11;;:18;;;;29110:25;;29034:109;;;:::o;63461:250::-;63557:18;63563:2;63567:7;63557:5;:18::i;:::-;63594:54;63625:1;63629:2;63633:7;63642:5;63594:22;:54::i;:::-;63586:117;;;;;;;;;;;;:::i;:::-;;;;;;;;;63461:250;;;:::o;67427:843::-;67548:4;67574:15;:2;:13;;;:15::i;:::-;67570:693;;;67626:2;67610:36;;;67647:12;:10;:12::i;:::-;67661:4;67667:7;67676:5;67610:72;;;;;;;;;;;;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;67606:602;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;67873:1;67856:6;:13;:18;67852:341;;;67899:60;;;;;;;;;;:::i;:::-;;;;;;;;67852:341;68143:6;68137:13;68128:6;68124:2;68120:15;68113:38;67606:602;67743:45;;;67733:55;;;:6;:55;;;;67726:62;;;;;67570:693;68247:4;68240:11;;67427:843;;;;;;;:::o;19234:125::-;19305:4;19350:1;19329:3;:12;;:17;19342:3;19329:17;;;;;;;;;;;;:22;;19322:29;;19234:125;;;;:::o;27189:1544::-;27255:4;27373:18;27394:3;:12;;:19;27407:5;27394:19;;;;;;;;;;;;27373:40;;27444:1;27430:10;:15;27426:1300;;27792:21;27829:1;27816:10;:14;;;;:::i;:::-;27792:38;;27845:17;27886:1;27865:3;:11;;:18;;;;:22;;;;:::i;:::-;27845:42;;28132:17;28152:3;:11;;28164:9;28152:22;;;;;;;;;;;;;;;;;;;;;;;;28132:42;;28298:9;28269:3;:11;;28281:13;28269:26;;;;;;;;;;;;;;;;;;;;;;;:38;;;;28417:1;28401:13;:17;;;;:::i;:::-;28375:3;:12;;:23;28388:9;28375:23;;;;;;;;;;;:43;;;;28527:3;:11;;:17;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;28622:3;:12;;:19;28635:5;28622:19;;;;;;;;;;;28615:26;;;28665:4;28658:11;;;;;;;;27426:1300;28709:5;28702:12;;;27189:1544;;;;;:::o;26599:414::-;26662:4;26684:21;26694:3;26699:5;26684:9;:21::i;:::-;26679:327;;26722:3;:11;;26739:5;26722:23;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;26905:3;:11;;:18;;;;26883:3;:12;;:19;26896:5;26883:19;;;;;;;;;;;:40;;;;26945:4;26938:11;;;;26679:327;26989:5;26982:12;;26599:414;;;;;:::o;16734:692::-;16810:4;16926:16;16945:3;:12;;:17;16958:3;16945:17;;;;;;;;;;;;16926:36;;16991:1;16979:8;:13;16975:444;;;17046:3;:12;;17064:38;;;;;;;;17081:3;17064:38;;;;17094:5;17064:38;;;17046:57;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;17261:3;:12;;:19;;;;17241:3;:12;;:17;17254:3;17241:17;;;;;;;;;;;:39;;;;17302:4;17295:11;;;;;16975:444;17375:5;17339:3;:12;;17363:1;17352:8;:12;;;;:::i;:::-;17339:26;;;;;;;;;;;;;;;;;;;;;;;;;;:33;;:41;;;;17402:5;17395:12;;;16734:692;;;;;;:::o;64047:404::-;64141:1;64127:16;;:2;:16;;;;64119:61;;;;;;;;;;;;:::i;:::-;;;;;;;;;64200:16;64208:7;64200;:16::i;:::-;64199:17;64191:58;;;;;;;;;;;;:::i;:::-;;;;;;;;;64262:45;64291:1;64295:2;64299:7;64262:20;:45::i;:::-;64320:30;64342:7;64320:13;:17;64334:2;64320:17;;;;;;;;;;;;;;;:21;;:30;;;;:::i;:::-;;64363:29;64380:7;64389:2;64363:12;:16;;:29;;;;;:::i;:::-;;64435:7;64431:2;64410:33;;64427:1;64410:33;;;;;;;;;;;;64047:404;;:::o;35401:422::-;35461:4;35669:12;35780:7;35768:20;35760:28;;35814:1;35807:4;:8;35800:15;;;35401:422;;;:::o;28819:129::-;28892:4;28939:1;28916:3;:12;;:19;28929:5;28916:19;;;;;;;;;;;;:24;;28909:31;;28819:129;;;;:::o;-1:-1:-1:-;;;;;;;:::i;:::-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;:::i;:::-;;;:::o;:::-;;;;;;;;;;;;;;;;;;;;;:::o;24:622:1:-;;145:80;160:64;217:6;160:64;:::i;:::-;145:80;:::i;:::-;136:89;;245:5;273:6;266:5;259:21;299:4;292:5;288:16;281:23;;324:6;374:3;366:4;358:6;354:17;349:3;345:27;342:36;339:2;;;391:1;388;381:12;339:2;419:1;404:236;429:6;426:1;423:13;404:236;;;496:3;524:37;557:3;545:10;524:37;:::i;:::-;519:3;512:50;591:4;586:3;582:14;575:21;;625:4;620:3;616:14;609:21;;464:176;451:1;448;444:9;439:14;;404:236;;;408:14;126:520;;;;;;;:::o;652:342::-;;754:64;769:48;810:6;769:48;:::i;:::-;754:64;:::i;:::-;745:73;;841:6;834:5;827:21;879:4;872:5;868:16;917:3;908:6;903:3;899:16;896:25;893:2;;;934:1;931;924:12;893:2;947:41;981:6;976:3;971;947:41;:::i;:::-;735:259;;;;;;:::o;1000:344::-;;1103:65;1118:49;1160:6;1118:49;:::i;:::-;1103:65;:::i;:::-;1094:74;;1191:6;1184:5;1177:21;1229:4;1222:5;1218:16;1267:3;1258:6;1253:3;1249:16;1246:25;1243:2;;;1284:1;1281;1274:12;1243:2;1297:41;1331:6;1326:3;1321;1297:41;:::i;:::-;1084:260;;;;;;:::o;1350:139::-;;1434:6;1421:20;1412:29;;1450:33;1477:5;1450:33;:::i;:::-;1402:87;;;;:::o;1512:303::-;;1632:3;1625:4;1617:6;1613:17;1609:27;1599:2;;1650:1;1647;1640:12;1599:2;1690:6;1677:20;1715:94;1805:3;1797:6;1790:4;1782:6;1778:17;1715:94;:::i;:::-;1706:103;;1589:226;;;;;:::o;1821:133::-;;1902:6;1889:20;1880:29;;1918:30;1942:5;1918:30;:::i;:::-;1870:84;;;;:::o;1960:137::-;;2043:6;2030:20;2021:29;;2059:32;2085:5;2059:32;:::i;:::-;2011:86;;;;:::o;2103:141::-;;2190:6;2184:13;2175:22;;2206:32;2232:5;2206:32;:::i;:::-;2165:79;;;;:::o;2263:271::-;;2367:3;2360:4;2352:6;2348:17;2344:27;2334:2;;2385:1;2382;2375:12;2334:2;2425:6;2412:20;2450:78;2524:3;2516:6;2509:4;2501:6;2497:17;2450:78;:::i;:::-;2441:87;;2324:210;;;;;:::o;2554:273::-;;2659:3;2652:4;2644:6;2640:17;2636:27;2626:2;;2677:1;2674;2667:12;2626:2;2717:6;2704:20;2742:79;2817:3;2809:6;2802:4;2794:6;2790:17;2742:79;:::i;:::-;2733:88;;2616:211;;;;;:::o;2833:139::-;;2917:6;2904:20;2895:29;;2933:33;2960:5;2933:33;:::i;:::-;2885:87;;;;:::o;2978:262::-;;3086:2;3074:9;3065:7;3061:23;3057:32;3054:2;;;3102:1;3099;3092:12;3054:2;3145:1;3170:53;3215:7;3206:6;3195:9;3191:22;3170:53;:::i;:::-;3160:63;;3116:117;3044:196;;;;:::o;3246:407::-;;;3371:2;3359:9;3350:7;3346:23;3342:32;3339:2;;;3387:1;3384;3377:12;3339:2;3430:1;3455:53;3500:7;3491:6;3480:9;3476:22;3455:53;:::i;:::-;3445:63;;3401:117;3557:2;3583:53;3628:7;3619:6;3608:9;3604:22;3583:53;:::i;:::-;3573:63;;3528:118;3329:324;;;;;:::o;3659:552::-;;;;3801:2;3789:9;3780:7;3776:23;3772:32;3769:2;;;3817:1;3814;3807:12;3769:2;3860:1;3885:53;3930:7;3921:6;3910:9;3906:22;3885:53;:::i;:::-;3875:63;;3831:117;3987:2;4013:53;4058:7;4049:6;4038:9;4034:22;4013:53;:::i;:::-;4003:63;;3958:118;4115:2;4141:53;4186:7;4177:6;4166:9;4162:22;4141:53;:::i;:::-;4131:63;;4086:118;3759:452;;;;;:::o;4217:809::-;;;;;4385:3;4373:9;4364:7;4360:23;4356:33;4353:2;;;4402:1;4399;4392:12;4353:2;4445:1;4470:53;4515:7;4506:6;4495:9;4491:22;4470:53;:::i;:::-;4460:63;;4416:117;4572:2;4598:53;4643:7;4634:6;4623:9;4619:22;4598:53;:::i;:::-;4588:63;;4543:118;4700:2;4726:53;4771:7;4762:6;4751:9;4747:22;4726:53;:::i;:::-;4716:63;;4671:118;4856:2;4845:9;4841:18;4828:32;4887:18;4879:6;4876:30;4873:2;;;4919:1;4916;4909:12;4873:2;4947:62;5001:7;4992:6;4981:9;4977:22;4947:62;:::i;:::-;4937:72;;4799:220;4343:683;;;;;;;:::o;5032:401::-;;;5154:2;5142:9;5133:7;5129:23;5125:32;5122:2;;;5170:1;5167;5160:12;5122:2;5213:1;5238:53;5283:7;5274:6;5263:9;5259:22;5238:53;:::i;:::-;5228:63;;5184:117;5340:2;5366:50;5408:7;5399:6;5388:9;5384:22;5366:50;:::i;:::-;5356:60;;5311:115;5112:321;;;;;:::o;5439:407::-;;;5564:2;5552:9;5543:7;5539:23;5535:32;5532:2;;;5580:1;5577;5570:12;5532:2;5623:1;5648:53;5693:7;5684:6;5673:9;5669:22;5648:53;:::i;:::-;5638:63;;5594:117;5750:2;5776:53;5821:7;5812:6;5801:9;5797:22;5776:53;:::i;:::-;5766:63;;5721:118;5522:324;;;;;:::o;5852:405::-;;5985:2;5973:9;5964:7;5960:23;5956:32;5953:2;;;6001:1;5998;5991:12;5953:2;6072:1;6061:9;6057:17;6044:31;6102:18;6094:6;6091:30;6088:2;;;6134:1;6131;6124:12;6088:2;6162:78;6232:7;6223:6;6212:9;6208:22;6162:78;:::i;:::-;6152:88;;6015:235;5943:314;;;;:::o;6263:260::-;;6370:2;6358:9;6349:7;6345:23;6341:32;6338:2;;;6386:1;6383;6376:12;6338:2;6429:1;6454:52;6498:7;6489:6;6478:9;6474:22;6454:52;:::i;:::-;6444:62;;6400:116;6328:195;;;;:::o;6529:282::-;;6647:2;6635:9;6626:7;6622:23;6618:32;6615:2;;;6663:1;6660;6653:12;6615:2;6706:1;6731:63;6786:7;6777:6;6766:9;6762:22;6731:63;:::i;:::-;6721:73;;6677:127;6605:206;;;;:::o;6817:375::-;;6935:2;6923:9;6914:7;6910:23;6906:32;6903:2;;;6951:1;6948;6941:12;6903:2;7022:1;7011:9;7007:17;6994:31;7052:18;7044:6;7041:30;7038:2;;;7084:1;7081;7074:12;7038:2;7112:63;7167:7;7158:6;7147:9;7143:22;7112:63;:::i;:::-;7102:73;;6965:220;6893:299;;;;:::o;7198:262::-;;7306:2;7294:9;7285:7;7281:23;7277:32;7274:2;;;7322:1;7319;7312:12;7274:2;7365:1;7390:53;7435:7;7426:6;7415:9;7411:22;7390:53;:::i;:::-;7380:63;;7336:117;7264:196;;;;:::o;7466:179::-;;7556:46;7598:3;7590:6;7556:46;:::i;:::-;7634:4;7629:3;7625:14;7611:28;;7546:99;;;;:::o;7651:118::-;7738:24;7756:5;7738:24;:::i;:::-;7733:3;7726:37;7716:53;;:::o;7805:732::-;;7953:54;8001:5;7953:54;:::i;:::-;8023:86;8102:6;8097:3;8023:86;:::i;:::-;8016:93;;8133:56;8183:5;8133:56;:::i;:::-;8212:7;8243:1;8228:284;8253:6;8250:1;8247:13;8228:284;;;8329:6;8323:13;8356:63;8415:3;8400:13;8356:63;:::i;:::-;8349:70;;8442:60;8495:6;8442:60;:::i;:::-;8432:70;;8288:224;8275:1;8272;8268:9;8263:14;;8228:284;;;8232:14;8528:3;8521:10;;7929:608;;;;;;;:::o;8543:109::-;8624:21;8639:5;8624:21;:::i;:::-;8619:3;8612:34;8602:50;;:::o;8658:360::-;;8772:38;8804:5;8772:38;:::i;:::-;8826:70;8889:6;8884:3;8826:70;:::i;:::-;8819:77;;8905:52;8950:6;8945:3;8938:4;8931:5;8927:16;8905:52;:::i;:::-;8982:29;9004:6;8982:29;:::i;:::-;8977:3;8973:39;8966:46;;8748:270;;;;;:::o;9024:364::-;;9140:39;9173:5;9140:39;:::i;:::-;9195:71;9259:6;9254:3;9195:71;:::i;:::-;9188:78;;9275:52;9320:6;9315:3;9308:4;9301:5;9297:16;9275:52;:::i;:::-;9352:29;9374:6;9352:29;:::i;:::-;9347:3;9343:39;9336:46;;9116:272;;;;;:::o;9394:377::-;;9528:39;9561:5;9528:39;:::i;:::-;9583:89;9665:6;9660:3;9583:89;:::i;:::-;9576:96;;9681:52;9726:6;9721:3;9714:4;9707:5;9703:16;9681:52;:::i;:::-;9758:6;9753:3;9749:16;9742:23;;9504:267;;;;;:::o;9777:366::-;;9940:67;10004:2;9999:3;9940:67;:::i;:::-;9933:74;;10037:34;10033:1;10028:3;10024:11;10017:55;10103:4;10098:2;10093:3;10089:12;10082:26;10134:2;10129:3;10125:12;10118:19;;9923:220;;;:::o;10149:372::-;;10312:67;10376:2;10371:3;10312:67;:::i;:::-;10305:74;;10409:34;10405:1;10400:3;10396:11;10389:55;10475:10;10470:2;10465:3;10461:12;10454:32;10512:2;10507:3;10503:12;10496:19;;10295:226;;;:::o;10527:382::-;;10690:67;10754:2;10749:3;10690:67;:::i;:::-;10683:74;;10787:34;10783:1;10778:3;10774:11;10767:55;10853:20;10848:2;10843:3;10839:12;10832:42;10900:2;10895:3;10891:12;10884:19;;10673:236;;;:::o;10915:370::-;;11078:67;11142:2;11137:3;11078:67;:::i;:::-;11071:74;;11175:34;11171:1;11166:3;11162:11;11155:55;11241:8;11236:2;11231:3;11227:12;11220:30;11276:2;11271:3;11267:12;11260:19;;11061:224;;;:::o;11291:326::-;;11454:67;11518:2;11513:3;11454:67;:::i;:::-;11447:74;;11551:30;11547:1;11542:3;11538:11;11531:51;11608:2;11603:3;11599:12;11592:19;;11437:180;;;:::o;11623:368::-;;11786:67;11850:2;11845:3;11786:67;:::i;:::-;11779:74;;11883:34;11879:1;11874:3;11870:11;11863:55;11949:6;11944:2;11939:3;11935:12;11928:28;11982:2;11977:3;11973:12;11966:19;;11769:222;;;:::o;11997:323::-;;12160:67;12224:2;12219:3;12160:67;:::i;:::-;12153:74;;12257:27;12253:1;12248:3;12244:11;12237:48;12311:2;12306:3;12302:12;12295:19;;12143:177;;;:::o;12326:376::-;;12489:67;12553:2;12548:3;12489:67;:::i;:::-;12482:74;;12586:34;12582:1;12577:3;12573:11;12566:55;12652:14;12647:2;12642:3;12638:12;12631:36;12693:2;12688:3;12684:12;12677:19;;12472:230;;;:::o;12708:388::-;;12871:67;12935:2;12930:3;12871:67;:::i;:::-;12864:74;;12968:34;12964:1;12959:3;12955:11;12948:55;13034:26;13029:2;13024:3;13020:12;13013:48;13087:2;13082:3;13078:12;13071:19;;12854:242;;;:::o;13102:314::-;;13265:67;13329:2;13324:3;13265:67;:::i;:::-;13258:74;;13362:18;13358:1;13353:3;13349:11;13342:39;13407:2;13402:3;13398:12;13391:19;;13248:168;;;:::o;13422:374::-;;13585:67;13649:2;13644:3;13585:67;:::i;:::-;13578:74;;13682:34;13678:1;13673:3;13669:11;13662:55;13748:12;13743:2;13738:3;13734:12;13727:34;13787:2;13782:3;13778:12;13771:19;;13568:228;;;:::o;13802:366::-;;13965:67;14029:2;14024:3;13965:67;:::i;:::-;13958:74;;14062:34;14058:1;14053:3;14049:11;14042:55;14128:4;14123:2;14118:3;14114:12;14107:26;14159:2;14154:3;14150:12;14143:19;;13948:220;;;:::o;14174:366::-;;14337:67;14401:2;14396:3;14337:67;:::i;:::-;14330:74;;14434:34;14430:1;14425:3;14421:11;14414:55;14500:4;14495:2;14490:3;14486:12;14479:26;14531:2;14526:3;14522:12;14515:19;;14320:220;;;:::o;14546:324::-;;14709:67;14773:2;14768:3;14709:67;:::i;:::-;14702:74;;14806:28;14802:1;14797:3;14793:11;14786:49;14861:2;14856:3;14852:12;14845:19;;14692:178;;;:::o;14876:330::-;;15039:67;15103:2;15098:3;15039:67;:::i;:::-;15032:74;;15136:34;15132:1;15127:3;15123:11;15116:55;15197:2;15192:3;15188:12;15181:19;;15022:184;;;:::o;15212:376::-;;15375:67;15439:2;15434:3;15375:67;:::i;:::-;15368:74;;15472:34;15468:1;15463:3;15459:11;15452:55;15538:14;15533:2;15528:3;15524:12;15517:36;15579:2;15574:3;15570:12;15563:19;;15358:230;;;:::o;15594:330::-;;15757:67;15821:2;15816:3;15757:67;:::i;:::-;15750:74;;15854:34;15850:1;15845:3;15841:11;15834:55;15915:2;15910:3;15906:12;15899:19;;15740:184;;;:::o;15930:373::-;;16093:67;16157:2;16152:3;16093:67;:::i;:::-;16086:74;;16190:34;16186:1;16181:3;16177:11;16170:55;16256:11;16251:2;16246:3;16242:12;16235:33;16294:2;16289:3;16285:12;16278:19;;16076:227;;;:::o;16309:379::-;;16472:67;16536:2;16531:3;16472:67;:::i;:::-;16465:74;;16569:34;16565:1;16560:3;16556:11;16549:55;16635:17;16630:2;16625:3;16621:12;16614:39;16679:2;16674:3;16670:12;16663:19;;16455:233;;;:::o;16694:365::-;;16857:67;16921:2;16916:3;16857:67;:::i;:::-;16850:74;;16954:34;16950:1;16945:3;16941:11;16934:55;17020:3;17015:2;17010:3;17006:12;16999:25;17050:2;17045:3;17041:12;17034:19;;16840:219;;;:::o;17065:381::-;;17228:67;17292:2;17287:3;17228:67;:::i;:::-;17221:74;;17325:34;17321:1;17316:3;17312:11;17305:55;17391:19;17386:2;17381:3;17377:12;17370:41;17437:2;17432:3;17428:12;17421:19;;17211:235;;;:::o;17452:328::-;;17615:67;17679:2;17674:3;17615:67;:::i;:::-;17608:74;;17712:32;17708:1;17703:3;17699:11;17692:53;17771:2;17766:3;17762:12;17755:19;;17598:182;;;:::o;17786:108::-;17863:24;17881:5;17863:24;:::i;:::-;17858:3;17851:37;17841:53;;:::o;17900:118::-;17987:24;18005:5;17987:24;:::i;:::-;17982:3;17975:37;17965:53;;:::o;18024:435::-;;18226:95;18317:3;18308:6;18226:95;:::i;:::-;18219:102;;18338:95;18429:3;18420:6;18338:95;:::i;:::-;18331:102;;18450:3;18443:10;;18208:251;;;;;:::o;18465:222::-;;18596:2;18585:9;18581:18;18573:26;;18609:71;18677:1;18666:9;18662:17;18653:6;18609:71;:::i;:::-;18563:124;;;;:::o;18693:640::-;;18926:3;18915:9;18911:19;18903:27;;18940:71;19008:1;18997:9;18993:17;18984:6;18940:71;:::i;:::-;19021:72;19089:2;19078:9;19074:18;19065:6;19021:72;:::i;:::-;19103;19171:2;19160:9;19156:18;19147:6;19103:72;:::i;:::-;19222:9;19216:4;19212:20;19207:2;19196:9;19192:18;19185:48;19250:76;19321:4;19312:6;19250:76;:::i;:::-;19242:84;;18893:440;;;;;;;:::o;19339:373::-;;19520:2;19509:9;19505:18;19497:26;;19569:9;19563:4;19559:20;19555:1;19544:9;19540:17;19533:47;19597:108;19700:4;19691:6;19597:108;:::i;:::-;19589:116;;19487:225;;;;:::o;19718:210::-;;19843:2;19832:9;19828:18;19820:26;;19856:65;19918:1;19907:9;19903:17;19894:6;19856:65;:::i;:::-;19810:118;;;;:::o;19934:313::-;;20085:2;20074:9;20070:18;20062:26;;20134:9;20128:4;20124:20;20120:1;20109:9;20105:17;20098:47;20162:78;20235:4;20226:6;20162:78;:::i;:::-;20154:86;;20052:195;;;;:::o;20253:419::-;;20457:2;20446:9;20442:18;20434:26;;20506:9;20500:4;20496:20;20492:1;20481:9;20477:17;20470:47;20534:131;20660:4;20534:131;:::i;:::-;20526:139;;20424:248;;;:::o;20678:419::-;;20882:2;20871:9;20867:18;20859:26;;20931:9;20925:4;20921:20;20917:1;20906:9;20902:17;20895:47;20959:131;21085:4;20959:131;:::i;:::-;20951:139;;20849:248;;;:::o;21103:419::-;;21307:2;21296:9;21292:18;21284:26;;21356:9;21350:4;21346:20;21342:1;21331:9;21327:17;21320:47;21384:131;21510:4;21384:131;:::i;:::-;21376:139;;21274:248;;;:::o;21528:419::-;;21732:2;21721:9;21717:18;21709:26;;21781:9;21775:4;21771:20;21767:1;21756:9;21752:17;21745:47;21809:131;21935:4;21809:131;:::i;:::-;21801:139;;21699:248;;;:::o;21953:419::-;;22157:2;22146:9;22142:18;22134:26;;22206:9;22200:4;22196:20;22192:1;22181:9;22177:17;22170:47;22234:131;22360:4;22234:131;:::i;:::-;22226:139;;22124:248;;;:::o;22378:419::-;;22582:2;22571:9;22567:18;22559:26;;22631:9;22625:4;22621:20;22617:1;22606:9;22602:17;22595:47;22659:131;22785:4;22659:131;:::i;:::-;22651:139;;22549:248;;;:::o;22803:419::-;;23007:2;22996:9;22992:18;22984:26;;23056:9;23050:4;23046:20;23042:1;23031:9;23027:17;23020:47;23084:131;23210:4;23084:131;:::i;:::-;23076:139;;22974:248;;;:::o;23228:419::-;;23432:2;23421:9;23417:18;23409:26;;23481:9;23475:4;23471:20;23467:1;23456:9;23452:17;23445:47;23509:131;23635:4;23509:131;:::i;:::-;23501:139;;23399:248;;;:::o;23653:419::-;;23857:2;23846:9;23842:18;23834:26;;23906:9;23900:4;23896:20;23892:1;23881:9;23877:17;23870:47;23934:131;24060:4;23934:131;:::i;:::-;23926:139;;23824:248;;;:::o;24078:419::-;;24282:2;24271:9;24267:18;24259:26;;24331:9;24325:4;24321:20;24317:1;24306:9;24302:17;24295:47;24359:131;24485:4;24359:131;:::i;:::-;24351:139;;24249:248;;;:::o;24503:419::-;;24707:2;24696:9;24692:18;24684:26;;24756:9;24750:4;24746:20;24742:1;24731:9;24727:17;24720:47;24784:131;24910:4;24784:131;:::i;:::-;24776:139;;24674:248;;;:::o;24928:419::-;;25132:2;25121:9;25117:18;25109:26;;25181:9;25175:4;25171:20;25167:1;25156:9;25152:17;25145:47;25209:131;25335:4;25209:131;:::i;:::-;25201:139;;25099:248;;;:::o;25353:419::-;;25557:2;25546:9;25542:18;25534:26;;25606:9;25600:4;25596:20;25592:1;25581:9;25577:17;25570:47;25634:131;25760:4;25634:131;:::i;:::-;25626:139;;25524:248;;;:::o;25778:419::-;;25982:2;25971:9;25967:18;25959:26;;26031:9;26025:4;26021:20;26017:1;26006:9;26002:17;25995:47;26059:131;26185:4;26059:131;:::i;:::-;26051:139;;25949:248;;;:::o;26203:419::-;;26407:2;26396:9;26392:18;26384:26;;26456:9;26450:4;26446:20;26442:1;26431:9;26427:17;26420:47;26484:131;26610:4;26484:131;:::i;:::-;26476:139;;26374:248;;;:::o;26628:419::-;;26832:2;26821:9;26817:18;26809:26;;26881:9;26875:4;26871:20;26867:1;26856:9;26852:17;26845:47;26909:131;27035:4;26909:131;:::i;:::-;26901:139;;26799:248;;;:::o;27053:419::-;;27257:2;27246:9;27242:18;27234:26;;27306:9;27300:4;27296:20;27292:1;27281:9;27277:17;27270:47;27334:131;27460:4;27334:131;:::i;:::-;27326:139;;27224:248;;;:::o;27478:419::-;;27682:2;27671:9;27667:18;27659:26;;27731:9;27725:4;27721:20;27717:1;27706:9;27702:17;27695:47;27759:131;27885:4;27759:131;:::i;:::-;27751:139;;27649:248;;;:::o;27903:419::-;;28107:2;28096:9;28092:18;28084:26;;28156:9;28150:4;28146:20;28142:1;28131:9;28127:17;28120:47;28184:131;28310:4;28184:131;:::i;:::-;28176:139;;28074:248;;;:::o;28328:419::-;;28532:2;28521:9;28517:18;28509:26;;28581:9;28575:4;28571:20;28567:1;28556:9;28552:17;28545:47;28609:131;28735:4;28609:131;:::i;:::-;28601:139;;28499:248;;;:::o;28753:419::-;;28957:2;28946:9;28942:18;28934:26;;29006:9;29000:4;28996:20;28992:1;28981:9;28977:17;28970:47;29034:131;29160:4;29034:131;:::i;:::-;29026:139;;28924:248;;;:::o;29178:419::-;;29382:2;29371:9;29367:18;29359:26;;29431:9;29425:4;29421:20;29417:1;29406:9;29402:17;29395:47;29459:131;29585:4;29459:131;:::i;:::-;29451:139;;29349:248;;;:::o;29603:222::-;;29734:2;29723:9;29719:18;29711:26;;29747:71;29815:1;29804:9;29800:17;29791:6;29747:71;:::i;:::-;29701:124;;;;:::o;29831:283::-;;29897:2;29891:9;29881:19;;29939:4;29931:6;29927:17;30046:6;30034:10;30031:22;30010:18;29998:10;29995:34;29992:62;29989:2;;;30057:18;;:::i;:::-;29989:2;30097:10;30093:2;30086:22;29871:243;;;;:::o;30120:311::-;;30287:18;30279:6;30276:30;30273:2;;;30309:18;;:::i;:::-;30273:2;30359:4;30351:6;30347:17;30339:25;;30419:4;30413;30409:15;30401:23;;30202:229;;;:::o;30437:331::-;;30588:18;30580:6;30577:30;30574:2;;;30610:18;;:::i;:::-;30574:2;30695:4;30691:9;30684:4;30676:6;30672:17;30668:33;30660:41;;30756:4;30750;30746:15;30738:23;;30503:265;;;:::o;30774:332::-;;30926:18;30918:6;30915:30;30912:2;;;30948:18;;:::i;:::-;30912:2;31033:4;31029:9;31022:4;31014:6;31010:17;31006:33;30998:41;;31094:4;31088;31084:15;31076:23;;30841:265;;;:::o;31112:132::-;;31202:3;31194:11;;31232:4;31227:3;31223:14;31215:22;;31184:60;;;:::o;31250:114::-;;31351:5;31345:12;31335:22;;31324:40;;;:::o;31370:98::-;;31455:5;31449:12;31439:22;;31428:40;;;:::o;31474:99::-;;31560:5;31554:12;31544:22;;31533:40;;;:::o;31579:113::-;;31681:4;31676:3;31672:14;31664:22;;31654:38;;;:::o;31698:184::-;;31831:6;31826:3;31819:19;31871:4;31866:3;31862:14;31847:29;;31809:73;;;;:::o;31888:168::-;;32005:6;32000:3;31993:19;32045:4;32040:3;32036:14;32021:29;;31983:73;;;;:::o;32062:169::-;;32180:6;32175:3;32168:19;32220:4;32215:3;32211:14;32196:29;;32158:73;;;;:::o;32237:148::-;;32376:3;32361:18;;32351:34;;;;:::o;32391:305::-;;32450:20;32468:1;32450:20;:::i;:::-;32445:25;;32484:20;32502:1;32484:20;:::i;:::-;32479:25;;32638:1;32570:66;32566:74;32563:1;32560:81;32557:2;;;32644:18;;:::i;:::-;32557:2;32688:1;32685;32681:9;32674:16;;32435:261;;;;:::o;32702:185::-;;32759:20;32777:1;32759:20;:::i;:::-;32754:25;;32793:20;32811:1;32793:20;:::i;:::-;32788:25;;32832:1;32822:2;;32837:18;;:::i;:::-;32822:2;32879:1;32876;32872:9;32867:14;;32744:143;;;;:::o;32893:348::-;;32956:20;32974:1;32956:20;:::i;:::-;32951:25;;32990:20;33008:1;32990:20;:::i;:::-;32985:25;;33178:1;33110:66;33106:74;33103:1;33100:81;33095:1;33088:9;33081:17;33077:105;33074:2;;;33185:18;;:::i;:::-;33074:2;33233:1;33230;33226:9;33215:20;;32941:300;;;;:::o;33247:191::-;;33307:20;33325:1;33307:20;:::i;:::-;33302:25;;33341:20;33359:1;33341:20;:::i;:::-;33336:25;;33380:1;33377;33374:8;33371:2;;;33385:18;;:::i;:::-;33371:2;33430:1;33427;33423:9;33415:17;;33292:146;;;;:::o;33444:96::-;;33510:24;33528:5;33510:24;:::i;:::-;33499:35;;33489:51;;;:::o;33546:90::-;;33623:5;33616:13;33609:21;33598:32;;33588:48;;;:::o;33642:149::-;;33718:66;33711:5;33707:78;33696:89;;33686:105;;;:::o;33797:126::-;;33874:42;33867:5;33863:54;33852:65;;33842:81;;;:::o;33929:77::-;;33995:5;33984:16;;33974:32;;;:::o;34012:154::-;34096:6;34091:3;34086;34073:30;34158:1;34149:6;34144:3;34140:16;34133:27;34063:103;;;:::o;34172:307::-;34240:1;34250:113;34264:6;34261:1;34258:13;34250:113;;;34349:1;34344:3;34340:11;34334:18;34330:1;34325:3;34321:11;34314:39;34286:2;34283:1;34279:10;34274:15;;34250:113;;;34381:6;34378:1;34375:13;34372:2;;;34461:1;34452:6;34447:3;34443:16;34436:27;34372:2;34221:258;;;;:::o;34485:320::-;;34566:1;34560:4;34556:12;34546:22;;34613:1;34607:4;34603:12;34634:18;34624:2;;34690:4;34682:6;34678:17;34668:27;;34624:2;34752;34744:6;34741:14;34721:18;34718:38;34715:2;;;34771:18;;:::i;:::-;34715:2;34536:269;;;;:::o;34811:233::-;;34873:24;34891:5;34873:24;:::i;:::-;34864:33;;34919:66;34912:5;34909:77;34906:2;;;34989:18;;:::i;:::-;34906:2;35036:1;35029:5;35025:13;35018:20;;34854:190;;;:::o;35050:176::-;;35099:20;35117:1;35099:20;:::i;:::-;35094:25;;35133:20;35151:1;35133:20;:::i;:::-;35128:25;;35172:1;35162:2;;35177:18;;:::i;:::-;35162:2;35218:1;35215;35211:9;35206:14;;35084:142;;;;:::o;35232:180::-;35280:77;35277:1;35270:88;35377:4;35374:1;35367:15;35401:4;35398:1;35391:15;35418:180;35466:77;35463:1;35456:88;35563:4;35560:1;35553:15;35587:4;35584:1;35577:15;35604:180;35652:77;35649:1;35642:88;35749:4;35746:1;35739:15;35773:4;35770:1;35763:15;35790:180;35838:77;35835:1;35828:88;35935:4;35932:1;35925:15;35959:4;35956:1;35949:15;35976:102;;36068:2;36064:7;36059:2;36052:5;36048:14;36044:28;36034:38;;36024:54;;;:::o;36084:122::-;36157:24;36175:5;36157:24;:::i;:::-;36150:5;36147:35;36137:2;;36196:1;36193;36186:12;36137:2;36127:79;:::o;36212:116::-;36282:21;36297:5;36282:21;:::i;:::-;36275:5;36272:32;36262:2;;36318:1;36315;36308:12;36262:2;36252:76;:::o;36334:120::-;36406:23;36423:5;36406:23;:::i;:::-;36399:5;36396:34;36386:2;;36444:1;36441;36434:12;36386:2;36376:78;:::o;36460:122::-;36533:24;36551:5;36533:24;:::i;:::-;36526:5;36523:35;36513:2;;36572:1;36569;36562:12;36513:2;36503:79;:::o

Swarm Source

ipfs://21fb5a2265b62e2caa7cfb584ae81a406027030be7912d5896bb8669020036e5
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.